9

What is the right way to override child component style from host component. I tried using encapsulation: ViewEncapsulation.None but i need to write the override stuff in style.sass file rather than host component. What should be the stackblitz

Hacker
  • 7,798
  • 19
  • 84
  • 154
  • 1
    Some good info on that here: https://stackoverflow.com/questions/36527605/how-to-style-child-components-from-parent-components-css-file – night_owl Jan 23 '19 at 14:06

2 Answers2

19

If you have control on the child component code, you can define a customStyle input property:

@Input() customStyle: {};
<div class="child-div" [ngStyle]="customStyle">I am the child</div>

and pass it from the parent component:

<app-child [customStyle]="style1"></app-child>
style1 = {
  backgroundColor: "red",
  height: "150px"
}

See this stackblitz for a demo.


A similar technique can allow to pass a specific style attribute to the child component:

@Input() backgroundColor: string;
<div class="child-div" [style.background-color]="backgroundColor">I am the child</div>

from the parent component:

<app-child backgroundColor="red"></app-child>

See this stackblitz for a demo.


Otherwise, until an alternative method is proposed by Angular, you can use the ::ng-deep shadow-piercing descendant combinator to modify the child component styling from the parent CSS:

:host ::ng-deep .parent .child-div {
  background-color: lime;
  height: 200px;
}

See this stackblitz for a demo.

ConnorsFan
  • 70,558
  • 13
  • 122
  • 146
  • 2
    But we are not supposed to use ::ng-deep right as it will be deprecated. – Hacker Jan 23 '19 at 14:29
  • 4
    You can see [this question](https://stackoverflow.com/q/47024236/1009922) about the deprecation of `::ng-deep`. I agree with the accepted answer: use it until Angular suggests an alternative technique. – ConnorsFan Jan 23 '19 at 14:33
  • To my knowledge, you can do it with `::ng-deep` or `ViewEncapsulation.None` (at the present time). – ConnorsFan Jan 23 '19 at 14:39
  • Can you show me right way to do it with viewEncapsulation.None. Is its case need to write override styles in styles.scss right? – Hacker Jan 23 '19 at 14:42
  • If you turn off the view encapsulation in both components, you can alter the child component styling from the parent CSS (or from `styles.css`). See [this stackblitz](https://stackblitz.com/edit/viewencapsulation-turned-off-zbk3ah). – ConnorsFan Jan 23 '19 at 14:47
  • Cool. ::ng-deep looks good for me when compared to encapsulation. As it keeps intact the encapsulations of the respective component and when required only will be updated from parent. – Hacker Jan 23 '19 at 14:52
  • I agree. We will see what Angular suggests when `:ng-deep` is officially removed. – ConnorsFan Jan 23 '19 at 14:54
  • 1
    You can use encapsulation:ViewEncapsulation.None in "parent" and add !important to the .css, e.g. background-color: lime!important – Eliseo Jan 23 '19 at 15:28
  • `::ng-deep` is deprecated but unfortunately the only option I know, you can check this discussion for more information about it: https://stackoverflow.com/a/49308475/9325419 – jo_va Jan 23 '19 at 15:39
2

My "way" is using viewEncapsulation.None, important and add class to the child. the forked stackblitz's Connors

//The parent
.child1 .child-div {
  background-color: lime!important;
  height: 200px!important;
}

<div style="text-align: center;" class='parent'>Hi I am the app-root and I contain child-comp!
<app-child class="child1"></app-child>
<app-child ></app-child>
</div>
Eliseo
  • 50,109
  • 4
  • 29
  • 67