The element is generated with an attribute and the respective CSS with another attribute

Asked

Viewed 392 times

1

I created the component toolbar with the following developer:

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

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

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

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

But the element nay was fixed at the top. When inspecting the element in the browser, I checked that it 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 attribute _ngcontent-c0 and the CSS with the attribute _ngcontent-c1.

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

1 answer

1


The behavior you are witnessing is due to the fact that framework Angular use Shadow DOM. In short, Shadow DOM is part of the standard Web Components and enables the encapsulation of the DOM tree and the DOM style. This means that the Shadow DOM allows you to hide the DOM logic behind other elements. In addition, it allows applying styles that have as a scope only the element itself without such styles "leaking" out of such an element.

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

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

Use the :host pseudo-class selector to target Styles in the element that hosts the Component.

The :host selector is the only way to target the host element. You can’t Reach the host element from Inside the Component with other selectors because it’s 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 hosting the component.

The selector : host is the only way to focus on the host element. You cannot 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 model of a parent component.

Thus, using its code as an example, given the component

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

The archive Toolbar.component.scss would have the following code so that the component element is properly stylized.

:host {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 2;
}
  • Thank you very much. I could complete your reply with an example using the :host and so would be more complete. I know enough in my scss declare the pseudo-class and within it the classes of the child elements, but for some this may not be very clear, the example would help.

  • @Filipemoraes following your suggestion I complemented my reply.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.