How to style child components from parent component's CSS file?

I've got a parent component:

<parent></parent>

And I want to populate this group with child components:

<parent>
  <child></child>
  <child></child>
  <child></child>
</parent>

Parent template:

<div class="parent">
  <!-- Children goes here -->
  <ng-content></ng-content>
</div>

Child template:

<div class="child">Test</div>

Since parent and child are two separate components, their styles are locked to their own scope.

In my parent component I tried doing:

.parent .child {
  // Styles for child
}

But the .child styles are not getting applied to the child components.

I tried using styleUrls to include the parent's stylesheet into child component to solve the scope issue:

// child.component.ts
styleUrls: [
  './parent.component.css',
  './child.component.css',
]

But that didn't help, also tried the other way by fetching the child stylesheet into parent but that didn't help either.

So how do you style child components that are included into a parent component?


Update - Newest Way

Don't do it, if you can avoid it. As Devon Sans points out in the comments: This feature will most likely be deprecated.

Last Update

From Angular 4.3.0 till even now (Angular 12.x), all piercing css combinators were deprecated. Angular team introduced a new combinator ::ng-deep as shown below,

DEMO : https://plnkr.co/edit/RBJIszu14o4svHLQt563?p=preview

styles: [
    `
     :host { color: red; }
     
     :host ::ng-deep parent {
       color:blue;
     }
     :host ::ng-deep child{
       color:orange;
     }
     :host ::ng-deep child.class1 {
       color:yellow;
     }
     :host ::ng-deep child.class2{
       color:pink;
     }
    `
],



template: `
      Angular2                                //red
      <parent>                                //blue
          <child></child>                     //orange
          <child class="class1"></child>      //yellow
          <child class="class2"></child>      //pink
      </parent>      
    `

Old way

You can use encapsulation mode and/or piercing CSS combinators >>>, /deep/ and ::shadow

working example : http://plnkr.co/edit/1RBDGQ?p=preview

styles: [
    `
     :host { color: red; }
     :host >>> parent {
       color:blue;
     }
     :host >>> child{
       color:orange;
     }
     :host >>> child.class1 {
       color:yellow;
     }
     :host >>> child.class2{
       color:pink;
     }
    `
    ],

template: `
  Angular2                                //red
  <parent>                                //blue
      <child></child>                     //orange
      <child class="class1"></child>      //yellow
      <child class="class2"></child>      //pink
  </parent>      
`

You should NOT use ::ng-deep, it is deprecated. In Angular, the proper way to change the style of children's component from the parent is to use encapsulation (read the warning below to understand the implications):

import { ViewEncapsulation } from '@angular/core';

@Component({
    ....
    encapsulation: ViewEncapsulation.None
})

And then, you will be able to modify the css form your component without a need from ::ng-deep

.mat-sort-header-container {
  display: flex;
  justify-content: center;
}

WARNING: Doing this will make all css rules you write for this component to be global.

In order to limit the scope of your css to this component and his child only, add a css class to the top tag of your component and put your css "inside" this tag:

template:

<div class='my-component'>
  <child-component class="first">First</child>
</div>,

Scss file:

.my-component {
  // All your css goes in there in order not to be global
}

UPDATE 3:

::ng-deep is also deprecated which means you should not do this at all anymore. It is unclear how this affects things where you need to override styles in child components from a parent component. To me it seems odd if this gets removed completely because how would this affect things as libraries where you need to override styles in a library component?

Comment if you have any insight in this.

UPDATE 2:

Since /deep/ and all other shadow piercing selectors are now deprecated. Angular dropped ::ng-deep which should be used instead for a broader compatibility.

UPDATE:

If using Angular-CLI you need to use /deep/ instead of >>> or else it will not work.

ORIGINAL:

After going to Angular2's Github page and doing a random search for "style" I found this question: Angular 2 - innerHTML styling

Which said to use something that was added in 2.0.0-beta.10, the >>> and ::shadow selectors.

(>>>) (and the equivalent/deep/) and ::shadow were added in 2.0.0-beta.10. They are similar to the shadow DOM CSS combinators (which are deprecated) and only work with encapsulation: ViewEncapsulation.Emulated which is the default in Angular2. They probably also work with ViewEncapsulation.None but are then only ignored because they are not necessary. These combinators are only an intermediate solution until more advanced features for cross-component styling is supported.

So simply doing:

:host >>> .child {}

In parent's stylesheet file solved the issue. Please note, as stated in the quote above, this solution is only intermediate until more advanced cross-component styling is supported.


Sadly it appears that the /deep/ selector is deprecated (at least in Chrome) https://www.chromestatus.com/features/6750456638341120

In short it appears there is (currently) no long term solution other than to somehow get your child component to style things dynamically.

You could pass a style object to your child and have it applied via:
<div [attr.style]="styleobject">

Or if you have a specific style you can use something like:
<div [style.background-color]="colorvar">

More discussion related to this: https://github.com/angular/angular/issues/6511


Had same issue, so if you're using angular2-cli with scss/sass use '/deep/' instead of '>>>', last selector isn't supported yet (but works great with css).