Using isolated CSS in Blazor components

· 3 min read

One thing that always bugged me when working with Blazor was how easy it was to accidentally break styles across components. You’d add a class in one component and suddenly something else on a completely different page looked off. Turns out, Blazor has a built-in solution for this: CSS isolation.

What is CSS isolation?

CSS isolation lets you scope styles to a specific component. Blazor does this by generating a unique attribute for each component at build time and appending it to the CSS selectors. So your styles only apply to the component they belong to.

No need for BEM naming, no need for crazy specificity hacks. Just clean, scoped CSS.

How to use it

Let’s say you have a component called Card.razor:

<div class="card">
    <h3 class="card-title">@Title</h3>
    <p class="card-body">@ChildContent</p>
</div>

@code {
    [Parameter]
    public string Title { get; set; }

    [Parameter]
    public RenderFragment ChildContent { get; set; }
}

To add isolated styles, you just create a file with the same name but with .razor.css extension. In this case: Card.razor.css.

.card {
    border: 1px solid var(--color-border);
    border-radius: 8px;
    padding: 1rem;
    background: var(--color-bg-secondary);
}

.card-title {
    font-size: 1.1rem;
    font-weight: 600;
    margin-bottom: 0.5rem;
}

.card-body {
    color: var(--color-text-secondary);
    font-size: 0.9rem;
}

And that’s it! Blazor will automatically pick it up and scope those styles to the Card component only. If you have another .card class somewhere else, it won’t be affected.

How it works under the hood

When you build your project, Blazor rewrites the HTML and CSS. Your component gets a unique attribute like b-3x8qz7k2f1, and the CSS selectors get that attribute appended:

.card[b-3x8qz7k2f1] {
    border: 1px solid var(--color-border);
    /* ... */
}

The generated CSS bundle is served as {ProjectName}.styles.css. Make sure you have this in your index.html or _Host.cshtml:

<link href="YourApp.styles.css" rel="stylesheet" />

If you’re missing that link, your isolated styles won’t show up and you’ll spend 30 minutes wondering what’s going on. Trust me, I’ve been there.

Targeting child elements

One thing to keep in mind is that by default, isolated CSS only applies to the current component’s elements. If you want to style elements inside a child component, you need the ::deep combinator:

::deep .child-element {
    color: red;
}

This tells Blazor to apply the style to matching elements within child components too. Pretty handy when you have a wrapper component that needs to style its children.

When to use it

I use CSS isolation for pretty much every component now. It keeps things clean and predictable. The only time I don’t use it is for truly global styles like resets, typography, or theme variables — those go in a shared CSS file.

Hope you liked the post! Feel free to contact me on any social media at @emimontesdeoca.

Resources