Skip to content

Proposal: Enable CSS Isolation Support for Third-Party Components via blazor-css-scope Attribute #63091

@stsrki

Description

@stsrki

Summary

Blazor’s CSS isolation is currently limited to user-authored Razor components. Third-party UI component libraries (e.g., Blazorise, MudBlazor) cannot participate in this system because:

  • CSS isolation is processed at build time.
  • Scoped attributes (e.g., b-12ab34cd) are automatically added only to components compiled with the application.
  • Third-party components are precompiled, preventing the Razor compiler from injecting the scoped attribute into their rendered elements.

This proposal introduces a new framework-supported attribute, blazor-css-scope, allowing third-party components to opt-in to CSS isolation. It would let application authors style third-party components using isolated .razor.css files without relying on global styles.

Motivation and goals

When using a third-party component:

<MyVendor.Button Text="Click me" />

and defining isolated styles in Parent.razor.css

.vendor-button {
    background: red;
}

Blazor transforms this into:

.vendor-button[b-12ab34cd] {
    background: red;
}

But because the vendor’s component cannot know or emit the b-12ab34cd attribute, the style does not apply.

Proposed Behavior

With the new feature:

  1. The compiler exposes the generated CSS scope ID (b-12ab34cd) as a built-in parameter or cascading value.
  2. Third-party components can bind this ID to a new attribute:
<button class="vendor-button" blazor-css-scope="b-12ab34cd">Click me</button>
  1. The isolated CSS selector matches, allowing scoped styling of third-party components.

Specification

1. New Attribute Name

  • Proposed name: blazor-css-scope
  • Purpose: Indicates a component’s association with a scoped CSS ID generated by Blazor’s compiler.

2. Compiler Changes

  • The compiler should:
    • Generate a CssScopeId (string) for each Razor component that uses CSS isolation.
    • Provide this ID as a special built-in parameter or cascading value to child components.

Example:

<MyVendor.Button CssScopeId="@this.CssScopeId" />

3. Third-Party Component Usage

  • Vendors add a parameter to their component:
[Parameter] public string? CssScopeId { get; set; }
  • Render it on the root element:
<button class="vendor-button" blazor-css-scope="@CssScopeId">@Text</button>

4. Backward Compatibility

  • Existing CSS isolation behavior remains unchanged.
  • If a vendor doesn’t implement the attribute, there’s no impact.
  • Purely additive, opt-in feature.

Benefits

  • Allows isolated .razor.css files to style third-party components.
  • Preserves encapsulation and avoids global CSS overrides.
  • Simple for vendors to implement and propagate within their libraries.
  • No breaking changes for existing projects.

Challenges & Considerations

  • Nested Components: Vendors must propagate the scope attribute through their internal components if they want full coverage.
  • Multiple Parents: Need clear rules for determining which scope ID applies (default to the immediate parent).
  • Performance: Minimal, adding an attribute is low cost.

Alternatives

  • Use global CSS overrides (leads to style conflicts).
  • Ask vendors to ship their own scoped styling (not practical for user customizations).
  • Reflection or hacks to read internal scope ID (unsupported).

Conclusion

Adding a framework-supported blazor-css-scope attribute would close a major gap in Blazor’s CSS isolation feature, enabling third-party UI libraries to fully integrate with the scoped styling system while maintaining component isolation and theming capabilities.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-blazorIncludes: Blazor, Razor Componentsdesign-proposalThis issue represents a design proposal for a different issue, linked in the description

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions