Skip to content

Feature request: Type-safe component CSS with implicit "$styles" in templates #71879

Open

Description

@Flarette

Which @angular/* package(s) are relevant/related to the feature request?

compiler, compiler-cli

Description

Angular provides style encapsulation but doesn't type-check CSS class references in templates. Renaming or removing a class from a component stylesheet can silently break its usage.

Validating existing class attributes or [class.name] bindings isn't viable because classes may come from global stylesheets, Tailwind, or third-party libraries.

Proposed solution

Introduce an implicit, compiler-provided $styles object in Angular templates, exposing class names declared in the component's own stylesheets (styleUrl, styleUrls, or inline styles).

Example:

/* button.component.css */
.primary { background: blue; }
.loading { opacity: 0.5; }
<!-- Existing syntax remains unrestricted -->
<button class="flex items-center" [class.loading]="loading()">
  Save
</button>

<!-- Explicitly type-checked local CSS references -->
<button [class]="$styles.primary">Save</button>
<button [class]="$styles.missing">Save</button>
<!-- Error: 'missing' does not exist -->

This could enable compile-time diagnostics, autocomplete, go-to-definition, and rename refactoring across templates and stylesheets.

Alternatives considered

TypeScript 7.1 content mappers could potentially provide stylesheet-derived types to Angular's existing template type-checking infrastructure.

$styles would be a compile-time abstraction resolving to ordinary class names, requiring no runtime object, CSS Modules imports, or changes to Angular's existing view encapsulation.

Angular would control the content mapper and language service highlighting.
Can leverage css modules under the hood. The limitation is not having access to the $styles object in the ts but existing @let synax should be good enough for dynamic class composition directly in the template.

Edge case: <component [prop]="$styles" (emit)="handler($styles)/> - can leak into the ts. Which basicaly forces a css module implementation if to be supported. Alternative is compile error.

css modules had been rejected before when used "as is", but this is a controlled angular api that would leverage content mappers so it deserves a discussion.

Activity

  1. added this to the needsTriage milestone on Nov 8, 2026
  2. added this to the needsTriage milestone on Nov 8, 2026
  3. Flarette commented on Nov 8, 2026

    @Flarette
    ContributorAuthor

    $styles follows the existing $index $event etc. pattern

  4. JeanMeche commented on Nov 8, 2026

    @JeanMeche
    Member

    This unfortunately not compatible with any style preprocessor as they are executed separately from the template compilation infra. (and it also obviously incompatible with JIT compilation)

  5. Flarette commented on Nov 8, 2026

    @Flarette
    ContributorAuthor

    This unfortunately not compatible with any style preprocessor as they are executed separately from the template compilation infra. (and it also obviously incompatible with JIT compilation)

    The native css is very capable nowadays and preprocessors are becoming less valuable. Angular offers plain .css as an option, is it possible to make it a .css specific featue? Since its scoped to the components is should not affect libraries. JIT can be documented as a known limitation. Most projects use AOT anyways.

  6. added
    featureLabel used to distinguish feature request from other issues
    on Nov 8, 2026
  7. modified the milestones: needsTriage, Backlog on Nov 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: compilerIssues related to `ngc`, Angular's template compilerfeatureLabel used to distinguish feature request from other issues

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions