SCSS modify parent selector - css

Is there a way to add a class to the first element of a nested selector with .scss?
Imagine the example below:
body p {
color: black;
}
body.other-mode p {
color: red;
}
Would it be possible to express it like this (or in a similar way, since this won't compile)
body p {
& {
color: black;
}
.other-mode& {
color: red;
}
}
I'm aware this can be written like this, but that's just a different way of "solving" an example of the issue.
body {
& p {
color: black;
}
&.other-mode p {
color: red;
}
}
I also tried using some scss selectors but they don't work quite as expected, in the case below the selectors ends up being body p body.other-mode p instead of body p
body p {
& {
color: black;
}
#{selector-replace(&, "body", "body.other-mode")} {
color: red;
}
}

To make your last solution work, you can use #at-root.
body p {
& {
color: black;
}
#at-root #{selector-replace(&, "body", "body.other-mode")} {
color: red;
}
}
compiles to
body p {
color: black;
}
body.other-mode p {
color: red;
}
But personally, I find your original solution the most readable.
body { &.other-mode p {color: red;} }
I find the split body and p more convenient in SCSS.

Related

How to add a "modified" class for an element in SCSS

Given this scss
.root {
color: red;
&-child {
color: blue;
small & {
font-size: 80%;
}
}
}
This is the CSS I get:
.root {
color: red;
}
.root-child {
color: blue;
}
small .root-child {
font-size: 80%;
}
I want to style .root-child on small differently so the rule I need is:
small.root-child {
font-size: 80%;
}
(Notice no whitespace after small)
How can I do that?
You need to use #at-root and that will remove the white space in your selector, as well as it will be a valid syntax so no issues while you try to compile.
.root {
color: red;
&-child {
color: blue;
#at-root small#{&} {
font-size: 80%;
}
}
}
You can use #at-root like this:
SCSS
.root {
color: red;
&-child {
color: blue;
#at-root {
small#{&} {
font-size: 80%;
}
}
}
}
Compiled:
.root {
color: red;
}
.root-child {
color: blue;
}
small.root-child {
font-size: 80%;
}

How to extend in scss from parent (in case of BEVM)

I try to understand BEVM+SCSS philosophy.
I don't know how to extend V from BE in this case.
What I want to achieve:
.block {
&__element {
background-color: black;
&--variation-a {
#extend &__element; //won't work
color: red;
}
&--variation-b {
#extend &__element; //won't work
color: green;
}
}
}
What I want to avoid:
.block {
&__element {
background-color: black;
&--variation-a {
#extend .block__element; //work but ugly
color: red;
}
&--variation-b {
#extend .block__element; //work but ugly
color: green;
}
}
}
The only way I've found it's to have a kind of %element { ... } aside and extends from it, but it's not exactly what I want.
You can use variables. $b to store block name and $e to store element name.
Sassmeister demo.
.block {
$b: &;
&__element {
$e: #{$b}__element;
background-color: black;
&--variation-a {
#extend #{$e};
color: red;
}
&--variation-b {
#extend #{$e};
color: green;
}
}
}
But it's bad practice to nest element styles by modifier. Modifier must only override styles.

Compass (SASS) rule with pseudo class

Is it possible to generate css rule for element for normal state and some other pseudo state like this:
.heading-link, .heading-link:hover {
color: red;
}
with
.heading-link {
color: $state-info-text;
&:hover {
color: $state-info-text;
}
}
I got
.heading-link {
color: #538DA7;
}
.heading-link:hover {
color: #538DA7;
}
What is not as expected, plus I have to write rule for color twice.
You can use the parent selector (&) by itself, in addition to other selectors inside nested blocks.
DEMO
$state-info-text: #538DA7;
.heading-link {
&, &:hover {
color: $state-info-text;
}
}
Compiles to
.heading-link, .heading-link:hover {
color: #538DA7;
}
Yes. You can use Sass's built in #extend function for this.
$state-info-text: red;
.heading-link {
color: $state-info-text;
&:hover {
#extend .heading-link;
}
}
Gives the output:
.heading-link, .heading-link:hover {
color: red;
}

LESS: Applying a ruleset only when selector is in another selector

Say I've got:
.apple {
color: red;
}
Now, let's say I've also got:
.big {
.apple {
font-size: 1.25em;
}
}
Is there a way I can put the .big selector inside the rule for .apple? In psuedocode, something like:
.apple {
color: red;
&:[WHEN INSIDE `.big`] {
font-size: 1.25em;
}
}
You place the & at the end:
.apple {
color: red;
.big & {
font-size: 1.25em;
}
}

SASS: Child classes according to parent class

Is there a way we can check the parent element class & change child element class properties?
Something like:
if parentClass {
h1{color: red;}
} else if parentClass2 {
h1{color: blue;}
}
Want CSS to be like:
.parentClass h1 {
color: red;
}
.parentClass h2 {
color: blue;
}
So, if the name of the parent class changes the child class properties also changes.
Thanks in advance :)
You can't use #if statement in that case but you could do something like this
h1 {
color: red;
.parent-1 & {
color: blue;
}
.parent-2 & {
color: yellow;
}
}
The output will be
h1 {
color: red;
}
.parent-1 h1 {
color: blue;
}
.parent-2 h1 {
color: yellow;
}

Resources