Angular 7: Advanced Components
Throughout this book, we’ve learned how to use Angular’s built-in directives and how to create components of our own. In this chapter we’ll take a deep dive into advanced features we can use to make components.
In this chapter we’ll learn the following concepts:
- Styling components (with encapsulation)
- Modifying host DOM elements
- Modifying templates with content projection
- Accessing neighbor directives
- Using lifecycle hooks
- Detecting changes
How to Use This Chapter
This chapter gives a tour of advanced Angular APIs. It’s assumed the reader is familiar with the basics of creating components, using built-in directives, and organizing component files.
As this is an intermediate/advanced level chapter, it’s assumed the reader is able to fill in some of the basics (such as importing dependencies).
This chapter comes with runnable code, found in the advanced-components
folder. If at any time you feel you’re lacking context, checkout the example code for this chapter.
To run the demos in this chapter, change into the project folder and run:
npm install
npm start
Then open your browser to http://localhost:4200
Styling
Angular provides a mechanism for specifying component-specific styles. CSS stands for cascading style sheet, but sometimes we don’t want the cascade. Instead we want to provide styles for a component that won’t leak out into the rest of our page.
Angular provides two attributes that allow us to define CSS classes for our component.
To define the style for our component, we use the View attribute styles
to define in-line styles, or styleUrls
, to use external CSS files. We can also declare those attributes directly on the Component
decorator.
Let’s write a component that uses inline styles:
import { Component } from '@angular/core';
@Component({
selector: 'app-inline-style',
styles: [`
.highlight {
border: 2px solid red;
background-color: yellow;
text-align: center;
margin-bottom: 20px;
}
`],
template: `
<h4 class="ui horizontal divider header">
Inline style example
</h4>
<div class="highlight">
This uses component <code>styles</code>
property
</div>
`
})
export class InlineStyleComponent {
}
In this example we defined the styles we want to use by declaring the .highlight
class as an item on the array on the styles
parameter.
Further on in the template we reference that class on the div using <div class="highlight">
.
And the result is exactly what we expect - a div with a red border and yellow background:

Another way to declare CSS classes is to use the styleUrls
property. This allows us to declare our CSS in an external file and just reference them from the component.
Let’s write another component that uses this, but first let’s create a file called external.css
with the following class:
.highlight {
border: 2px dotted red;
text-align: center;
margin-bottom: 20px;
}
Then we can write the code that references it:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-external-style',
styleUrls: ['./external-style.component.css'],
template: `
<h4 class="ui horizontal divider header">
External style example
</h4>
<div class="highlight">
This uses component <code>styleUrls</code>
property
</div>
`
})
export class ExternalStyleComponent {
}
And when we load the page, we see our div with a dotted border:

View (Style) Encapsulation
One interesting thing about this example is that both components define a class called highlight
with different properties, but the attributes of one didn’t leak into the other.
This happens because Angular styles are encapsulated by the component context by default. If we inspect the page and expand the <head>
, we’ll notice that Angular injected a <style>
tag with our style:

You’ll also notice that the CSS class has been scoped with _ngcontent-hve-2
:
.highlight[\_ngcontent-hve-2] {
border: 2px solid red;
background-color: yellow;
text-align: center;
margin-bottom: 20px;
}
And if we check how our <div>
is rendered, you’ll find that _ng-content-hve-2
was added:

The same thing happens for our external style:

and:

Angular allows us to change this behavior, by using the encapsulation
property.
This property can have the following values, defined by the ViewEncapsulation
enum:
- Emulated - this is the default option and it will encapsulate the styles using the technique we just explained above
- Native - with this option, Angular will use the Shadow DOM (more on this below)
- None - with this option set, Angular won’t encapsulate the styles at all, allowing them to leak to other elements on the page
Shadow DOM Encapsulation
You might be wondering: what is the point of using the Shadow DOM? By using the Shadow DOM the component uses a unique DOM tree that is hidden from the other elements on the page. This allows styles defined within that element to be invisible to the rest of the page.
Let’s create another component that uses the Native encapsulation (Shadow DOM) to understand how this works:
```javascript)
import {
Component,
ViewEncapsulation
} from ‘@angular/core’;
@Component({
selector: 'app-native-encapsulation',
styles: [`
.highlight {
text-align: center;
border: 2px solid black;
border-radius: 3px;
margin-botton: 20px;
}`],
template: `
<h4 class="ui horizontal divider header">
Native encapsulation example
</h4>
<div class="highlight">
This component uses <code>ViewEncapsulation.Native</code>
</div>
`,
encapsulation: ViewEncapsulation.Native
})
export class NativeEncapsulationComponent {
} ```
In this case, if we inspect the source code, we’ll see:

Everything inside the #shadow-root
element has been encapsulated and isolated from the rest of the page.
No Encapsulation
Finally, if we create a component that specifies ViewEncapsulation.None
, no style encapsulation will be added:
import {
Component,
ViewEncapsulation
} from '@angular/core';
@Component({
selector: 'app-no-encapsulation',
styles: [`
.highlight {
border: 2px dashed red;
text-align: center;
margin-bottom: 20px;
}
`],
template: `
<h4 class="ui horizontal divider header">
No encapsulation example
</h4>
<div class="highlight">
This component uses <code>ViewEncapsulation.None</code>
</div>
`,
encapsulation: ViewEncapsulation.None
})
export class NoEncapsulationComponent {
}
This page is a preview of ng-book 2.
Get the rest of this chapter plus hundreds of pages Angular 7 instruction, 5 sample projects, a screencast, and more.
Ready to master Angular 7?
- What if you could master the entire framework – with solid foundations – in less time without beating your head against a wall? Imagine how quickly you could work if you knew the best practices and the best tools?
- Stop wasting your time searching and have everything you need to be productive in one, well-organized place, with complete examples to get your project up without needing to resort to endless hours of research.
- You will learn what you need to know to work professionally with ng-book: The Complete Book on Angular 7 or get your money back.
Download the First Chapter (for free)