In this post we use Sassy CSS to style our Blazor components and we will integrate Web Optimizer to compile these files to a single file site.css.

Web Optimizer is an ASP.Net Core middleware for bundling and minification of CSS and JavaScript files at runtime. With full server-side and client-side caching to ensure high performance. No complicated build process and no hassle.

In our server side .Net Core 3.0 Blazor project we got the following project structure

  • BlazorStyling.WebOptimizer
    • wwwroot/
      • css/
    • Components/
      • Progress.razor
      • Progress.scss
    • Pages/
      • _Host.cshtml
      • Index.razor
    • Shared/
      • Helper.scss
      • MainLayout.razor
    • _Imports.razor
    • App.razor
    • App.scss
    • appsettings.json
    • Program.cs
    • Startup.cs

We use SCSS to style a progress bar Blazor component Progress.razor

<div class="progress">
    <div class="progress-bar @BackgroundClass"
         style="width: @Width"
        @if (!string.IsNullOrWhiteSpace(Label))
            @string.Format(Label, ValueNow)

@code {
    public enum BackgroundColor { Red, Yellow, Green }

    public int ValueNow { get; set; }
    public string Label { get; set; }
    public BackgroundColor BgColor { get; set; } = BackgroundColor.Green;

    private string BackgroundClass => $"bg-{BgColor.ToString().ToLower()}";
    private string Width => $"{ValueNow}%";

with its style Progress.scss.

.progress {
    display: flex;
    height: 1rem;
    overflow: hidden;
    font-size: .75rem;
    background-color: #e9ecef;
    border-radius: .25rem;

.progress-bar {
    display: flex;
    flex-direction: column;
    justify-content: center;
    color: #fff;
    text-align: center;
    white-space: nowrap;
    background-color: #007bff;
    transition: width .6s ease;

$bg-green: #28a745;
$bg-yellow: #ffc107;
$bg-red: #dc3545;

.bg {
    &-green {
        background-color: $bg-green;

    &-yellow {
        background-color: $bg-yellow;

    &-red {
        background-color: $bg-red;

The index page Index.razor just renders the progress bar components

@page "/"

<div class="mt-1">
    <Progress ValueNow="ValueNow" BgColor="Progress.BackgroundColor.Green" />
<div class="mt-1">
    <Progress ValueNow="ValueNow" BgColor="Progress.BackgroundColor.Red" />
<div class="mt-1">
    <Progress ValueNow="ValueNow" BgColor="Progress.BackgroundColor.Yellow" />
<div class="mt-1">
    <Progress ValueNow="ValueNow" BgColor="Progress.BackgroundColor.Green" Label="we got {0}%" />
<div class="mt-1">
    <Progress ValueNow="ValueNow" BgColor="Progress.BackgroundColor.Red" Label="finally {0}%" />
<div class="mt-1">
    <Progress ValueNow="ValueNow" BgColor="Progress.BackgroundColor.Yellow" Label="{0}%" />

@code {
    const int From = 0, To = 100;
    int ValueNow { get; set; } = 50;

    protected override Task OnAfterRenderAsync(bool firstRender)
        => InvokeAsync(async () =>
            while (true)
                await System.Threading.Tasks.Task.Delay(2000);
                ValueNow = new Random().Next(From, To);

and we need a root SCSS file App.scss to combine all other SCSS files.

@import 'Components/Progress';
@import 'Shared/Helper';

The MainLayout.razor is nearly empty

@inherits LayoutComponentBase


and our Host.cshtml just renders the app and includes the compiled css.

@page "/"
@namespace BlazorStyling.WebCompiler.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<!DOCTYPE html>
<html lang="en">
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <base href="~/" />
    <environment include="Development">
        <link href="css/site.css" rel="stylesheet" />
    <environment exclude="Development">
        <link href="css/site.min.css" rel="stylesheet" />
        @(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered))

    <script src="_framework/blazor.server.js"></script>

With this set up, we can install the NuGet packages LigerShark.WebOptimizer.Core and LigerShark.WebOptimizer.Sass.

PM> Install-Package LigerShark.WebOptimizer.Core
PM> Install-Package LigerShark.WebOptimizer.Sass

To add the middleware we have to add the Web Compiler services to our service collection in Startup.cs

public void ConfigureServices(IServiceCollection services)
    services.AddWebOptimizer(pipeline =>
        // UseContentRoot only sets the root of the source files
        pipeline.AddScssBundle("/css/site.css", "App.scss").UseContentRoot();

and add Web Optimizer to the request execution pipeline also in Startup.cs.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    if (env.IsDevelopment())



    app.UseEndpoints(endpoints =>

This project is available on GitHub.