I'm asking this question for an Angular application but I believe this relates to CSS in general.
I have an Angular component with a number of child components, and each has the standard view encapsulation. As an example, I want to change the line-height
of all p
tags within the parent component, including children components, to a different value.
Something like the following works for this (SCSS):
:host {
::ng-deep {
p {
line-height: 2em;
}
}
}
However, I don't want to change this style to effect a certain child component, let's call it foobar
. So I hoped something like the following would work:
:host {
::ng-deep {
:not(foobar) {
p {
line-height: 2em;
}
}
}
}
I understand this doesn't work because the p
element can be descendants of other elements and so the rule is still applied.
I also know I can do the following:
:host {
::ng-deep {
p:not(foobar p) {
line-height: 2em;
}
}
}
However, if I want to override a number of elements/classes etc. then this becomes rather unmanageable.
So question is; is there a good/modern way to do this using SCSS or more modern selectors? Anything on the Angular side that can help (aside from turning off viewEncapsulation)?
I resolved this by using a SCSS mixin:
@mixin not-foobar {
&:not(foobar #{nth(nth(&, 1), length(nth(&, 1)))}) {
@content;
}
}
with example usage:
:host {
::ng-deep {
p {
@include not-foobar {
line-height: 2em;
}
}
}
}
The mixin basically creates the p:not(foobar p) {
selector but means I only need to include the mixin where it's needed, rather than using the selector and possibly setting it incorrectly.
The #{nth(nth(&, 1), length(nth(&, 1)))})
part of the mixin basically selects the immediate parent. Using just &
set the whole parent which led to unwanted side effects in my case.