Using Angular 5, angular-cli with scss.
I'm creating angular component that uses 3rd party component (angular-tree-component). I need to import styles for the tree. Because of styles isolation in angular (using the default emulated view encapsulation) the only way how to achieve it is using ::ng-deep
, like this:
:host ::ng-deep {
@import '~angular-tree-component/dist/angular-tree-component.css';
}
But this does not work - it looks like the @import
is ignored inside the :host ::ng-deep
. I workarounded it by copying the content of the css file directly within the brackets but its suboptimal as if the referenced package was upgraded then I would have to manually replace the content with the new styles.
Only other workaround I can think of is changing the view encapsulation to None
but it seems even worse as it makes the styles global.
Is there any better option?
The ::ng-deep pseudo-class selector So this style will be applied to all h2 elements inside app-root , but not outside of it as expected. This combination of selectors is useful for example for applying styles to elements that were passed to the template using ng-content , have a look at this post for more details.
::ng-deep is quite powerful and has the capacity to render the styles defined under it as global. Its important to note here that ::ng-deep must be used after the :host selector to ensure that the styles defined will be scoped only to the <app-child-a> component and its descendant component <app-child-b> only.
Style encapsulation is one of many great Angular features. Style encapsulation ensures that component styles don't leak out and affect the rest of the page. Thx to style encapsulation; we can safely target a div without affecting other divs on the page.
For me, in an Angular CLI 6 project, all works fine when not including the file's suffix. Like if the actual file is simplemde.min.css
:
:host ::ng-deep {
// For proper scoping, do not include the .css file suffix here
@import '~simplemde/dist/simplemde.min';
}
So, the above works without the need for encapsulation: ViewEncapsulation.None
. And it also makes non-scoped content (typically HTML that is created at runtime outside of Angular, like in my case the HTML generated for the SimpleMDE Markdown editor) be styled as expected.
Some background:
With the suffix, the @import
is actually processed as well; whenever my component was instantiated a scoped <style>
element was added to <head>
:
Note that this yields scoping for _ngcontent
, and this does not work well for ::ng-deep
, leaving dynamic child content unstyled.
However, without the suffix, one gets:
Above, the scoping is using _nghost
.
I wonder if this is a bug, or documented behaviour. (And maybe things are even different for Sass files? Using @import
for CSS is non-standard behaviour which will be removed in future versions of LibSass...)
Note that :host
is needed. With just ::ng-deep
the result with the file suffix is the same. But without the file suffix the styles are not scoped at all when not using :host
:
Looking at the rendered web pages I have very much been fooled into thinking this worked too (and one's own styles are still nicely scoped, so this is a partial success). But the third party CSS is effectively imported without any scoping when not using :host
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With