Blazor and Component Scoped CSS/SASS

Jason Tucker
5 min readAug 9, 2020

I have had this on again/off again relationship with Blazor for the past year plus. Every major release I come back to it and do a couple quick demo apps (Todo and the like) and then go back to whatever web tech I’m using for my customers. So, for this go around during the transition to .Net 5, I decided to take an existing production Angular app and see how hard it would be to convert it to Blazor. The current application is done in the canonical Angular style with modules and components, so I set about converting the site. I opened my terminal and quickly typed out dotnet new blazorwasm -o Blaze-Convert and started coding.

I quickly discovered that one of the most utilized features of our current app was component scoped styles. For those that are unfamiliar, here is a blurb from the Angular docs:

Angular applications are styled with standard CSS. That means you can apply everything you know about CSS stylesheets, selectors, rules, and media queries directly to Angular applications.

Additionally, Angular can bundle component styles with components, enabling a more modular design than regular stylesheets.

This means that we can define a CSS file next to our components that is scoped only to that component. This is utilized by using a unique identifier applied to the component + some HTML5 + CSS3 magic.

Once I realized I couldn’t do that with the latest version of Blazor at the time (.Net 5.0 Preview 7) I just threw out a random tweet.

My twitter post about wanted scoped CSS for Blazor

What I should have done was probably do a quick google-bing search because what I found after I did some sleuthing was that there was already a GitHub issue about this and even better was a comment that the feature had been worked and is being delivered in the next preview release of .Net 5.

Not being one to be patient when amid problem solving some code issue I was having, I grabbed up the nightly version of the .Net 5 SDK. I then went back to my trusty terminal and once again executed a dotnet new blazorwasm -o Blaze-Convert-Nightly and as expected, the out of the box Blazor WASM project includes scoped CSS functionality.

UPDATE: .Net 5 Preview 8 is now out and includes this scoped css feature.

Awesome! But what if, like me, you wanted to convert an existing project to use this as well?

It’s actually fairly straight forward and detailed in the README for the .Net SDK but for simplicity sake, I’ll show you the one that I used as well as the Nuget.Config that goes along with it. The version numbers will change day to day in the .csproj so make sure you update them accordingly.

Bare minimum nightly (as of 8/7/2020) .Net 5 project & nuget config.

Once you have your csproj file and NuGet.config file updated and restored, you need to add the following line to your index.html:

<link href=”_framework/scoped.styles.css” rel=”stylesheet” />

Now you can start to create your component scoped CSS files by creating a new file next to you component and post-pend the .css extension as below:

Components/NavMenu.razor
Components/NavMenu.razor.css

Build your app and marvel in your browser devtools your newly scoped CSS classes. You can tell it’s there because your component HTML elements now have strange identifiers within them.

You can tell a Component Scoped CSS by the unique identifiers on your HTML elements.

So that’s great, I now have my component scoped CSS styles being built and displaying properly but I get another wrinkle going back to my production app. Our styles are using SASS instead of vanilla CSS. Normally, this isn’t a problem and we just let ng deal with building and bundling these styles for us. Back to the GitHub issue from earlier in this story, it is specifically called out that there is no plan to incorporate any additional transformation tools within the build pipeline. So, I forge ahead and dig into our old friends MSBuild and npm.

Below is a gist of what I currently have working in my little demo application. This is the full csproj and package.config that is currently working for me and my specific needs, so YMMV.

updates to the csproj and package.json for getting SASS to compile

So, let’s take a step back and cover what is going on here.

  1. We use npm and node-sass to do the compiling of the SASS files for us. You can see those listed in the devDependencies section of the package.json.
  2. There is a simple npm run script that allows MSBuild to call the node-sass cli without having to trying and figure out paths and such.
  3. With the npm pre-reqs configured we turn to the MSBuild script. I have defined two Targets and an ItemGroup to complete this solution.
  4. The ItemGroup is what searches our codebase for all the SASS files we have defined. I currently have all my SASS files indexed but you could easily update the wildcard search to only look for your razor.css files instead. I’ve also specifically excluded any files from the node_modules folder.
  5. The first Target that is defined is making sure that we have Node installed and by extension npm also installed. This will fail the build if it’s not found and if it is found, it will output the version currently installed.
  6. The second Target is where MSBuild will loop through all the files it found in the project and pass each one to the npm run script node-sass compiling each file to CSS. It will output the resulting file right next to the component so Blazor will then come in afterwards and compile all the scoped CSS into one file.

Now the next time I execute dotnet build my build log shows the current version of Node, all the files that are found and that each one is being transformed into CSS.

Example build output from dotnet

In result, this little detour has given me some more insight into Blazor development that is coming and I’m excited for it. I also now have another data point to discuss with customers that are looking to go from Angular/JavaScript SPAs to Blazor in the future.

--

--

Software Guy. Just took a DNA test turns out I’m 100% that guy that broke the build.