Compass (SASS) rule with pseudo class - css

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;
}

Related

SCSS modify parent selector

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.

SASS / SCSS hover when using &__* syntax to reach parent selector

Yes yes, I had a hard time trying to define my question.
The general case is like this:
in sass/scss I have a button with some variants:
.button {
/* generic button styles here */
&__icon {
color: green;
}
}
And now I wish to use some hover styles on this, per variant. But because I use the &__* I can't seem to grasp how to do this without rewriting the parent class name.
.button {
/* generic button styles here */
&__icon {
color: green;
}
&:hover {
.button__icon {
color: red;
}
}
}
^^ this works but is pretty manual
Is there a way in sass that allows to access the parent class and get something like:
&:hover {
&__icon {
color:red;
}
}
But this time the &__icon should reference the parent.
The html to this would look somewhat like this:
<button type="button" class="button">
[name]
<span class="button__icon">+</span>
</button>
.button {
$root: &;
&__icon {
color: green;
}
&:hover #{$root}__icon {
color: red;
}
}
or
.button {
$root: &;
&__icon {
color: green;
#{$root}:hover & {
color: red;
}
}
}

How do I render duplicate classes using the amerpsand operator in scss?

I am trying to generate a double class using scss for specifity reasons and avoiding the usage of the dreaded !important
I have tried the following example:
.my-class {
color: black;
&.&:hover {
color: red;
}
}
But all I'm getting is:
Error: Invalid CSS after "... of parent rule": expected "}", was "&.&:hover {"
With reference to your answer, the ampersand can be interpolated as well:
.my-class {
color: black;
&#{&}:hover {
color: red;
}
}
outputs
.my-class {
color: black;
}
.my-class.my-class:hover {
color: red;
}

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.

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