The element is generated with one attribute and its CSS with another attribute

1

I created the toolbar component with the following decorator:

@Component({
    selector: 'app-toolbar',
    templateUrl: './toolbar.component.html',
    styleUrls: ['./toolbar.component.scss']
})

Notice that the component is using the app-toolbar selector.

I added the following CSS in the file toolbar.component.scss :

app-toolbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 2;
}

But the element did not get fixed at the top. When I inspected the element in the browser, I noticed that it has received the following attributes:

<app-toolbar _ngcontent-c0 _nghost-c1>
    //...
</app-toolbar>

When checking the generated CSS, it is being applied to the element app-toolbar but with a different attribute:

app-toolbar[_ngcontent-c1] {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 2; 
}

That is, the element is rendered with the _ngcontent-c0 attribute and the CSS with the _ngcontent-c1 attribute.

What's wrong? Why is the context of the element different from the CSS context?

    
asked by anonymous 25.01.2018 / 20:47

1 answer

1

The behavior you're witnessing is due to the fact that the framework Angular uses Shadow DOM . Briefly, Shadow DOM is part of the Web Components pattern and enables the encapsulation of the DOM tree and DOM style. This means that the DOM Shadow allows you to hide the DOM logic behind other elements. In addition, it allows you to apply styles that are scoped only to the element itself without such styles "leaking" out of that element.

Angular makes use of views encapsulation. This concept is very important because it makes it possible to create components that expose a single custom element with a DOM logic hidden beneath the cloths, and styles that are applied only to that element.

For you to solve your problem, you need to use the :host pseudo-class. From the documentation:

  

Use the :host pseudo-class selector to target styles in the element that hosts the component.

     

The% selector is the only way to target the host element. You can not reach the host element from inside the component with other selectors because it is not part of the component's own template. The host element is in a parent component's template.

Translating:

  

Use the pseudo-class :host to define styles in the element that hosts the component.

     

The : host selector is the only way to focus on the host element. You can not reach the host element inside the component with other selectors because it is not part of the component model itself. The host element is in the parent component model.

In this way, using your code as an example, given the

@Component({
    selector: 'app-toolbar',
    templateUrl: './toolbar.component.html',
    styleUrls: ['./toolbar.component.scss']
})

The toolbar.component.scss file would have the following code for the component element to be properly stylized.

:host {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 2;
}
    
25.01.2018 / 23:30