From site.css to component styles
Developers are human beings…
If there’s one thing we know about human beings it’s that they’re hardwired to take the shortest route from A to B…
Which probably explains why you have a single stylesheet in your app where ALL the CSS styles go.
One stylesheet to rule them all#
You’re working on your app and realise you need to tweak the CSS…
… so you go to the one place where all the styles live.
Once there you realise you need a new style but where should you put it?
I mean… you’re already in this file which has lots of other CSS styles, and creating a new one would mean naming it, and linking to it from your main HTML page.
That all sounds like work and it’s nearly lunchtime… maybe, just this once, you could add one teeny-tiny little style to the bottom of this file?
Go round this hamster wheel a few times; site.css
gets bigger, new styles are chucked on the end and tweaking your styles takes longer, and longer (as does figuring out why anything looks the way it does).
.NET 5 offers a solution - CSS Isolation#
Enter .NET 5 and CSS Isolation.
With CSS Isolation you can define styles for your components right there, next to the component.
All you need to do is:
- Create a new
<component>.razor.css
file - Define your component’s styles in that file
- Get on with the rest of your day (or you know, go for lunch)
Say you want to tweak the styles for the Counter
component which ships with the Blazor project templates.
With .NET 5 you can create a new Counter.razor.css
file.
In there, define your styles as normal at which point Blazor will automatically wire everything up so Counter
uses these styles.
Counter.razor.css
The big win is that these styles only apply to the specific component. So you can happily set styles for generic elements like h1
, confident that it will only affect this component’s h1
elements and not the other h1
elements in your application.
Index.razor
Go ::deep#
By default these styles will only apply to the specific component, not child components.
For example:
Counter.razor
If the Counter
component includes another component (CustomHeading
in this example), and that component has an h1
tag:
The style we defined in Counter.razor.css
won’t apply to the h1
in CustomHeading
.
However, you can make it apply using the ::deep
combinator.
Counter.razor.css
Now any child components with h1
elements will take on this style as well.
How it works#
When you use this feature in .NET 5 Blazor automatically gives your elements unique names/identifiers and rewrites your CSS rules to use these identifiers (at build time).
It also compiles all the various CSS styles into a file called {project_name}.styles.css
.
So your HTML will end up looking something like this (when you inspect the source):
And the corresponding file can be seen in {project_name}.styles.css
.
If we omit the ::deep
combinator from our example we get slightly different CSS in {project_name}.styles.css
.
This shows the clear difference between using or not using ::deep
.
In summary#
Once you start thinking in terms of components it follows you’ll want fine-grained control of each component’s appearance using CSS.
CSS Isolation in .NET 5 makes this much easier and keeps the CSS close to the markup it affects (avoiding the problem of everything getting thrown into one big stylesheet, making maintenance much more difficult).
All posts in To .NET 5 and beyond
- Does .NET 6 fix Blazor Prerendering?
- Update the HTML head from your Blazor components
- From site.css to component styles
- Render Blazor WASM components in your existing MVC/Razor Pages applications
- Prerendering your Blazor WASM application with .NET 5 (part 1)
- Prerendering your Blazor WASM application with .NET 5 (part 2 - solving the missing HttpClient problem)