Download Sample Code

Component Styling

Styling isn't just about making things look good - it's about creating maintainable and reusable UI components. Blazor offers several ways to apply CSS, each suited for different needs and scenarios. In this tutorial, you will explore:

  • An overview of styling approaches.
  • Understanding CSS Class Name Pollution.
  • Global styles.
  • Scoped styles.
  • Internal styles.
  • External styles.
  • Inline styles

An Overview of Styling Approaches

In Blazor, you can style components in several ways, depending on your needs:

  • Global styles apply to the entire application and are usually defined in files like app.css.
  • Scoped styles are specific to a single component, helping prevent accidental style overrides.
  • Internal styles are written inside the component itself using the <style> tag.
  • External styles live in a separate .css file and linked to the component.
  • Inline styles are added directly on an element via the style attribute, useful for quick or dynamic styling.

Understanding CSS Class Name Pollution

CSS class name pollution occurs when the same class name is used in multiple parts of an app, but with different styling intentions. For example, you might define a .card class for one component, only to find that another part of the app already uses .card with different styles. As a result, your styles get overridden or mixed, creating bugs that are hard to trace.

This issue forces developers to come up with overly specific or redundant class names - like .card-product, .card-user, and so on - just to avoid conflict.

Blazor addresses this issue through CSS isolation, a feature that scopes styles to specific components. When using scoped styles with .razor.css files, Blazor rewrites CSS selectors at build time to include a unique scope identifier, such as .card[b-tjvd9khfp8]. This ensures that the .warning class in one component does not affect another. Even if other components use the same class name, the styles won’t conflict. This keeps your CSS cleaner, safer, and easier to manage in large applications.


Global Styles

In Blazor, global styles are CSS rules that apply to the entire application. They’re usually written in a shared file like app.css and included via index.html.

Global styles are helpful for defining consistent visual rules across your app - like base font settings, color themes, spacing, and common layouts. For example:

body {
  font-family: Arial, sans-serif;
}

This rule will apply to every component unless specifically overridden. Global styles are perfect for shared UI elements such as headers, footers, buttons, or utility classes. However, since they are not scoped to any single component, they can unintentionally affect other parts of your app - a problem known as CSS class name pollution. As your app grows, this can make debugging styles more difficult, especially when class names collide.


Scoped Styles

We have mentioned the CSS class name pollution problem above and briefly noted that Blazor can resolve this issue gracefully with scoped styles.

The Under-the-Hood Technique

Delving deeper into the technology that helps Blazor achieve this, we can see that it uses the Attribute selectors technique behind the scenes.

Blazor generates a unique attribute tag along with the CSS class name on the fly. For example, with the following code in your Razor file:

<span class="scoped">
  The "scoped" CSS class is isolated to this component. Even if another component defines a class with the same name, it won’t interfere with or override the styles used here.
</span>

And the CSS in your .razor.css file:

.scoped {
  color: blue;
}

Blazor then compiles it into something like this:

<span class="scoped b-tjvd9khfp8"> ... </span>
.scoped[b-tjvd9khfp8] {
  color: blue;
}

Setting Up Scoped Styles

  1. Enable the scoped CSS feature in index.html. In some projects, you might find the line for scoped CSS commented out. Look for a line like this in your index.html:
<link href="ComponentStyling.styles.css" rel="stylesheet" />
  1. Blazor uses a naming convention: if your component is ScopedComponentExample.razor, create a file named ScopedComponentExample.razor.css. Place all the CSS rules you want scoped to that component inside this file.

Overriding Scoped Styles

Scoped CSS is designed to prevent unintended overrides, not to completely lock down styles. Developers can still override scoped styles when necessary.

Suppose you are using ScopedComponentExample inside another component called OverridingScopedComponentExample, and you want the inner component to use different styles.

  1. Add a scoped CSS file for OverridingScopedComponentExample. Name it OverridingScopedComponentExample.razor.css, and place it in the same folder as the component.
  2. Define the CSS rule with an outer selector, followed by ::deep, ending with the scoped class you want to override. For example:
.override ::deep .scoped
{
    color: yellow;
    background-color: red;
}

Here:

  • .override is the outer selector.
  • ::deep is the required syntax for overriding styles of nested components.
  • .scoped is the scoped CSS class you want to override.
  1. Apply the outer selector in your markup:
<div class="override">
  <ScopedComponentExample />
</div>

Internal Styles

While putting CSS in app.css or creating a scoped CSS file is better for long-term maintenance, sometimes testing things out during development requires a simpler approach. Internal styles are perfect for this scenario because they allow you to write minimal CSS directly alongside your component and remove it quickly when no longer needed.

Internal styles work by placing a <style> block directly inside your component, next to the elements it affects. For example:

<span class="internal-style">Hello Blazor School!</span>

<style>
    .internal-style
    {
        color: yellow;
    }
</style>

This approach is quick and requires no additional boilerplate. However, it comes with notable disadvantages and should generally only be used in a development environment:

  1. Every time the component is rendered, it generates duplicated style code, making the site heavier than necessary.
  2. CSS rules can unintentionally override others, causing strange bugs such as:
    • A component not rendering correctly.
    • The UI breaking when a component is removed.

External Styles

External styles are a common technique that can help reduce the initial loading size of a website by grouping related CSS into a separate file and fetching it only when the component is rendered. The trade-off is a potential layout shift when the CSS file is being loaded.

In the component, you include a <link> tag that points to the external CSS file. For example:

<link href="/css/external.css" rel="stylesheet" />
<span class="external-style">Hello Blazor School!</span>

This technique offers several advantages:

  • Clear separation of concerns between HTML structure and presentation.
  • Reduced initial loading time by delaying CSS loading until it’s needed.

However, developers should use this technique carefully, as it comes with drawbacks:

  1. Duplicated <link> tags may be generated when a component is rendered multiple times.
  2. Layout shifts can occur if styles are applied too late during rendering.

Inline Styles

When you need to apply something dynamic - such as changing text color based on a user's selection - the best approach is often to use inline styles. This technique applies styles directly to an element, giving them the highest priority.

For example, you can set the text color for a specific paragraph like this:

<span style="color: green">Hello Blazor School!</span>

Inline styles can also be useful for quick testing, similar to internal styles. However, they come with significant drawbacks:

  • They make maintenance harder because styles are scattered across the markup instead of being centralized.
  • They reduce reusability, since the style is tied to one element only.
BLAZOR SCHOOL
Designed and built with care by our dedicated team, with contributions from a supportive community. We strive to provide the best learning experience for our users.
Docs licensed CC-BY-SA-4.0
Copyright © 2021-2025 Blazor School
An unhandled error has occurred. Reload 🗙