-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
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:
- The compiler exposes the generated CSS scope ID (
b-12ab34cd
) as a built-in parameter or cascading value. - Third-party components can bind this ID to a new attribute:
<button class="vendor-button" blazor-css-scope="b-12ab34cd">Click me</button>
- 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.
- Generate a
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.