Introduction
When building Angular applications, styles can quickly become messy if every component’s CSS is applied across the entire app. This is where ViewEncapsulation comes in. It’s Angular’s mechanism for controlling whether a component’s styles remain scoped and private, or leak into the global stylesheet. By choosing between Emulated, None, and ShadowDom, developers can decide how much isolation they want — balancing flexibility, reusability, and maintainability.
What is ViewEncapsulation?
At its core, ViewEncapsulation tells Angular how to attach styles to the DOM. Instead of placing all CSS into a single global scope (like in traditional web apps), Angular gives you control over how tightly styles are scoped to a component. Under the hood, Angular can:
- Emulate encapsulation by rewriting selectors with unique attributes,
- Disable encapsulation and let styles behave globally, or
- Rely on the browser’s Shadow DOM for true native isolation.
This approach makes it easier to manage large applications by preventing style conflicts, while still giving you the option to share or isolate styles depending on your needs.
Encapsulation Modes in Angular
Angular provides three encapsulation strategies. Each one defines how component styles are applied to the DOM. It controls whether the CSS defined in a component affects only that component or can “leak” out to others.
There are three main modes:
1. None
- No encapsulation. Styles are global and will affect the entire app.
- Useful when you want global theming.
@Component({
selector: 'app-no-encapsulation',
standalone: true,
imports: [],
template: `
<div class="none-wrapper">
<h2>None</h2>
<div class="none-message">No encapsulation</div>
</div>
`,
styles: [`
h2, .none-message {
color: red;
}
.none-wrapper {
border: 2px solid red;
padding: 10px;
margin: 5px;
}
`],
encapsulation: ViewEncapsulation.None
})
export class NoEncapsulationComponent {}
⚠️ Result: All <h2> tags across the entire app turn red, not just inside this component.
2. Emulated (default)
- Angular emulates Shadow DOM behavior using attribute selectors by adding unique attributes (like _nghost-c0 or _ngcontent-c0) to elements and styles. This ensures styles apply only to that component.
- With ViewEncapsulation.Emulated, Angular pre-processes all the component’s styles so that they are only applied to the component’s view. This is the most commonly used option in Angular apps.
@Component({
selector: 'app-emulated-encapsulation',
standalone: true,
imports: [NoEncapsulationComponent],
template: `
<div class="emulated-wrapper">
<h2>Emulated</h2>
<div class="emulated-message">Emulated encapsulation</div>
<app-no-encapsulation></app-no-encapsulation>
</div>
`,
styles: [`
h2, .emulated-message {
color: green;
}
.emulated-wrapper {
border: solid 2px green;
padding: 10px;
margin: 5px;
}
`],
encapsulation: ViewEncapsulation.Emulated // default
})
export class EmulatedEncapsulationComponent {}
✅ Result: The <h2> inside this component is green, but <h2> tags in other components remain unchanged.
3. ShadowDom
- Angular actually uses the browser’s real Shadow DOM.
- Styles are completely isolated inside the component’s shadow root.
- Best for building reusable web components.
- Supported only in modern browsers.
@Component({
selector: 'app-shadow-dom-encapsulation',
standalone: true,
imports: [NoEncapsulationComponent, EmulatedEncapsulationComponent],
template: `
<div class="shadow-dom-wrapper">
<h2>ShadowDom</h2>
<div class="shadow-message">Shadow DOM encapsulation</div>
<app-emulated-encapsulation></app-emulated-encapsulation>
<app-no-encapsulation></app-no-encapsulation>
</div>
`,
styles: [`
h2, .shadow-message {
color: blue;
}
.shadow-dom-wrapper {
border: 2px solid blue;
padding: 10px;
margin: 5px;
}
`],
encapsulation: ViewEncapsulation.ShadowDom
})
export class ShadowDomEncapsulationComponent {}
🔒 Result: The <h2> inside the ShadowDomEncapsulationComponent appears red because it inherits the global styles injected by the NoEncapsulationComponent. Meanwhile, the <h2> in the EmulatedEncapsulationComponent remains unaffected and stays green.
🚩 Why: Normally, Shadow DOM blocks global styles. But when a ViewEncapsulation.None component is rendered inside a ShadowDom component, its styles are injected into that shadow root. From there, the styles can affect other elements inside the same shadow boundary, following normal CSS cascade rules.
Demo
Now you will have the page as below
However it’s a little bit difference with Angular example at – https://v17.angular.io/guide/view-encapsulation and I will talk about that in the next post.
A Quick Note on Shadow DOM
The Shadow DOM is a browser feature that lets web components have their own isolated DOM tree and styles, hidden from the main document. For example, the <video> element in HTML uses Shadow DOM internally for its controls — you can’t directly style the play button or progress bar because they live inside the element’s shadow root.
- With
ViewEncapsulation.Emulated, Angular simulates this isolation by rewriting CSS selectors with special attributes. - With
ViewEncapsulation.ShadowDom, Angular relies on the browser’s real Shadow DOM, giving components true style encapsulation that global styles cannot cross.
Constraints & Considerations
Choosing the right ViewEncapsulation mode isn’t just about preference — each option comes with trade-offs you should be aware of:
1. Global Styles and Theming
- With
ShadowDom, global styles (like Bootstrap or Tailwind utilities) cannot penetrate the shadow boundary. - You’ll need to rely on CSS variables or manually provide styles inside each shadow component.
2. Third-Party Libraries
- Many UI libraries (Angular Material, PrimeNG, etc.) assume styles are global or at least emulated.
- Wrapping them in ShadowDom can break layouts or require extra configuration.
3. Cross-Component Styling
- Emulated allows parent/child components to influence each other’s styles (with tools like
::ng-deep). ShadowDomcompletely isolates styles — making it harder to apply shared themes.
4. Browser Support
ShadowDomrelies on nativeShadow DOMsupport (modern browsers are fine, but older browsers like IE11 are not supported).- Emulated works everywhere Angular supports.
5. Performance
- Each
Shadow Rootis isolated, which can add a small overhead in very large applications with many components. - Emulated is generally lighter and better suited for apps with hundreds of components.
Conclusion
ViewEncapsulation is Angular’s way of controlling how component styles interact with the rest of your application. By choosing between Emulated, None, and ShadowDom, you decide whether styles should be scoped to a single component, applied globally, or fully isolated using the browser’s Shadow DOM.
For most projects, the default Emulated mode strikes the right balance between isolation and flexibility. But when you need global theming across the app, or true encapsulation for reusable web components, Angular gives you the tools to adapt.
Understanding these options early helps you keep your project maintainable, consistent, and free from unexpected style conflicts as it scales.