Component Styles and View Encapsulation
Scoping CSS to a single component and understanding Angular's default view encapsulation.
阅读需 2 分钟
A CSS file attached to a component in Angular doesn't leak out and affect the rest of the app, and other components' styles don't leak in. This is view encapsulation, and it's on by default.
Styles are scoped per component
@Component({
selector: 'app-alert',
template: `<div class="box">{{ message }}</div>`,
styles: [`
.box {
padding: 1rem;
border-radius: 6px;
background: #fef3c7;
}
`],
})
export class AlertComponent {
message = 'Something needs your attention.';
}If a second, unrelated component also defines a .box class with completely different styles, the two won't collide. Angular achieves this by rewriting selectors behind the scenes, attaching a generated attribute (something like _ngcontent-xyz) to every element this component renders and to every selector in its stylesheet, so .box effectively only ever matches .box[_ngcontent-xyz].
Seeing it in the rendered DOM
If you inspect a running Angular app in the browser, you'll notice these generated attributes on nearly every element:
<div class="box" _ngcontent-ng-c123456789>Something needs your attention.</div>This is Angular's default ViewEncapsulation.Emulated strategy — it emulates the effect of Shadow DOM style scoping without actually using Shadow DOM, which keeps things simpler and more compatible across browsers.
Reaching outside a component's own scope
Occasionally a component legitimately needs to style something it renders that isn't part of its own template — most often content projected in from a parent (covered in a later lesson). The :host selector targets the component's own host element, and combining it with descendant selectors reaches into projected content:
:host {
display: block;
border: 1px solid #e5e7eb;
}
:host(.compact) {
padding: 0.25rem;
}:host styles the <app-alert> element itself, not just what's inside it — useful for things like display and border that need to apply to the component as a whole. :host(.compact) applies only when the host element also carries a compact class, letting a parent influence the component's own styling through a class binding.
When to turn encapsulation off
Global styles — a CSS reset, typography defaults, third-party component overrides — don't belong scoped to one component. Those live in the app-wide styles.css (or styles.scss) file set up when the project was created, which applies unencapsulated to the whole document. Reach for component-level styles for anything specific to that component, and global styles for anything meant to apply everywhere; mixing the two up is a common source of "why isn't my CSS working" confusion in Angular apps.