What is ViewEncapsulation in Angular?
Tags: angular
Published: 2020-03-07 14:43:22

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

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

<p>At a component level, there are some cool features that we can use.</p>

<p>Check the <a href="https://codesandbox.io/s/viewencapsulation-in-angular-uh1fs">sandbox</a> that I already created and feel free to change or fork it for yourself.</p>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/f6lm4ghbqbyvg5y8zmo3.PNG)

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

<h4><i>styles.css</i></h4>


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

.title {
  border: 2px solid orange;
  padding: 10px;
  background-color: #ede8e8;
  color: black;
}
```

<p>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.</p>

<p>Why is that?</p>

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

<hr>

<h2>ViewEncapsulation.Emulated</h2>

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

<p>Let´s see our components style.</p>

<h4><i>app.component.css</i></h4>

```css
div {
  text-align: center;
}

.title {
  border-color: cyan;
}
```

<h4><i>servers.component.css</i></h4>

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

h3 {
  font-size: 50px;
}
```

<h4><i>server.component.css</i></h4>

```css
.title {
  border: 5px solid red;
}
```

<hr>

<h2>ViewEncapsulation.None</h2>

<p>In the <b>None</b> 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.</p>

<p>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:</p>

<h4><i>servers.component.ts</i></h4>

```javascript
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 {}
```

<p>Notice that <b>ViewEncapsulation</b> was added in the import in order to be used as <b> encapsulation: ViewEncapsulation.None</b></p>
<p>Try to comment out the previous mode and uncomment this line in the servers.component.ts and see what happen.</p>

<p>The result will be like the image bellow.</p>
<p>Now, all the components have the same border radius, border width and font-size as the Servers Component.</p>

![Angular Encapsulation Mode None](https://dev-to-uploads.s3.amazonaws.com/i/8vdrcyazlklr3w5fvqvq.PNG)

<p>Let's inspect our <b>Server Component</b> (not Servers) to see what happened.</p>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/i9pc4k22ciwm9ekcue2d.PNG)

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

<p>Remember that we defined these styles before.</p>

<h4><i>servers.component.css</i></h4>

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

h3 {
  font-size: 50px;
}
```

<h4><i>server.component.css</i></h4>

```css
.title {
  border: 5px solid red;
}
```
<hr>

<h2>ViewEncapsulation.ShadowDom</h2>

<p>With the <b>ShadowDom</b> 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.</p>

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

```javascript
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 {}
```

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/bp1lmlj0trp0mnjsg1xm.PNG)

<p>Let's inspect again.</p>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/hn54vd4pkx53d05h1yg6.PNG)

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

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

<hr>

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