Skip to content

CSS Variable Namespacing#67362

Open
dgp1130 wants to merge 2 commits intoangular:mainfrom
dgp1130:css-namespace
Open

CSS Variable Namespacing#67362
dgp1130 wants to merge 2 commits intoangular:mainfrom
dgp1130:css-namespace

Conversation

@dgp1130
Copy link
Contributor

@dgp1130 dgp1130 commented Feb 28, 2026

This adds CSS variable namespacing support to Angular.

This allows multiple apps to coexist on the same page with isolated CSS variables, meaning one can use color: var(--primary-color); without worrying about accidentally inheriting the primary color of a different app which happens to set it on an ancestor element.

To enable this feature, call provideCssVarNamespacing in your app.config.ts. Typically you want to configure this with the same value as APP_ID, but with an additional separator at the end (a - or _):

import {ApplicationConfig, APP_ID} from '@angular/core';
import {provideCssVarNamespacing} from '@angular/platform-browser';

export const appConfig: ApplicationConfig = {
  providers: [
    {
      provide: APP_ID,
      useValue: 'my-app',
    },
    provideCssVarNamespacing('my-app_'),
  ],
};

This only namespaces styles in Angular components (the styles or styleUrls properties in @Component). It does not namespace global styles, which are out of scope for this effort.

Namespacing does naturally break any JavaScript references to CSS variables, therefore this PR also introduces CssVarNamespacer which allows you to automatically namespace variables based on what is configured in the application.

import {CssVarNamespacer} from '@angular/platform-browser';

const namespacer = inject(CssVarNamespacer);
const color = namespacer.namespace('--primary-color');
getComputedStyle(someElement).getPropertyValue(color);

Libraries should consider always using the namespacer when referring to CSS variables, as they may be consumed by applications which enable namespacing.

Namespacing works by having the compiler unconditionally prepend %NS% to CSS variables (--foo -> --%NS%foo) and then at runtime replaces %NS% with a namespace specified by provideCssVarNamespacing('my-app_') (--%NS%foo -> --my-app_foo).

Internal bug: b/485672083

This allows Angular to apply a namespace to any CSS variables based on runtime configuration. In most situations, the `APP_ID` followed by a separator (`-` or `_`) is likely sufficient as a namespace.

```typescript
bootstrapApplication(Root, {
  providers: [
    {
      provide: APP_ID,
      useValue: 'my-app',
    },

    // Variables like `--foo` will become `--my-app_foo`.
    provideCssVarNamespacing('my-app_'),
  ],
});
```

This is implemented by having the compiler unconditionally transform `--foo` to `--%NS%foo` to ensure a consistent output format, and then replace the `%NS%` at runtime with the namespace given to `provideCssVarNamespacing` (or an empty string for a no-op).
Adds the CssVarNamespacer utility service for prefixing CSS variables with MicA namespace dynamically.
@dgp1130 dgp1130 requested a review from mattrbeck February 28, 2026 01:44
@dgp1130 dgp1130 added action: review The PR is still awaiting reviews from at least one requested reviewer area: compiler Issues related to `ngc`, Angular's template compiler target: minor This PR is targeted for the next minor release labels Feb 28, 2026
@ngbot ngbot bot modified the milestone: Backlog Feb 28, 2026
@angular-robot angular-robot bot added detected: feature PR contains a feature commit area: core Issues related to the framework runtime labels Feb 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action: review The PR is still awaiting reviews from at least one requested reviewer area: compiler Issues related to `ngc`, Angular's template compiler area: core Issues related to the framework runtime detected: feature PR contains a feature commit target: minor This PR is targeted for the next minor release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant