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.
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;
}
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;
}
servers.component.css
.title {
border: 3px solid green;
border-radius: 5px;
border-width: 7px;
}
h3 {
font-size: 50px;
}
server.component.css
.title {
border: 5px solid red;
}
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 {}
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.
Let's inspect our Server Component (not Servers) to see what happened.
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;
}
server.component.css
.title {
border: 5px solid red;
}
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 {}
Let's inspect again.
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.
Top comments (1)
I found out about ViewEncapsulation the hard way after I struggled with styling
<mat-form-field>
for an hour and was beginning to question my sanity.