Episode 6 of 27

Templates & CSS

Work with Angular templates and component styles — interpolation, view encapsulation, and global vs component CSS.

Templates & CSS

Templates define what a component looks like. They're HTML files enhanced with Angular-specific syntax. CSS in Angular is scoped to each component by default.

Template Basics — Interpolation

<!-- greeting.component.html -->
<h1>{{ title }}</h1>
<p>Welcome, {{ username }}!</p>
<p>2 + 2 = {{ 2 + 2 }}</p>
<p>{{ isLoggedIn ? 'Logged in' : 'Guest' }}</p>
// greeting.component.ts
export class GreetingComponent {
    title = 'My Angular App';
    username = 'Alice';
    isLoggedIn = true;
}

Double curly braces {{ }} — called interpolation — output the value of an expression from the component class.

What Can Go Inside {{ }}?

  • Properties: {{ name }}
  • Expressions: {{ price * quantity }}
  • Method calls: {{ getFullName() }}
  • Ternary operators: {{ isActive ? 'Active' : 'Inactive' }}
  • String methods: {{ name.toUpperCase() }}

What cannot go inside: assignments, new, chaining (;), or global access (console.log).

Component CSS — Scoped by Default

/* user.component.css */
h1 {
    color: #e74c3c;
    font-size: 24px;
}

.card {
    padding: 20px;
    border-radius: 12px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

These styles only apply to this component. An h1 styled here won't affect h1 tags in other components.

How View Encapsulation Works

Angular adds unique attributes to the component's elements:

<!-- What you write: -->
<h1>Hello</h1>

<!-- What Angular renders: -->
<h1 _ngcontent-abc-c42>Hello</h1>

/* Angular rewrites your CSS: */
h1[_ngcontent-abc-c42] {
    color: #e74c3c;
}

This attribute-based scoping ensures styles don't leak between components.

Encapsulation Modes

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
    selector: 'app-user',
    templateUrl: './user.component.html',
    styleUrls: ['./user.component.css'],
    encapsulation: ViewEncapsulation.Emulated  // Default
})

// ViewEncapsulation.Emulated  — Default, attribute-based scoping
// ViewEncapsulation.None      — No scoping, styles are global
// ViewEncapsulation.ShadowDom — Uses native Shadow DOM

Global Styles

Styles in src/styles.css apply to the entire application:

/* src/styles.css — Global */
* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

body {
    font-family: 'Inter', sans-serif;
    background: #f5f7fa;
    color: #333;
}

a {
    color: #3498db;
    text-decoration: none;
}

Use global styles for resets, typography, and base element styles. Use component CSS for everything component-specific.

Multiple Style Files

@Component({
    selector: 'app-dashboard',
    templateUrl: './dashboard.component.html',
    styleUrls: [
        './dashboard.component.css',
        './dashboard-responsive.component.css'  // Additional file
    ]
})

Conditional CSS Classes

<!-- Toggle a class based on a condition -->
<div [class.active]="isActive">Toggle me</div>

<!-- Multiple conditional classes -->
<div [ngClass]="{
    'active': isActive,
    'disabled': isDisabled,
    'highlight': isHighlighted
}">Styled div</div>

Inline Styles

<!-- Dynamic inline style -->
<div [style.background-color]="bgColor">Colored</div>
<div [style.font-size.px]="fontSize">Sized text</div>

<!-- Multiple dynamic styles -->
<div [ngStyle]="{
    'color': textColor,
    'font-size': fontSize + 'px',
    'font-weight': isBold ? 'bold' : 'normal'
}">Dynamic</div>

Key Takeaways

  • {{ }} interpolation renders data from the component class into the template
  • Component CSS is scoped by default — styles don't leak to other components
  • Angular uses attribute-based emulated encapsulation (not Shadow DOM)
  • Global styles go in src/styles.css
  • [class.name] and [ngClass] toggle CSS classes dynamically
  • [style.prop] and [ngStyle] apply inline styles dynamically