• notice
  • Congratulations on the launch of the Sought Tech site

How Angular does view wrapping

This article mainly explains "how to encapsulate views in Angular". Interested friends may wish to take a look. The method introduced in this paper is simple, fast, and practical. Let the editor take you to learn "how to encapsulate views in Angular"!

How does Angular perform view encapsulation

In daily work, when we define a Component , we must consider its encapsulation encapsulation, that is, whether you expect the styles defined in this component to only apply to this component, or to apply to the whole world. In Angular, a component's styles can be encapsulated in the component's host element so that they don't affect the rest of the application. Component's decorator provides an encapsulation option that can be used to control how view encapsulation is applied on a per-component basis. ViewEncapsulation

There are three encapsulation modes in Angular, namely ViewEncapsulation.ShadowDom, ViewEncapsulation.Emulated, ViewEncapsulation.None.

export enum ViewEncapsulation {
     /**
      * Emulates a native Shadow DOM encapsulation behavior by adding a specific attribute to the
      * component's host element and applying the same attribute to all the CSS selectors provided
      * via {@link Component#styles styles} or {@link Component#styleUrls styleUrls}.
      *
      * This is the default option.
      */
     Emulated = 0,
     /**
      * Doesn't provide any sort of CSS style encapsulation, meaning that all the styles provided
      * via {@link Component#styles styles} or {@link Component#styleUrls styleUrls} are applicable
      * to any HTML element of the application regardless of their host Component.
      */
     None = 2,
     /**
      * Uses the browser's native Shadow DOM API to encapsulate CSS styles, meaning that it creates
      * a ShadowRoot for the component's host element which is then used to encapsulate
      * all the Component's styling.
      */
     ShadowDom = 3
}
  • ViewEncapsulation.Emulated: Emulate native behavior with shimed CSS.

  • ViewEncapsulation.None : Use global CSS without any encapsulation.

  • ViewEncapsulation.ShadowDom: Use Shadow DOM v1 to encapsulate styles.

If not provided, the value will be taken from CompilerOptions. The default compiler option is ViewEncapsulation.Emulated.

If the policy is set to ViewEncapsulation.Emulated, and the component does not specify styles or styleUrls, it will automatically switch to ViewEncapsulation.None.

Have you found out why there is no 1 for the enumeration type ? More on this later.

ViewEncapsulation.ShadowDom

Aside from the encapsulation of ShadowDom in Angular, let's take a look at what ShadowDOM is.

Shadow DOM

Shadow DOM allows to attach a hidden DOM tree to a regular DOM tree - it starts with the shadow root node, and below this root node, can be any element, just like a normal DOM element.

How does Angular perform view encapsulation

Here, there are some Shadow DOM-specific terms we need to know:

  • Shadow host: A regular DOM node to which the Shadow DOM will be attached.

  • Shadow tree: The DOM tree inside the Shadow DOM.

  • Shadow boundary: Where the Shadow DOM ends, and where the regular DOM begins.

  • Shadow root: The root node of the Shadow tree.

You can manipulate the Shadow DOM in the same way as a regular DOM - such as adding child nodes, setting properties, and adding your own styles to nodes (eg via the element.style property), or adding styles to the entire Shadow DOM (eg adding styles inside elements). The difference is that elements inside Shadow DOM never affect elements outside it (except :focus-within ), which facilitates encapsulation.

Let's look at a simple example.

<!DOCTYPE html>
<html>
<head>
     <meta charset="UTF-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>Shadow DOM</title>
     <style>
         span{
             color: green;
         }
     </style>
</head>
<body>
     <span>I am Root</span>
     <div id="app"></div>
     <script>
         let app = document.querySelector('#app');
         let shadow1 = app.attachShadow({ mode: 'open'});
        
         let style1 = document.createElement('style');
         style1.appendChild(document.createTextNode("span{color: red;}"));
         shadow1.appendChild(style1);

         let span1 = document.createElement('span');
         span1.textContent = 'I am span.';
         shadow1.appendChild(span1);
     </script>
</body>
</html>

How does Angular perform view encapsulation

The above example defines the global span style and also defines the span style in shadowDOM. It can be seen that they are not affected by each other.

Encapsulation of ShadowDOM in Angular

After understanding what ShadowDOM is, let's take a look at the encapsulation of ShadowDOM in Angular.

Angular uses the browser's built-in Shadow DOM API to wrap the component's view in the ShadowRoot (which serves as the component's host element) and applies the provided styles in isolation. ViewEncapsulation.ShadowDom is only available in browsers with built-in support for shadow DOM. Not all browsers support it, which is why ViewEncapsulation.Emulated is the recommended and default mode.

For example, the following example uses ViewEncapsulation.ShadowDom .

@Component({
   selector: 'user-child',
   templateUrl: 'UserChild.component.html',
   styles: [`
   h4{
     color: red;
   }
   `],
   encapsulation: ViewEncapsulation.ShadowDom
})

export class UserChildComponent implements OnInit {
   ......
}

How does Angular perform view encapsulation

As you can see from the running page, the user-child component is encapsulated into a ShadowDOM, and the style is also encapsulated inside, which will not affect the external style.

ViewEncapsulation.Emulated

Angular modifies the component's CSS selectors so that they only apply to the component's view and do not affect other elements in the application (simulating Shadow DOM behavior).

When using mock view encapsulation, Angular preprocesses all component styles so that they apply only to the component's view. In the DOM of a running Angular application, the element containing the component that uses the mock view encapsulation mode has some additional attributes attached:

< hero-details  _nghost-pmm-5 >   < h4  _ngcontent-pmm-5 > Mister Fantastic </ h4 >   < hero-team  _ngcontent-pmm-5  _nghost-pmm-6 >     < h5  _ngcontent-pmm-6 > Team </ h5 >   </ hero-team > </ hero-details >

There are two such properties:

AttributesDetails
_nghostTo be added to the element wrapping the component's view , this will be the ShadowRoots in the native Shadow DOM wrapper. This is usually the case with the component's host element .
_ngcontentAdded to child elements in component views , these attributes are used to match elements to their respective mock ShadowRoots (host elements with matching _nghost attributes).

The exact values of these properties are Angular's private implementation details. They are automatically generated and you should not reference them in your application code.

They target the generated component styles, which are injected into the DOM section:

[_nghost-pmm-5]  {
   display : block;
   border :  1px  solid black;}h5 [_ngcontent-pmm-6]  {
   background-color : white;
   border :  1px  solid  #777 ;}

These styles are post-processed so that each CSS selector is augmented with the appropriate _nghost or _ngcontent attribute. These modified selectors ensure that styles are applied to the component's views in an isolated and targeted manner.

< p > child works! </ p >
p {
   color : green;}
@Component ({
   selector :  'app-child' ,
   templateUrl :  './child.component.html' ,
   styleUrls : [ './child.component.scss' ],
   encapsulation : ViewEncapsulation.Emulated})export class ChildComponent implements OnInit { ......}

How does Angular perform view encapsulation

The result of the ViewEncapsulation.Emulated setting is that there is no Shadow DOM, but the component is encapsulated through the style packaging mechanism provided by Angular, so that the style of the component is not affected by external influences. Although styles are still applied to the entire document, Angular creates a [_ngcontent-oow-c11] selector for p. As you can see, the styles we defined for the component are modified by Angular. In short, although it is also a global style, due to the automatic selector, it will not affect the styles of other components. If you manually add this attribute on other elements, the styles will also be applied to this element.

ViewEncapsulation.None

Angular does not apply any form of view encapsulation, which means that any styles specified for a component are actually applied globally and can affect any HTML elements present in the application. This pattern is essentially the same as including styles in the HTML itself.

parent:

< p  # caption > parent works!{{count}} </ p > < p  # caption > first: {{count}} </ p > < span  class = "red-font" > parent </ span > < app-child > </ app-child >

child:

< div  style = "border: 1px solid green;" >     < p > child works! </ p >     < span  class = "red-font" > Child </ span > </ div >
p {
   color : green;}.red-font  {
   color : red;}
@Component ({
   selector :  'app-child' ,
   templateUrl :  './child.component.html' ,
   styleUrls : [ './child.component.scss' ],
   encapsulation : ViewEncapsulation.None})export class ChildComponent implements OnInit {  ......}

How does Angular perform view encapsulation

Abandoned Native

Using ViewEncapsulation.Native in Angular2.

@Component({  ...,  encapsulation: ViewEncapsulation.Native})export  class  UserComponent  {

How does Angular perform view encapsulation

The result of the ViewEncapsulation.Native setting is to use the native Shadow DOM features. Angular will render the component in the form of Shadow DOM supported by the browser. In fact, this is the later ViewEncapsulation.ShadowDom.

At this point, I believe that everyone has a deeper understanding of "How Angular conducts view encapsulation", so let's do it in practice! 


Tags

Technical otaku

Sought technology together

Related Topic

0 Comments

Leave a Reply

+