Reputation: 63
We have an in-house Angular component library (one project), each component has basic styling.
We use this library in our App (another project).
A component in the App contains a component from our library.
From the global styles.scss in the App, I can target the elements in the library component just fine.
If I move that global CSS into the App component CSS file, try what may, I cannot target any elements inside the library component.
app-component.html
<div class="outter">
<library-component specificityattr></library-component>
</div>
library-component.html
<div class="generic-styles">
<p class="hello">Hello</p>
</div>
app-component.scss
library-component[specificityattr] p.hello {
background: red;
}
styles.scss
library-component[specificityattr] p.hello {
background: green;
}
Without the selector in styles.scss, I expect the P tag to have a red background. Only when I put the same selector in styles.scss do I get a green background.
How is this failing?
What is the correct way to style a components sub-components?
Upvotes: 1
Views: 8548
Reputation: 1
check the css file that is produced at the end.
it looks like the first is physically before the second hence it's green
library-component[specificityattr] p.hello {
background: red;
}
library-component[specificityattr] p.hello {
background: green;
}
Upvotes: 0
Reputation: 8879
What you are experiencing is an effect of the default ViewEncapsulation
of components in Angular.
When you define a component such as below, the view encapsulation of the component will be the default value, which I've included inside a comment. This means that Angular won't create a so called 'shadow DOM' for your component, and all the styles will only be applied to your component.
Encapsulated component
@Component({
selector: 'my-component',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
//encapsulation: ViewEncapsulation.Emulated
})
If you instead want to apply the styles not only to your component, you can specify a specific ViewEncapsulation
in your component declaration. Using ViewEncapsulation.None
will move the styles to the DOM head, and it will still not create a shadow DOM.
Without encapsulation
@Component({
selector: 'my-component',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
encapsulation: ViewEncapsulation.None
})
Have a look at this StackBlitz example
It's important to keep in mind that ViewEncapsulation.None
will "leak" your styles to other components, which in turn will make it harder to style your application unless you know exactly where your styles are defined.
Upvotes: 1