Skip to content

fix: substitute Angular 22.1 CSS custom property namespace placeholder - #182

Merged
NathanWalker merged 1 commit into
mainfrom
fix/css-var-namespace
Oct 23, 2026
Merged

NathanWalker merged 1 commit into
mainfrom
fix/css-var-namespace

Conversation

@NathanWalker

Copy link
Copy Markdown
Contributor

Problem

Angular 22.1.0 namespaces CSS custom properties at compile time (namespaceCssVariables in @angular/compiler). In component styles, under every encapsulation mode, and in [style.--x] bindings:

  • --brand: red becomes --%NS%brand: red
  • var(--brand) becomes var(--%NS%brand)

@angular/platform-browser then replaces %NS% at runtime. The default is an empty namespace; provideCssVarNamespacing() sets a real one. Our renderer only replaced %COMP%, so the placeholder reached NativeScript core unchanged. In apps on Angular 22.1+, this causes two failures:

  1. var(--x) in a component never resolves. The common pattern is declaring theme variables globally (.ns-root { --brand: … } in app.scss) and using var(--brand) in component styles. That breaks because the component looks up --%NS%brand.
  2. A whole component stylesheet is dropped silently. Any custom-property declaration in component styles, including one pulled in through @import/@use of a shared file, becomes --%NS%x: …. The css-tree parser rejects that with Parse error: Colon is expected, and CSSSource.parse swallows the error (it's only logged under Trace), so every rule in that stylesheet is lost. Ordinary rules like .action-bar { background-color: #f00 } stop applying too.

Fix

Strip %NS% to match Angular's default empty namespace:

  • EmulatedRenderer.addStyles
  • the ViewEncapsulation.None branch of NativeScriptRendererFactory.createRenderer
  • setStyle / removeStyle for names starting with --

On Angular < 22.1 the placeholder never appears, so nothing changes there.

provideCssVarNamespacing() isn't honored. The CSS_VAR_NAMESPACE token only exists in @angular/platform-browser 22.1+, and this repo builds against 22.0.8. Global app.css doesn't go through Angular's compiler, so an empty namespace is the only choice that lets component styles see globally declared variables.

Tests

css-variables.spec.ts feeds component styles in the namespaced form Angular 22.1 emits, so it doesn't depend on the compiler version:

  • emulated component: declare and use a custom property
  • ViewEncapsulation.None component: declare and use a custom property
  • Renderer2.setStyle / removeStyle with a --%NS% name

Results with ns test ios, iOS 26.5 simulator:

  • with the fix: 129/129 pass
  • with the fix reverted: the 3 new specs fail (Expected null to be '#ff0000', …)

Also checked end to end in a NativeScript Angular app on Angular 22.1.8 (iOS 27 simulator), using a locally built package. Cases tested: global declaration with var() in a component, ::ng-deep .ns-root { --x }, declaring and using inside one component, and a component that @imports app.scss and sets a plain background-color. All failed before the fix. After it, all apply and there are no Css styling failed trace errors.

Workaround for affected apps until released

Use Angular's escape prefix in component styles: var(--global--brand) compiles to var(--brand). Keep declarations out of component stylesheets.

Angular 22.1 compiles custom properties in component styles and
[style.--x] bindings to `--%NS%name` / `var(--%NS%name)` and expects the
renderer to replace `%NS%`. The NativeScript renderer passed the
placeholder through, so:

- `var(--x)` in a component never resolved against `--x` declared in
  app.css/app.scss.
- Declaring any custom property in a component stylesheet made the
  NativeScript CSS parser reject `--%NS%x:` and silently drop the whole
  stylesheet.

Strip the placeholder (Angular's default empty namespace) for emulated
and unencapsulated component styles and for setStyle/removeStyle.
@coderabbitai

coderabbitai Bot commented Oct 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c3e5128d-557e-466b-9fec-83513097de78

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Oct 23, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/NativeScript/angular/@nativescript/angular@182
npm i https://pkg.pr.new/NativeScript/angular/@nativescript/zone-js@182

commit: d0580d9

@NathanWalker
NathanWalker merged commit ffa1d00 into main Oct 23, 2026
8 of 9 checks passed
@NathanWalker
NathanWalker deleted the fix/css-var-namespace branch October 23, 2026 21:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant