Templates, Styles and Encapsulation
PlantCard now has a template and a stylesheet. As Greenhouse grows, dozens of components will each have an h3 rule. If every rule applied to the whole page, the last one loaded would win and the design would fall apart. Angular prevents that by default.
The rule
A component's styles stay home; global styles live in
styles.css.
First, where the HTML and CSS live. Short ones can sit inline; longer ones go in their own files:
@Component({
selector: 'app-plant-card',
templateUrl: './plant-card.html',
styleUrl: './plant-card.css',
})
export class PlantCard {}Use exactly one of template or templateUrl. For CSS, styles holds inline CSS and styleUrl (or styleUrls for a list) points at files.
Now the scoping. By default Angular uses emulated encapsulation. It stamps every element in the component's template with a generated attribute, such as _ngcontent-abc-1, and rewrites each selector to require it. So h3 { color: seagreen; } becomes, in effect, h3[_ngcontent-abc-1], which only matches this component's headings.
Two extra tools:
:hoststyles the component's own tag,<app-plant-card>, from inside::host { display: block; border: 1px solid #ccc; }.encapsulationin the metadata changes the mode:
import { ViewEncapsulation } from '@angular/core';
@Component({
// ...
encapsulation: ViewEncapsulation.None,
})| Mode | Effect |
|---|---|
Emulated (default) |
Styles scoped with generated attributes |
None |
Styles become global and can hit any element |
ShadowDom |
Uses the browser's real Shadow DOM |
The shortcut
Before writing a rule, ask "whose element is this?" If it is in this component's template, write it in this component's styles. If it is this component's own tag, use :host. If it is everywhere, like body fonts, put it in src/styles.css.
The plant name heading
It sits in
PlantCard's template, so the rule goes inplant-card.css.
The trap is switching to ViewEncapsulation.None to fix one stubborn style. Every rule in that component now applies to the whole app, and a harmless button { } rule suddenly restyles every button.
Drills
Answer fast — trust the rule.
PlantCard styles p { font-size: 12px; }. Which paragraphs shrink by default?
Which selector styles the <app-plant-card> element from inside its own stylesheet?
Where should a font rule that applies to the entire app go?
What does ViewEncapsulation.None do?
Remember
- Inline
template/stylesor separate files viatemplateUrl/styleUrl. - Component styles are scoped by default;
:hoststyles the component's own tag; global rules go instyles.css. - Trap:
ViewEncapsulation.Noneleaks every rule in that component.
