8

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?

Karma
  • 2,196
  • 1
  • 22
  • 30

3 Answers3

10

Component styles normally apply only to the HTML in the component's own template.

Use the /deep/ shadow-piercing descendant combinator to force a style down through the child component tree into all the child component views. The /deep/ combinator works to any depth of nested components, and it applies to both the view children and content children of the component.

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

In angular documentation they mention that /deep/ is deprecated so you can use ::ng-deep

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

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). Until then ::ng-deep should be preferred for a broader compatibility with the tools.

Component Styles

stackblitz demo

Muhammed Albarmavi
  • 23,240
  • 8
  • 66
  • 91
7

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

Saksham
  • 9,037
  • 7
  • 45
  • 73
-1

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.

Ravi Sevta
  • 2,817
  • 21
  • 37