Angular Styling
Styling in Angular uses class/style bindings in templates and component-scoped CSS for maintainable, theme-friendly UIs.
Styling Essentials
- Bindings: Use
[class.foo]/[ngClass]for classes and[style.prop]/[ngStyle]for styles. - Themes: Toggle CSS variables to switch light/dark or accents.
- Encapsulation: Component styles are scoped by default; use
:hostand:host-context()for host/theme styling.
<div [class.active]="isActive" [ngClass]="{ big: big }" [style.color]="color" [ngStyle]="{ padding: pad + 'px' }">...</div>Related: SeeData Binding for property/class/style bindings,Templates for applying directives, andComponents for component-scoped styles.
Tip: Use class bindings over inline styles for maintainability.
ImportCommonModule forngClass/ngStyle in standalone components.
Use CSS variables to implement theme toggles efficiently.
Encapsulation: Component styles are scoped by default.
Use:host to style the component root and:host-context(.theme-dark) to react to a parent theme.
Basic Styling
<div [class.highlight]="highlight" [ngClass]="{ big: big }" [style.color]="color" [style.borderColor]="color">...</div>Use[class.foo] for single boolean toggles and[ngClass] when applying multiple classes.
Use classes for reusable look-and-feel.
Use[style.prop] for one-off numeric or dynamic values (like color, width, padding).
Keep complex styling in CSS classes.
Example
import { bootstrapApplication } from '@angular/platform-browser';import { Component } from '@angular/core';import { CommonModule } from '@angular/common';@Component({ selector: 'app-root', standalone: true, imports: [CommonModule], styles: [` .box { padding: 12px; border: 2px solid #ccc; margin-top: 8px; border-radius: 6px; } .highlight { background: #fffa8b; } .big { font-size: 24px; } .toolbar button { margin-right: 6px; } `], template: ` <h3>Styling</h3> <div> <button (click)="toggleHighlight()">Toggle Highlight</button> <button (click)="toggleBig()">Toggle Big</button> <button (click)="setColor('crimson')">Crimson</button> <button (click)="setColor('seagreen')">Green</button> <button (click)="setColor('royalblue')">Blue</button> </div> <div [class.highlight]="highlight" [ngClass]="{ big: big }" [style.color]="color" [style.borderColor]="color"> Styled box </div> `})export class App { highlight = false; big = false; color = 'royalblue'; toggleHighlight() { this.highlight = !this.highlight; } toggleBig() { this.big = !this.big; } setColor(c: string) { this.color = c; }}bootstrapApplication(App);<app-root></app-root>Example explained
[class.highlight]: Toggles thehighlightclass with a boolean.[ngClass]: Applies multiple classes from an object (e.g.,{ big: big }).[style.color]/[style.borderColor]: Bind style properties to the currentcolor.- Toolbar: Buttons update component state to demonstrate the bindings.
Bindings over literal class=: Usingclass="..." together with[ngClass] can overwrite classes.
Use[class.foo]/[ngClass] for predictable toggles.
Boolean values: Avoid string booleans like[class.active]="'false'".
Bind real booleans:[class.active]="isActive".
Import CommonModule:ngClass/ngStyle live inCommonModule for standalone components.
Dynamic Styling
<div [ngClass]="{ fancy: fancy, rounded: rounded }" [ngStyle]="{ color: color, padding: pad + 'px' }">...</div>Two-way binding with controls lets you change styles live.
[ngClass] toggles classes based on booleans, and[ngStyle] sets several style properties at once.
Tip: For performance and clarity, keep style objects small and focused.
Favor classes for larger visual changes.
Example
import { bootstrapApplication } from '@angular/platform-browser';import { Component } from '@angular/core';import { CommonModule } from '@angular/common';import { FormsModule } from '@angular/forms';@Component({ selector: 'app-root', standalone: true, imports: [CommonModule, FormsModule], styles: [` .box { border: 2px solid #ccc; margin-top: 12px; border-radius: 6px; transition: all .15s ease-in-out; } .fancy { box-shadow: 0 2px 8px rgba(0,0,0,.15); background: #f9fbff; } .rounded { border-radius: 14px; } .toolbar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; } .toolbar label { display: inline-flex; align-items: center; gap: 6px; } `], template: ` <h3>Dynamic Styling</h3> <div> <label><input type="checkbox" [(ngModel)]="fancy"> Fancy</label> <label><input type="checkbox" [(ngModel)]="rounded"> Rounded</label> <label>Color <input type="color" [(ngModel)]="color"></label> <label>Padding <input type="range" min="0" max="40" [(ngModel)]="padding"> {{ padding }}px</label> <label>Font Size <input type="range" min="12" max="36" [(ngModel)]="fontSize"> {{ fontSize }}px</label> </div> <div [ngClass]="{ fancy: fancy, rounded: rounded }" [ngStyle]="{ color: color, borderColor: color, padding: padding + 'px', fontSize: fontSize + 'px' }"> Styled box </div> `})export class App { fancy = true; rounded = false; color = '#4169e1'; padding = 12; fontSize = 18;}bootstrapApplication(App);<app-root></app-root>Example explained
[(ngModel)]: Two-way binds form controls to component fields.[ngClass]: Togglesfancy/roundedbased on booleans.[ngStyle]: Sets several style properties at once from component state.
Keep ngStyle small: Large inline style objects become hard to maintain.
Move most styling into CSS classes and bind only dynamic bits.
Encapsulation
:host { display: block; }:host(.dense) { padding: 8px; }:host-context(.theme-dark) { color: #eee; }Component styles are scoped by default to their host element.
Use:host and:host-context() for host and theme-aware styling.
Modes: Default isEmulated.
UseNone sparingly for global styles (e.g., third-party overrides).
ShadowDom isolates styles fully.
Host styling: Use:host over selecting wrapper tags.
Combine with classes on the host for variants (e.g.,:host(.dense)).
Theme context: Use:host-context(.theme-dark) to adapt to parent themes without leaking global CSS.
Avoid deep selectors: Don't rely on.parent .child chains inside components.
Expose tokens via CSS variables instead.
Theme with CSS Variables
<div [class.theme-dark]="dark"> <button (click)="dark = !dark">Toggle {{ dark ? 'Light' : 'Dark' }}</button> <button (click)="setAccent('#e91e63')">Pink</button> <button (click)="setAccent('#00b894')">Green</button> <button (click)="setAccent('#ff9800')">Orange</button> <span [style.background]="accent"></span></div><div [style.--accent]="accent"> This box follows the current theme and accent color.</div>CSS variables are named paint buckets you can swap at runtime.
Toggle a class to switch buckets (light/dark) and bind the accent variable for instant theme changes.
Use variables for colors, spacing, and shadows so components can respond to theme changes without code changes.
Example
import { bootstrapApplication } from '@angular/platform-browser';import { Component } from '@angular/core';import { CommonModule } from '@angular/common';@Component({ selector: 'app-root', standalone: true, imports: [CommonModule], styles: [` :host { --bg: #ffffff; --fg: #222; --accent: #4169e1; } .theme-dark { --bg: #121212; --fg: #eaeaea; --accent: #4f8cff; } .toolbar { display: flex; gap: 8px; align-items: center; } .swatch { width: 18px; height: 18px; border-radius: 50%; border: 1px solid #ccc; display: inline-block; vertical-align: middle; } .box { margin-top: 10px; padding: 14px; border-radius: 8px; border: 2px solid var(--accent); background: var(--bg); color: var(--fg); transition: all .15s ease-in-out; } button { padding: 6px 10px; } `], template: ` <h3>Theme with CSS Variables</h3> <div [class.theme-dark]="dark"> <button (click)="dark = !dark">Toggle {{ dark ? 'Light' : 'Dark' }}</button> <button (click)="setAccent('#e91e63')">Pink</button> <button (click)="setAccent('#00b894')">Green</button> <button (click)="setAccent('#ff9800')">Orange</button> <span [style.background]="accent"></span> </div> <div [style.--accent]="accent"> This box follows the current theme and accent color. </div> `})export class App { dark = false; accent = '#4169e1'; setAccent(c: string) { this.accent = c; }}bootstrapApplication(App);<app-root></app-root>Example explained
- Theme tokens: CSS variables (e.g.,
--bg,--fg,--accent) define the theme. - Toggle: Adding
theme-darkon the toolbar swaps variable values. [style.--accent]: Binds a custom CSS property; the box reads it viavar(--accent).
Don't hard-code colors: Binding literal colors (e.g.,[style.color]="'red'") fights theming.
Use CSS variables and classes.
Scope variables carefully: Keep theme variables at the component host or a top-level theme wrapper to avoid conflicts.
Respect user preference: Use@media (prefers-color-scheme: dark) to set a sensible default, then allow toggling.
Design tokens: Define semantic tokens (e.g.,--surface,--text,--accent) and reference them in components for consistent theming.

