What is ViewEncapsulation in Angular?

The Coding Mermaid 🧜‍♀️ - Mar 7 '20 - - Dev Community

The architecture of an Angular application allows to create web applications that are made of reusable and independent building blocks, known as Components .

Styles in an Angular App, can be defined at a global level or they can be defined at the component level.

At a component level, there are some cool features that we can use.

Check the sandbox that I already created and feel free to change or fork it for yourself.

Alt Text

In this sandbox we have the App Component, the Servers Component and the Server Component. For each component, we have a css file. And we also have a global css file, the styles.css.

styles.css

html,
body {
  font-family: sans-serif;
  background-color: black;
  color: white;
}

.title {
  border: 2px solid orange;
  padding: 10px;
  background-color: #ede8e8;
  color: black;
}
Enter fullscreen mode Exit fullscreen mode

Did you notice something already? All the titles in this App, have the same class "title" but none of them is inheriting the orange color defined at the global level.

Why is that?

So, I welcome you to the first of our first encapsulation mode in Angular.😄


ViewEncapsulation.Emulated

The Emulated mode is the default one. This allows that styles from main HTML propagate to the component but styles defined in this component's @Component decorator are scoped to this component only.

Let´s see our components style.

app.component.css

div {
  text-align: center;
}

.title {
  border-color: cyan;
}
Enter fullscreen mode Exit fullscreen mode

servers.component.css

.title {
  border: 3px solid green;
  border-radius: 5px;
  border-width: 7px;
}

h3 {
  font-size: 50px;
}
Enter fullscreen mode Exit fullscreen mode

server.component.css

.title {
  border: 5px solid red;
}
Enter fullscreen mode Exit fullscreen mode

ViewEncapsulation.None

In the None mode, styles from the component propagate back to the main HTML and therefore are visible to all components on the page. Be careful with apps that have None components in the application.

Since the default view encapsulation mode in Angular is Emulated, for us to specify a different mode in your components, we have to do like this:

servers.component.ts

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

@Component({
  selector: "app-servers",
  template: `
    <h3 class="title">App Servers Component</h3>
    <app-server></app-server>
  `,
  styleUrls: ["./servers.component.css"],
  //encapsulation None
  encapsulation: ViewEncapsulation.None
})
export class ServersComponent {}
Enter fullscreen mode Exit fullscreen mode

Notice that ViewEncapsulation was added in the import in order to be used as encapsulation: ViewEncapsulation.None

Try to comment out the previous mode and uncomment this line in the servers.component.ts and see what happen.

The result will be like the image bellow.

Now, all the components have the same border radius, border width and font-size as the Servers Component.

Angular Encapsulation Mode None

Let's inspect our Server Component (not Servers) to see what happened.

Alt Text

From bottom to top, we have the style given in the global file, then we have the style from or Servers Component that is leaking out to our Server Component and in the top we have our component specific style, that has priority above all the other styles.

Remember that we defined these styles before.

servers.component.css

.title {
  border: 3px solid green;
  border-radius: 5px;
  border-width: 7px;
}

h3 {
  font-size: 50px;
}
Enter fullscreen mode Exit fullscreen mode

server.component.css

.title {
  border: 5px solid red;
}
Enter fullscreen mode Exit fullscreen mode

ViewEncapsulation.ShadowDom

With the ShadowDom mode, styles from main HTML do not propagate to the component. Styles defined in this component's @Component decorator are scoped to this component only.

Let's then uncomment our encapsulation: ViewEncapsulation.ShadowDom in the servers.component.ts file.

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

@Component({
  selector: "app-servers",
  template: `
    <h3 class="title">App Servers Component</h3>
    <app-server></app-server>
  `,
  styleUrls: ["./servers.component.css"],
   //encapsulation ShadowDom
  encapsulation: ViewEncapsulation.ShadowDom
})
export class ServersComponent {}
Enter fullscreen mode Exit fullscreen mode

Alt Text

Let's inspect again.

Alt Text

The Shadow DOM creates a ShadowRoot for Component's Host Element and encapsulate styles to the element, in this case our Servers Component.

In our case, since Servers Component is inside our Server Component, it also don't get affect by the global styles.


Sometimes codesandbox doesn't auto refresh our changes in the window, so please after save any change, refresh you browser.

. . . . . . . . . . . . . . . . . . . . .