CSS Isolation In Blazor

Introduction

CSS (Cascading Style Sheets) is a powerful standard for users (developers) to define the look of the application. Many client side frameworks such as Angular support component-wise CSS; i.e. you can attach CSS directly to component. Its scope isolates it from the rest of the application. Now, Blazor has also supported CSS isolation that helps to avoid styling conflicts among the component.

The CSS isolation in the Blazor component is by default enabled and to use it create a ".razor.css" file matching with component name. This is also referred to as a scoped CSS file. For example, if you want to create scoped CSS for the "ComponentWiseCss.razor" component then create the "ComponentWiseCss.razor.css" file and define component-related CSS.

CSS Isolation In Blazor

The style defined in ComponentWiseCss.razor.css is only applied to the rendering of ComponentWiseCss.razor page. It is not applied to the other razor pages.

Example 

@*ComponentWiseCss.razor*@
@page "/cssexample"
<h1>CSS EXample</h1>
<div class="col-12 style1">
    <p>Applying Style 1</p>
</div>
<div class="col-12 style2">
    <p>Applying Style 2</p>
</div>
<div class="col-12 style3">
    <p>Applying Style 3</p>
</div>
@code {  
}

ComponentWiseCss.razor.css

body {
}
.style1 {
    background-color: lightgray;
    font-weight:bold;
}
.style2 {
    background-color: lightgreen;
    font-weight: bold;
}
.style3 {
    background-color: black;
    color: yellow;
    font-weight: bold;
}

Output

CSS Isolation In Blazor

CSS isolation bundling

The CSS isolation happens at build time. The Blazor engine rewrites the CSS and HTML to match markup to components. The rewritten CSS styles are bundled into one and saved as a static resource. The stylesheet references inside the <head> tag of wwwroot/index.html (Blazor WebAssembly) or Pages/_Host.cshtml (Blazor Server). The name of the stylesheet is in format "{ASSEMBLY NAME}.styles.css" here, {ASSEMBLY NAME} is the project name. 

When the Blazor engine bundles the CSS file, it associates unique scope identifiers with each component. The scope identifier is in the format "b-<10 character string>". In the following example, three different styles are created for the <div> element. When you look at the page source, you notice that the Blazor engine creates unique scope identifiers and associates them with both HTML and CSS. 

body[b-qvelpzvlyq] {
}
.style1[b-qvelpzvlyq] {
    background-color: lightgray;
    font-weight:bold;
}
.style2[b-qvelpzvlyq] {
    background-color: lightgreen;
    font-weight: bold;
}
.style3[b-qvelpzvlyq] {
    background-color: black;
    color: yellow;
    font-weight: bold;
}

CSS Isolation In Blazor

Cascading CSS style to Child Component

The CSS isolation is only applied to the component level by default but you can extend it to the child component using "::deep" attribute in the CSS file. This attribute is the Blazor attribute so, it only understands and parses by the Blazor engine. When "::deep" attribute used in the CSS file, the Blazor engine also applied scope identifier to all descendants of components. 

In the following example, the "::deep" attribute is assigned to <div> element style but not to paragraph (<p>) element. You can see here, <div> element styles are applied to both parent and child components but paragraph (<p>) element style is only applied to the parent component. 

 ChildComponent.razor

<hr />
<p>
    paragraph:: This is child component content
</p>
<div>
    div:: This is child component content
</div>
<hr />
@code {
}

ParentComponent.razor

@page "/parentcomponent"
<h3>Parent Component</h3>
<div>
    <p>paragraph:: This is Parent Component content</p>
    <ChildComponent></ChildComponent>
    <div>
        div:: This is parent component content
    </div>
</div>
@code {
}

ParentComponent.razor.css

p {
    color: red
}
::deep div {
    color:orange;
    font-weight:bold;
}

Output

CSS Isolation In Blazor

The Sass and Less are well-known CSS preprocessors. They are useful for improving CSS development. They provide many features such as variables, nesting, inheritance, modules, and mixins. The CSS isolation does not natively support the CSS preprocessor but you can integrate the CSS preprocessor to the Blazor project by compiling the preprocessor before the Blazor engine rewrites the CSS selectors during the build process. For example, you can perform preprocessor compilation on Before build task in Visual Studio.

Summary

Blazor provides a very beautiful feature called CSS isolation that enables you to create CSS files per component.

You can view or download the source code from the GitHub link here.