What Is ViewEncapsulation in Angular?

Vibha Sharma
4 min readMar 24, 2021
ViewEncapsulation
ViewEncapsulation

In Angular, component CSS styles are encapsulated into the component’s view and don’t affect the rest of the application.

As we know Angular Components are made up of three things:

  1. Component Class
  2. Template
  3. Style

The combination of these three factors makes an Angular component reusable across an application. Angular also provides these feature for Components and we can control it with the encapsulation property.

We can set the view encapsulation mode in the component metadata to control how this encapsulation happens on a per component basis.

The valid values for this config property are:

  • ViewEncapsulation.ShadowDom
  • ViewEncapsulation.Emulated
  • ViewEncapsulation.None

The default value is ViewEncapsulation.Emulated

To understand ViewEncapsulation in Angular, first, we should understand the Shadow DOM. Simply put, the Shadow DOM brings Encapsulation to HTML Elements. Using the Shadow DOM, markup, styles, and behaviors are scoped to the element and do not clash with other nodes of the DOM. The Shadow DOM is part of Web Components, which encapsulates styles and login of the element.

Let’s try to understand it using an example:

ViewEncapsulation.None:

Let’s create a component as component1:

component1.component.ts:

To understand different ViewEncapsulation options, we will add the metadata as encapsulation: ViewEncapsulation.None to component1.

import {Component, OnInit, ViewEncapsulation} from'@angular/core';@Component({
selector: 'app-component1',
templateUrl: './component1.component.html',
styleUrls: ['./component1.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class Component1 implements OnInit {
constructor() { }
ngOnInit(): void {}
}

component1.component.css:

h1 {
background: gray;
color: white;
text-transform: capitalize;
text-align: center;
width: max-content;
padding: 30px;
}

component1.component.html:

<h1>Test Encapsulation component1</h1>

Let’s create another component as component2:

import { Component, OnInit } from '@angular/core';@Component({
selector: 'app-component2',
templateUrl: './component2.component.html',
styleUrls: ['./component2.component.scss']
})
export class Component2 implements OnInit {
constructor() { }
ngOnInit(): void {}
}

component2.component.html:

<h1>Test Encapsulation component2</h1>

In component2, we are also using the h1 tag.

In ViewEncapsulation.None:

  1. There is no shadow DOM.
  2. Style is not scoped to the component.

As we run the application, we will find h1 style has applied to both components, even though we only set style the in component1. This happened because in component1 we have set the encapsulation property to ViewEncapsulation.None

Kindly check the screenshot below forViewEncapsulation.None:

ViewEncapsulation.None, changes will reflect to both component
ViewEncapsulation.None

ViewEncapsulation.Emulated:

Now if we changed the ViewEncapsulation mode to emulated which is the by default option, the output will be different.

  1. Angular will not create a Shadow DOM for the component.
  2. The style will be scoped to the component.
  3. This is the default value for encapsulation.

component1.component.ts:

import {Component, OnInit, ViewEncapsulation} from'@angular/core';@Component({
selector: 'app-component1',
templateUrl: './component1.component.html',
styleUrls: ['./component1.component.scss'],
encapsulation: ViewEncapsulation.Emulated
})
export class Component1 implements OnInit {
constructor() { }
ngOnInit(): void {}
}

We have changes the encapsulation in component1.component.ts only and the rest of the things remain the same.

Let’s run the application now, we will find the h1 style changes in component1 only, not in component2. This is due to emulated scoping.

In this, the style is scoped only to the component. In this option, Angular only emulates the Shadow DOM and does not create a real shadow DOM. Hence, the application that runs in browsers does not support a Shadow DOM also and styles are scoped to the component as well.

Kindly check the screenshot below forViewEncapsulation.Emulated:

ViewEncapsulation.Emulated, Changes will be scoped to the componet
ViewEncapsulation.Emulated

ViewEncapsulation.ShadowDom:

Now if we changed the ViewEncapsulation mode to ShadowDom, the output will be different.

  1. Angular will create Shadow DOM for the component.
  2. Style is scoped to the component.

component1.component.ts:

import {Component, OnInit, ViewEncapsulation} from'@angular/core';@Component({
selector: 'app-component1',
templateUrl: './component1.component.html',
styleUrls: ['./component1.component.scss'],
encapsulation: ViewEncapsulation.ShadowDom
})
export class Component1 implements OnInit {
constructor() { }
ngOnInit(): void {}
}

We have changes the encapsulation in component1.component.ts only and the rest of the things remain the same.

Let’s run the application now, Here Angular is using the shadow DOM because of ViewEncapsulation.ShadowDom

Now, if we look at the application h1 changes will be applied to component1 only. The angular renders the component inside the #shadow root element. The styles from the component along with the styles from the parent and other components are also injected inside the shadow root

ViewEncapsulation.ShadowDom, Changes will be scoped to component only. The angular renders the component inside the #shadow root element
ViewEncapsulation.ShadowDom

According to angular.io, Native is now deprecated in favor of ShadowDOM implementation. The reason for the change is that the Native ViewEncapsulation uses the deprecated version of ShadowDOM, and the new one uses the current version of the standard. (For the browsers that support it).

NOTE: To know more about shadow DOM, Kindly check this: https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM

Thanks for Reading!!!!!!!!

--

--