Apply styles from parent
Asked Answered
H

4

12

Suppose I have a component with this template:

<div class="frame">
  <span class="user-defined-text">{{text}}</span>
</div>
<style>
  span { font-size: 3em; }
  .frame { ... }
</style>

How can I merge the styles applied to the component, e.g.

<custom-component [text]="'Some text'">
<style>custom-component { font-weight: bold; }</style>

so that the final output "Some text" is both bold and 3em sized?

Even better is there a way to get the computed styles for the host element, so that, for example, I could apply the background-color of the host to the border-color of some element in my template?

Henriettahenriette answered 29/1, 2016 at 5:47 Comment(3)
Don't you think its good to put stylesheet at global level so you can use styleUrl property. or you want to achieve it through this way only?Phia
The idea is that in different places, the component could be re-used with different styles. E.g. a button that is bold in some places, or larger text in some places. Angular2 seems to stop all styles at the component, so they don't propagate further.Henriettahenriette
A :children selector or similar that lets a component access it's children would be a pretty neat feature. It should also be possible with the emulated view encapsulation, but I am not sure they want to do something that differs to much from native shadow dom, since using native is the future goal.Welby
C
20
  • set encapsulation: ViewEncapsulation.None to allow styles from outside to be applied.
import {Component, ViewEncapsulation} from '@angular/core';

@Component({
  selector: 'custom-component',
  encapsulation: ViewEncapsulation.None
})
export class Custom {
  • use styleUrl to add a CSS file in combination with host selector
:host(.someClass) {
      background-color: blue;
}

<custom-component class="someClass"></custom-component>

to apply styles depending on the class added to the element.

Corbett answered 29/1, 2016 at 6:45 Comment(9)
Suppose I use the first strategy: I can avoid name collisions by using a prefix for the class names. However, unless I also disable encapsulation for the parent component, all its styles are still only scoped to its elements, and won't propagate further. (i.e., they all have the [ng...] qualifier when using emulated encapsulation)Henriettahenriette
Emulated and Native are for style encapsulation. You have to disable it everywhere to be able to apply global styles. I'd suggest the 2nd strategy anyway. This way you can have both - encapsulation and global styles. You can add several styleUrls to each component. Add a global everywhere and a local where appropriate. If you add the local first, you should be able to override local styles by global ones to customize the "default" style (haven't tried myself yet if this works, I'd consider it a bug if it doesn't).Phyliciaphylis
For the second strategy, wouldn't the child component need to know all possible parents in order to customise specific instances?Henriettahenriette
Not sure what you mean. The direct parent should add a class to the component (where <custom-component> is added to its template. <custom-component> then applies the style with matching .someClass. :host {} means "self" and :host(.someClass) means "self with class someClass"Phyliciaphylis
I mean if I want custom-component to have color: red, then the parent would need to apply something like class="color-red", and the child would need :host(.color-red) span { color: red; }. Which means I need to know all such possible classes... or am I missing something?Henriettahenriette
Thats correct. I don't understand how this is related to "need to know all possible parents". I wouldn't use class="color-red". It should be more like class="warning" and then the style would look like :host(.warning) {color: red; background-color: yellow; border: 3px solid red; }.Phyliciaphylis
I haven't tried this myself but from what I have seen, for the global styles using the element name instead of :host should work as well, but it needs added to styleUrls of the elements where you want to apply the styles nonetheless.Phyliciaphylis
Suppose I have a graph component that I want others to be able to use in their application and customise the stroke and fill. I'd like to just inherit whatever stroke and fill is defined on the component to the svg path that is the graph. Using classes like warning or error won't help in that case.Henriettahenriette
I see. I haven't tried if explicitly setting style properties to inherit works in this case. Otherwise just using encapsulation: None would be the best option and add the styles to the nearest parent that doesn't have encapsulation Emulated or Native.Phyliciaphylis
E
18

I know this is old, but I feel this should be more visible. You could use the /deep/ selector to force a style down through the child component tree into all the child component views. The /deep/ selector works to any depth of nested components, and it applies both to the view children and the content children of the component.

I feel this is much cleaner and easier to implement.

parent.css

/deep/ .class {
    background-color: red;
}

https://angular.io/docs/ts/latest/guide/component-styles.html

Entomb answered 7/11, 2016 at 19:19 Comment(3)
doesn't get applied to directivesSoniasonic
/deep/ is being deprecated in polymer and Chrome (Probably soon on angular). And must be use only with emulated view encapsulation.Disconcerted
Prior to Angular 4.3, /deep/ or >>> was used instead of ::ng-deep. Both notations have been deprecated by browsers, so ::ng-deep is now the temporary workaround. alligator.io/angular/styles-between-components-angularImminent
B
0

Regarding CSS, components support shadow DOM. This means that their styles are isolated. The default mode is isolated. So you need to define CSS styles into the component (styles property).

You can also change the encapsulation mode to ViewEncapsulation.None. This way you're component will be able to see styles of the parent component:

@Component({
  selector: 'child',
  encapsulation: ViewEncapsulation.None,
  (...)
})
export class MyComponent {
  (...)
}

Hope it helps you, Thierry

Beehive answered 29/1, 2016 at 6:44 Comment(0)
R
0

Use :host pseudo-class selector to style the any <custom-component>.

We can't write css style to custom element, by using class.

Example

<custom-component class="custom-comp" [text]="'Some text'">

.custom-comp {
  font-weight: bold;
  color: green;
}

For this purpose, we can use :host selector to style the as given below

@Component({
  selector: 'custom-component',
  templateUrl: './custom-component.html',
  styleUrls: ['./custom-component.scss']
})

In custom-component.scss

:host {
  font-weight: bold;
  color: green;
}

You can read more about style the :host element on Angular4's Official docs

Rankin answered 1/9, 2017 at 10:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.