“ViewEncapsulation” in Angular
Tags: angular
Published: 2023-10-03 12:14:19

Ah, [`ViewEncapsulation`](https://angular.io/api/core/ViewEncapsulation)!

It’s what keeps you asleep through the night! Or does it? 😊

Let’s refresh our knowledge about `ViewEncapsulation`.

### `ViewEncapsulation.Emulated`

By default, all Angular components come with something called “style encapsulation”. It means that a component “encapsulates” its own styles so they **only** apply to elements within its scope. Styles defined in one component will **not** have an effect on the elements in another component.

Angular achieves this by _adding a specific attribute to the component’s host element and applying the same attribute to all the CSS selectors provided via `Component#styles` or `Component#styleUrls`._ (taken from Angular’s docs)

Considering a component to be an independent unit, this is the expected behaviour. You don’t want your components to “leak” styles that affect “outside” elements.

The above is done by setting the `Component.encapsulation` option to `ViewEncapsulation.Emulated` (or not setting it at all since that’s the default value).

Looking at the DevTools in the Figure 1 below, you can see that the `my-app` component has a `_nghost-ng-<id>` attribute. The same `<id>` is also added to the `_ngcontent-ng-<id>` attribute present on all child elements.

![ViewEncapsulation.Emulated in Angular](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ck32vtip2vbr1izk6r9d.jpg)

Note that the `<id>` is auto-generated by Angular and you should not rely on it being the same every time. So don’t style elements with `_ngcontent-ng-abc123`!

### `ViewEncapsulation.None`

View encapsulation can be turned off on a component by setting the `Component.encapsulation` option to `ViewEncapsulation.None`.

But beware! Turning view encapsulation off means that all of the component’s styles now apply globally. They will no longer be scoped to the component, and can therefore affect any HTML element in the application.

You can see that by inspecting the component’s elements in DevTools.

![ViewEncapsulation.None in Angular](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/koxbfhk738nshd1dp8f8.jpg)

Figure 2 above shows us that the `_nghost-ng-<id>` attribute is no longer present on the `my-app` component, nor on any child elements. Styles added to `h1` will now “leak” from the component and affect any other `h1`s on the page. Had there been another `h1` on the page, even in a completely different component, the `color: tomato` style would be applied to it.

There are valid reasons for turning encapsulation off, e.g. styling 3rd party components, or because parts of a component are dynamically created/moved to some other part of the DOM, e.g. a modal that is created as a child to `body`. Whatever the case, beware that the styles you add to a component might have an effect on unrelated elements!

But what if you want to disable view encapsulation on a component but still keep some, or all of its styles scoped to the component?

You can achieve this by nesting the styles under the component’s selector, i.e.

```scss
my-component {
  h1 {
    color: tomato;
  }
}
```

![ViewEncapsulation.None with component selector](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c0pgmmlsxlmrhuaangy8.jpg)

### `ViewEncapsulation.ShadowDom`

`Component.encapsulation` can take a third value - [`ViewEncapsulation.ShadowDom`](https://angular.io/api/core/ViewEncapsulation#ShadowDom) but so far I’ve never used it in my apps. Once set, it _uses the browser’s native Shadow DOM API to encapsulate CSS styles, ..._ (taken from Angular’s docs).

It looks like this in DevTools:

![ViewEncapsulation.ShadowDom](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/92nm1y3cdq7nrqgewj52.jpg)

I don’t have experience with `ShadowDom`, so I’ve included it only for reference. You can decide for yourself whether it makes sense to use it in your apps.

Well, that’s it! I hope you learned something new about style encapsulation in Angular.

See you in the next post 👋

---

Photo by <a href="https://unsplash.com/@sadswim?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">ian dooley</a> on <a href="https://unsplash.com/photos/DuBNA1QMpPA?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>