SASS: Child classes according to parent class - css

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

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 & LESS - extending a separated Class

Just wanted to know if there exist any way to extend just first two of separated Class like in example, or either exist any other option like creating a specific Class
.background{background:red} and use it as extension instead of a separated Class (but i don't wanted to output in CSS a class .background).
EXAMPLES:
SASS:
.foo {
background:red
}
.foo {
color:red
}
.bar {
#extend .foo;
}
.foo {
font-size: 16px
}
LESS:
.foo {
background:red
}
.foo {
color:red
}
.bar {
&:extend(.foo);
}
.foo {
font-size: 16px
}
The output in CSS will be:
.foo, .bar {
background: red;
}
.foo, .bar {
color: red;
}
.foo, .bar {
font-size: 16px;
}
But I want to be like this:
.foo, .bar {
background: red;
}
.foo, .bar {
color: red;
}
// No .bar class here
.foo {
font-size: 16px;
}
What way should i follow to make this happened?
You've got your inheritance backwards. bar does not extend foo, foo extends bar:
LESS:
.bar {
background-color: red;
}
.bar {
color: red;
}
.foo {
&:extend(.bar);
font-size: 16px;
}
Produces
CSS:
.bar,
.foo {
background-color: red;
}
.bar,
.foo {
color: red;
}
.foo {
font-size: 16px;
}

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

Sass referencing parent selectors using the ampersand character within nested selectors

Just when I thought Sass was the coolest thing since sliced bread, it had to go and let me down. I'm trying to use the ampersand to select a parent of a nested item. It's a complex selection and its returning some unexpected results...
My sass:
.page--about-us {
a {
text-decoration:none;
}
.fa-stack {
.fa {
color:pink;
}
a & {
&:hover {
.fa-circle-thin {
color:red;
}
.fa-twitter {
color:blue;
}
}
}
}
}
Outputted CSS:
.page--about-us a {
text-decoration: none;
}
.page--about-us .fa-stack .fa {
color: pink;
}
a .page--about-us .fa-stack:hover .fa-circle-thin {
color: red;
}
a .page--about-us .fa-stack:hover .fa-twitter {
color: blue;
}
Expected Output (Note the placement of the a tag):
.page--about-us a {
text-decoration: none;
}
.page--about-us .fa-stack .fa {
color: pink;
}
.page--about-us a .fa-stack:hover .fa-circle-thin {
color: red;
}
.page--about-us a .fa-stack:hover .fa-twitter {
color: blue;
}
Demo:
http://sassmeister.com/gist/8ed68bbe811bc9526f15
You can store the parent selector in a variable!
Take the following BEM-like SASS:
.content-block {
&__heading {
font-size: 2em;
}
&__body {
font-size: 1em;
}
&--featured {
&__heading {
font-size: 4em;
font-weight: bold;
}
}
}
The selector inside of .content-block--featured is going to be .content-block--featured .content-block--featured__heading which might not be what you're after.
It's not as elegant as the single ampersand but you can stash the parent selector into a variable! So to get what you might be after from the above example without hard-coding the parent selector:
.content-block {
$p: &; // store parent selector for nested use
&__heading {
font-size: 2em;
}
&__body {
font-size: 1em;
}
&--featured {
#{$p}__heading {
font-size: 4em;
font-weight: bold;
}
}
}
So, OP, in your case you might try something like this:
.page--about-us {
$about: &; // store about us selector
a {
text-decoration:none;
}
.fa-stack {
.fa {
color:pink;
}
#{$about} a & {
&:hover {
.fa-circle-thin {
color:red;
}
.fa-twitter {
color:blue;
}
}
}
}
}
This is the normal behavior, as described in Sass documentation (link):
& will be replaced with the parent selector as it appears in the CSS. This means that if you have a deeply nested rule, the parent selector will be fully resolved before the & is replaced.
Meaning:
.foo {
.bar {
.baz & {
color: red;
}
}
}
Will render as:
.baz .foo .bar {
color: red;
}
And not:
.baz .bar {
color: red;
}
The right way to get your expected result is this one:
.page--about-us {
a {
text-decoration:none;
.fa-stack:hover {
.fa-circle-thin {
color:red;
}
.fa-twitter {
color:blue;
}
}
}
.fa-stack {
.fa {
color:pink;
}
}
}

Resources