Unable to add style to projected content in Angular 4

Viewed 6956

I have created a modal component that projects 3 sections: header, body and footer.

modal.component.html

<div>
    <ng-content select="section[modal-header]"></ng-content>
    <ng-content select="section[modal-body]"></ng-content>
    <ng-content select="section[modal-footer]"></ng-content>
</div>

Thus, usage:

<modal-component>
    <section modal-header>Header</section>
    <section modal-body>Body</section>
    <section modal-footer>Footer</section>
</modal-component>

I want to style the header. Thus:

modal.component.scss

:host([modal-header]) { font-weight: bold; }

This doesn't work. Am I missing anything?

3 Answers

Quoting from the official Angular documentation

The shadow-piercing descendant combinator is deprecated and support is being removed from major browsers and tools. As such we plan to drop support in Angular (for all 3 of /deep/, >>> and ::ng-deep).

The other alternative could be to use the @Component decorators encapsulation property in a combination with adding a class to the host using @HostBinding

  1. Set child component's encapsulation: ViewEncapsulation.None. This will make sure that there is no style encapsulation and the styles are valid globally.
  2. To encapsulate the styles, add a custon CSS class to the host of the child component as

    @HostBinding('class.custContainerClass') containerClass: boolean = true;
    
  3. Write your styles in the child component as

    .custContainerClass .projectedElement { }
    

Demo at: https://stackblitz.com/edit/angular-add-styles-to-projected-content

I think you should add css in component where your are using modal-component

like if you are using modal-component in app.component.html then you should write css in app.component.scss without host and ng deep

[modal-header] {
  font-weight: bold;
}

actually it has 2 reasons, 1 because there might be change that you are using modal-component in two different component and want different css for sections.

and second is that you should write css where actual content is.

and if you still want to write css code in your modal-component then you should create parent container to hold that content like:

<div class="header">
  <ng-content select="section[modal-header]"></ng-content>
</div>
<ng-content select="section[modal-body]"></ng-content>
<ng-content select="section[modal-footer]"></ng-content>

and in your modal.component.scss file

.header {
  font-weight: bold
 }

because ng-content is replaced with new template so you need parent container.

Related