Skip to content

CSS-aware syntax scoping for style bindings#67396

Draft
kbrilla wants to merge 5 commits intoangular:mainfrom
kbrilla:feat/css-style-scoping
Draft

CSS-aware syntax scoping for style bindings#67396
kbrilla wants to merge 5 commits intoangular:mainfrom
kbrilla:feat/css-style-scoping

Conversation

@kbrilla
Copy link
Contributor

@kbrilla kbrilla commented Mar 2, 2026

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • angular.dev application / infrastructure changes
  • Other... Please describe:

What is the current behavior?

Style bindings in Angular templates and host metadata are tokenized as plain strings without CSS-aware scoping. This means:

  • style="color: red; font-size: 14px" — the value is a generic HTML attribute string
  • [style]="'border: 1px solid black'" — CSS declarations inside the string literal are not recognized
  • [style.width.px]="'320'" — CSS units like px, em, % in binding keys are not scoped
  • [style]="{ color: 'red' }" — object literal style values get no CSS scoping
  • Host metadata style:, '[style]', '[style.prop.unit]' — same lack of CSS awareness

This results in style values appearing as uniform string colors in the editor, losing the visual distinction between property names, values, units, custom properties, and separators that users get in <style> blocks and .css files.

Depends on: #67357

What is the new behavior?

Style bindings now receive CSS-aware syntax scoping that matches the behavior of <style> blocks and .css files:

Template bindings

  • style="color: red; font-size: 14px" — full CSS declaration scoping (property names, values, separators)
  • [style]="'border: 1px solid black; --padding: 1em'" — CSS declarations inside string literals
  • [style.prop.unit]="'value'" — CSS property-value scoping with keyword.other.unit.css for units
  • [style]="{ color: 'red', 'font-size': '14px' }" — object literal keys as CSS property names, values as CSS values
  • CSS custom properties (--custom-prop) get variable.css scoping

Host metadata

  • style: 'display: block; border: 1px solid black' — CSS declaration scoping
  • '[style]': '"width: 200px; height: 50px"' — CSS declaration scoping
  • '[style.padding.px]': '"8"' — CSS value scoping with unit awareness

Markdown fences

  • CSS scoping works inside angular-html and angular-ts fenced code blocks

Scope assignments

Token Scope
Property name (color, border) meta.property-name.css support.type.property-name.css
Custom property (--gap) meta.property-name.css variable.css
Separator (:) punctuation.separator.key-value.css
Terminator (;) punctuation.terminator.rule.css
Value content source.css#property-values (delegated to VS Code CSS grammar)
Unit in key (px, em, %) keyword.other.unit.css

Screenshots

image image image

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

  • This branch is based on fix/issue-66641-vscode-only (Dedicated markdown-fence grammar support for angular-ts and angular-html #67357) and adds CSS scoping on top of the markdown fence grammar support.
  • Validation runs:
    • pnpm bazel test //vscode-ng-language-service/syntaxes/test:test (pass)
    • pnpm bazel test //vscode-ng-language-service/integration/e2e:test --test_output=errors --test_env=PATH=/opt/X11/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin --nocache_test_results (pass)
  • E2e test coverage includes:
    • Parity matrix comparing <style> block, .css file, style="" attribute, [style] binding, [style.prop.unit] binding, and [style] object literal — asserting identical CSS scopes across all contexts
    • Host metadata CSS scoping tests for static style:, dynamic '[style]', and '[style.prop.unit]' bindings
    • Fence CSS scoping tests verifying CSS awareness inside angular-html and angular-ts markdown blocks
    • Negative tests: expression bindings (e.g., [style]="dynamicStyle") correctly get NO CSS scopes
    • Edge cases: !important, single-quoted style='...', multiline style attributes, Angular control flow after style bindings
  • embeddedLanguages mappings added to package.json for source.css in angular-html, angular-ts, and the inline template grammar — enabling VS Code CSS IntelliSense features (completions, hover, color pickers) inside style bindings
  • Snapshot tests updated for both template-tag and host-object-literal grammars

@pullapprove pullapprove bot requested review from josephperrott and kirjs March 2, 2026 21:10
@angular-robot angular-robot bot added detected: feature PR contains a feature commit area: vscode-extension Issues related to the Angular Language Service VsCode extension labels Mar 2, 2026
@ngbot ngbot bot added this to the Backlog milestone Mar 2, 2026
Copy link
Member

@josephperrott josephperrott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Reviewed-for: dev-infra

@kbrilla kbrilla force-pushed the feat/css-style-scoping branch from c2de52e to 78c1a3f Compare March 2, 2026 21:56
kbrilla added 5 commits March 3, 2026 15:06
Stabilizes e2e activation/waits, runner launch args/timeouts, and test constants for markdown fixture targeting.
Adds angular-ts/angular-html markdown fence grammars and injection wiring for inline template/styles and host bindings in fenced contexts.
Include the fenced inline-template scope fix and checklist cleanup in the e2e coverage update so branch history stays at three commits.
@kbrilla kbrilla force-pushed the feat/css-style-scoping branch from 78c1a3f to 8998d0e Compare March 3, 2026 14:15
@JeanMeche JeanMeche marked this pull request as draft March 3, 2026 23:16
@JeanMeche
Copy link
Member

Marking as draft as its coupled with a previous PR: #67357

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: vscode-extension Issues related to the Angular Language Service VsCode extension detected: feature PR contains a feature commit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants