Let's take for an example the scenario where the ComponentParent
contains ComponentChild
. For this example we are discussing different encapsulation scenarios for the ComponentParent
.
import { ViewEncapsulation } from '@angular/core';
@Component({
selector: 'component-child',
// templateUrl: './child.component.html',
template: '<h1>Hello, child</h1>',
// styleUrls: ['./child.component.scss'],
style: '/* ... */'
})
export class ComponentParent {
// ...
}
@Component({
selector: 'component-parent',
template: '<h1>Hello, parent</h1><component-child/>',
style: 'h1{background-color:yellow}',
encapsulation: ViewEncapsulation.Emulated // this is the default encapsulation for the angular component
})
export class ComponentParent {
// ...
}
ViewEncapsulation has 1 obsoleted value:
and 3 valid values:
None
This is the transparent mode and something the most similar to the scenario where angular is not involved at all.
Both ComponentParent
and ComponentChild
will have H1 tag with yellow background.
ShadowDom
This mode creates a native shadow DOM root around the component (in our case: ComponentParent
) content. This will protect any (CSS/SASS) style we declare inside the component to leak OUTSIDE the component. However, it will apply to child components like ComponentChild
.
Both ComponentParent
and ComponentChild
will have H1 tag with yellow background (similar to the None
mode), but any H1 tag outside the ComponentParent
will NOT be affected.
Emulated
In short, this applies the styles declared in the ComponentParent
ONLY and ONLY to the ComponentParent
content, but EXCLUDING the child components like ComponentChild
. In other words, only on "pure" HTML elements, but not angular web (component) elements.
Only ComponentParent
will have H1 tag with yellow background.
Additional explanation on Emulation mechanism
The Emulated
mode is usually transparent to us, as we prefer to put our global styles (affecting both ComponentParent
and ComponentChild
) which WILL penetrate both None
and Emulated
components and their children components and HTML elements.
However imagine the ComponentChild
is a 3rd party component and you want to style it. You will NOT be able to do that with the Emulated
mode applied on the ComponentParent
component. This is due to the Emulated
implementation:
EACH HTML element inside the ComponentParent
component will be decorated with the component-name attribute (without value), for example:
_nghost-c3
: for the component container
_ngcontent-c3
: for the component's content
In parallel EACH (S)CSS selector in our component ComponentParent
will be "encapsulated" (conditioned) with the same component-name attribute
.H1[_ngcontent-c3] {
background-color:yellow;
}
Overall, this means, that only elements of the ComponentParent
will be affected, and our aim to decorate H1 of the 3rd party component will fail, as it doesn't have the (same, if any) component-name attribute (_ngcontent-c3
)
Solutions for the 3rd party components:
- Use the
ShadowDom
if available
- Disable encapsulation, use
None
- put styles in global (S)CSS
- simulate emulation for inner 3rd party components by decorating their elements with the component-name attribute