English
Français

Blog of Denis VOITURON

for a better .NET world

Blazor CSS Isolation

Posted on 2025-10-17

Overview

CSS Isolation is a Blazor feature that allows CSS styles to be associated specifically with a component, thereby avoiding style conflicts with other components or libraries. This approach improves the maintainability and modularity of Blazor applications.

How to enable CSS Isolation

To define styles specific to a component, simply create a .razor.css file with the same name as the component’s .razor file, in the same folder.

For example, for a component named MyComponent in a file named MyComponent.razor, create a file named MyComponent.razor.css next to it:

MyComponent.razor :

<div class="container">
    <h1>My Title</h1>
    <p class="description">Description of my component</p>
</div>

MyComponent.razor.css :

.container {
    background-color: #f0f0f0;
    padding: 20px;
    border-radius: 8px;
}

h1 {
    color: #333;
    font-size: 2rem;
    margin-bottom: 1rem;
}

.description {
    color: #666;
    font-style: italic;
}

How it works internally?

During compilation, Blazor automatically rewrites CSS selectors to match the markup rendered by the component. The framework generates a unique scope identifier in the format b-{STRING} (where {STRING} is a 10-character string generated automatically) and adds it as an HTML attribute to the component’s elements.

generated HTML :

<div class="container" b-3xxtam6d07>
    <h1 b-3xxtam6d07>Mon Titre</h1>
    <p class="description" b-3xxtam6d07>...</p>
</div>

generated CSS :

.container[b-3xxtam6d07] {
    background-color: #f0f0f0;
    padding: 20px;
    border-radius: 8px;
}

h1[b-3xxtam6d07] {
    color: #333;
    font-size: 2rem;
    margin-bottom: 1rem;
}

.description[b-3xxtam6d07] {
    color: #666;
    font-style: italic;
}

Advantages of CSS Isolation

✅ Style encapsulation

✅ Improved maintainability

✅ Optimized performance

✅ Ease of use

Disadvantages and limitations

❌ Complexity with child components

❌ Limitation on Razor components

❌ Restricted HTML structure

❌ More complex debugging

Styling child components with ::deep

One of the major challenges of CSS Isolation is styling child components. By default, isolated styles only apply to the parent component.

The problem

Parent.razor :

@page "/parent"

<h1>Parent Component</h1>
<MyChildComponent />

Parent.razor.css :

/* This style will NOT apply to the child component. */
h1 {
    color: blue;
}

MyChildComponent.razor :

<h1>MyChildComponent</h1>

The solution with ::deep

To apply styles to child components, use the pseudo-element ::deep :

Parent.razor.css :

/* This style will apply to the h1 of the parent AND the children. */
::deep h1 {
    color: blue;
}

Crucial point: Need for an HTML container element

Problem: The generated identifier is not applied to the Razor components themselves, but only to the HTML elements they contain. To use ::deep correctly, it is often necessary to add a container HTML element.

Incorrect example (will not work):

<!-- Parent.razor -->
<h1>Parent</h1>
<MyChildComponent />

Correct example (will work):

<!-- Parent.razor -->
<div>
    <h1>Parent</h1>
    <MyChildComponent />
</div>

Parent.razor.css :

/* Now ::deep can work correctly */
::deep h1 {
    color: red;
}

The container div receives the scope identifier, allowing ::deep to work on descendant elements.

Practical examples

Card component with CSS isolation

Card.razor :

<div class="card">
    <div class="card-header">
        <h3>@Title</h3>
    </div>
    <div class="card-content">
        @ChildContent
    </div>
</div>

@code {
    [Parameter] public string Title { get; set; } = "";
    [Parameter] public RenderFragment? ChildContent { get; set; }
}

Card.razor.css :

.card {
    background: white;
    border: 1px solid #ddd;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    margin-bottom: 1rem;
}

.card-header {
    background: #f8f9fa;
    padding: 1rem;
    border-bottom: 1px solid #ddd;
    border-radius: 8px 8px 0 0;
}

.card-header h3 {
    margin: 0;
    color: #333;
}

.card-content {
    padding: 1rem;
}

Page using the Card component

MyPage.razor :

@page "/my-page"

<div class="page-container">
    <Card Title="First card">
        <p>Content of the first card</p>
    </Card>
    
    <Card Title="Second card">
        <p>Content of the second card</p>
    </Card>
</div>

MyPage.razor.css :

.page-container {
    max-width: 800px;
    margin: 0 auto;
    padding: 2rem;
}

/* Styling cards from the parent */
::deep .card {
    transition: transform 0.2s ease;
}

::deep .card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}

Advanced configuration

Customize the scope identifier

You can customize the scope identifier format in the project file:

<ItemGroup>
  <None Update="Components/MyComponent.razor.css" CssScope="my-custom-id" />
</ItemGroup>

Disable CSS Isolation

To completely disable CSS Isolation in a project:

<PropertyGroup>
  <ScopedCssEnabled>false</ScopedCssEnabled>
</PropertyGroup>

Best practices

  1. Organize your styles: Keep .razor.css files next to their respective components
  2. Use explicit class names: Even if styles are isolated, clear names improve readability
  3. Minimize the use of ::deep: Prefer component composition over modifying child styles
  4. Add HTML containers: When you need to use ::deep, make sure you have an appropriate HTML container element
  5. Test compatibility: Check that your styles work correctly with different browsers

Conclusion

Blazor CSS Isolation is a powerful tool for keeping styles organized and avoiding conflicts. Although it has some limitations, particularly with child components and the need to sometimes add container HTML elements, its advantages in terms of maintainability and encapsulation make it a wise choice for most Blazor applications.

Understanding how it works internally, particularly the fact that the generated ID only applies to HTML elements and not to Razor components themselves, is essential for using this feature effectively.

Resources

Languages

EnglishEnglish
FrenchFrançais

Follow me

Recent posts