Scoping Your Styles in Angular With ViewEncapsulation

An application framework like Angular allows to create web applications that are made of reusable and independent building blocks (components). For this to work however, we need a way for CSS rules to only apply within a given component.

We briefly mentioned view encapsulation in our post about applying styles between components, but let’s now explain things a bit more.

This post applies to Angular 2+ apps.

For example, say we have a component template that looks like this:

app.component.html

<h1>
  Hello, I am a {{ animal }}
</h1>

And we want to style our h1 element for this component like this:

app.component.css

h1 {
  background: pink;
  color: white;
  font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande',
    'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
  text-transform: uppercase;
  text-align: center;
  padding: 1rem 0;
}

Without any view encapsulation, any other h1 element in your app would inherit these styles.


The default view encapsulation mode in Angular, for now, is Emulated. You can specify a different mode in your components like this:

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  encapsulation: ViewEncapsulation.None
})
export class AppComponent {
  animal = '🐰';
}

Let's go over the 3 available values for ViewEncapsulation:

ViewEncapsultion.Native

This is the encapsulation mode that would be ideal and it uses the Shadow DOM to scope styles only to that specific component.

Here’s how the encapsulation with shadow DOM looks like in Chrome DevTools:

Shadow DOM in DevTools

The only problem right now however is that support for Shadow DOM is still lacking:

Can I Use shadowdom? Data on support for the shadowdom feature across the major browsers from caniuse.com.

At this time, you'll probably want to use Native ViewEncapsulation only if you're targeting a narrow set of modern browsers, or you're working on an app that won't see the light of day for a little while.

ViewEncapsultion.Emulated (the default)

Short of being able to use native view encapsulation in production yet, the Emulated mode is what allows us to achieve the same effect.

With this mode, Angular adds attributes to our component templates like this:

<h1 _ngcontent-c0>
  Hello, I am a 🐰
</h1>

And the styles, which can be found in the document’s head are scope to these attributes:

h1[_ngcontent-c0] {
  background: pink;
  color: white;
  font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande',
  'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
  text-transform: uppercase;
  text-align: center;
  padding: 1rem 0;
}

ViewEncapsultion.None

This removes any encapsulation and all CSS rules will have a global effect. This mode is comparable to how we’ve been developing web apps prior to separating our apps into reusable components.

With ViewEncapsultion.None, adding rules to CSS file that’s tied to a component is the equivalent to adding the same rules to a global styles.css file.

You'll probably want to use None only when working on smaller apps or for components that should share global styles.

Learning More

Here are two great posts that go even more in-depth on the topic:

  Tweet It
✖ Clear

🕵 Search Results

🔎 Searching...