Simon
Simon

Reputation: 2116

SASS child selector not finding its target

OK so I have the following HTML (via angular 6)

<mat-tab-group class="mat-tab-group is-third-party">
<mat-tab-header class="mat-tab-header">

I then have the following SASS that I am trying to get working

 mat-tab-group {
      background-color: yellow;
      height: 100%;
      display: inherit; 

      &.is-third-party {
           background-color: blue;

           mat-tab-header {
                display: none !important;
           }
      }

Everything work as far as down to isThirdParty (I get my blue background which I've added to see what the heck is going on)

I've tried all sorts of combinations to get mat-tab-header to be hit but its not having it. I've tried . for the class name, the child selector > and whatever I do I don't get the mat-tab-header being hit and hence hidden.

I've only dabbled in SASS, can somebody see what I am doing wrong please? UPDATE: See my image below, bit more bloat in the html but you can see the HTML looks ok for this SASS?

enter image description here

Upvotes: 3

Views: 1777

Answers (2)

frido
frido

Reputation: 14129

Your styles don't apply to the Angular Material components nested in your Angular component because of Angular's style scoping feature. By default component styles are not inherited by any components nested within your component's template.

You have the following options to define styles that apply to other components nested within a component (like your Angular Material components):

  • Add the styles to your global styles.scss file
  • Keep the styles in your component and turn off view encapsulation for this component.
  • Keep the styles in your component and use a deprecated shadow-piercing descendant combinator to force styles to apply to all the child elements. (see original answer below)

Disabling View Encapsulation

Disable view encapsulation on your components that use Angular Material components.

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

ViewEncapsulation.None means that Angular does no view encapsulation. Angular adds the CSS to the global styles. The scoping rules, isolations, and protections discussed earlier don't apply. This is essentially the same as pasting the component's styles into the HTML. Angular Docs

If you turn off view encapsulation make sure to target only the html element you realy want, because the styles defined for this component now apply to your whole Angular app (not just the one component). (e.g. add a custom class or id to your element)

I've found that when disabling view encapsulation you might also have to use !important in your CSS to overwrite existing Angular Material styles, while it wasn't always needed with ::ng-deep.


Using ::ng-deep

Put ::ng-deep in front of your your parent selector.

Note that ::ng-deep is currently deprecated.

::ng-deep mat-tab-group {
  background-color: yellow;
  height: 100%;
  display: inherit; 

  &.is-third-party {
       background-color: blue;

       mat-tab-header {
            display: none !important;
       }
  }
}

Upvotes: 5

Roberto LL
Roberto LL

Reputation: 112

In your sass you have

mat-tab-group {
  background-color: yellow;
  height: 100%;
  display: inherit; 

  &.is-third-party {
       background-color: blue;

       mat-tab-header {
            display: none !important;
       }
  }

it should be (notice the "." before the mat-tab-group)

.mat-tab-group {
  background-color: yellow;
  height: 100%;
  display: inherit; 

  &.is-third-party {
       background-color: blue;

       mat-tab-header {
            display: none !important;
       }
  }

Upvotes: 0

Related Questions