This article was updated on October 12th, 2020, see the update below.
To explain what style encapsulation means, we will look at how Angular does it. Here is a lengthy article, which links to this demo. Or, if you prefer screenshots.
On this screenshot an h1
style is converted to _ngcontent-lvy-c0
class during compilation, and then it does not leak out styles to other components and the app. You can declare another h1
style in another component and that will not have any effect on this component, guaranteed by Angular. Or its children, which might be even more important (so it’s more than just nesting css in an HTML selector tree).
You also have access to a bunch of encapsulation related selectors such as :host
and ::ng-deep
. ::ng-deep
can be used to ignore style encapsulation for that specific style rule and apply styles for child components, which can be useful to tweak 3rd party components.
Blazor currently does not include any style encapsulation feature. Despite obvious benefits, the recommended way is building your app without it. The problem is that style encapsulation is essential to enterprise development, when your app becomes big and is maintained by at least 100 software developers. Still, for some reason Microsoft did not consider it important until recently. Even despite bad reception of this answer (lots of downvotes).
Here is a quote on the importance of style encapsulation, by Justin Couto:
Being able to isolate the CSS for an individual component knowing with certainty there will be no CSS bleed or naming collision/accidental overrides is critical. The simplicity of being able to have a style called
.item
in many components at any level in your application is extremely freeing and useful. You can actually name your styles for what they are not worrying about how those names are impacting the rest of your application. This feature dramatically reduces accidental global cascading issues that developers have been dealing with for years. The global nature of CSS has always been problematic.
There are a few third-party solutions such as BlazorStyled or BlazorScopedCss. But not built in, with a learning curve and no way to just copy/paste from regular CSS - meaning increased conversion effort, and in general, that you had to rely on some free tool. As we all know, free tools are not as good, on average, when it comes to productivity. In addition, they may suddenly cease to work after you update to the latest version of your IDE, or the tool (or both). This is where MS have always been great - having one tool that works, out of the box. Talking about .NET and Visual Studio, on top of which you could have Resharper, NDepend and other productivity tools.
Fortunately, after a lengthy discussion on this ticket, Microsoft finally accepted CSS encapsulation into their roadmap for .NET 5.0.
This is great news for everyone, it means that Blazor will eventually be able to compete with other popular JS-based frameworks, offering a core set of features, as well as great tools to use them from the comfort of IDE that works. Competition is always good, since Angular folks will try to keep up, and this situation will further improve our developer’s lives in long term.
Update (October 12th, 2020)
They did it! CSS isolation in Blazor is a new feature coming as part of .NET 5.0, and available since preview 8. Here is a great article about it:
How they handled ::deep
is perfect, I didn’t like when Angular imported the ::ng-deep
styles and you forgot the :host
, and suddenly all your styles are broken. So Microsoft fixed this issue by auto-applying to only child elements. It’s interesting that with ::deep
, the position of this keyword inside CSS selector matters (unlike Angular, where ::ng-deep
simply disables view encapsulation), see this ticket on GitHub: