SASS & LESS - extending a separated Class - css

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

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.

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

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

Sass #extend base/default without also extending pseudo-classes?

I know I can #extend .foo:hover, but is there a way to #extend the .foobar base/default properties without also extending the definitions for pseudo-classes like :hover, :active, etc?
For example, how would I change the following such that .foobar extends only .foo's default state?
.foo {
& {
color:blue;
}
&:hover {
background-color: black;
}
}
.foobar {
#extend .foo;
&:hover {
//As is, I have to override. Any better way?
background-color: transparent;
}
}
(If there is no way to do this with Sass, is there a preferred way to achieve the same effect?)
You have to rewrite your selectors in such a way that you only extend exactly the part you want:
%foo {
color:blue;
}
.foo {
#extend %foo;
&:hover {
background-color: black;
}
}
.foobar {
#extend %foo;
&:hover {
background-color: transparent;
}
}
However, depending on how you are going to be extending/reusing your .foo class, the new #content directive might be the better way to go.
#mixin foo {
color: blue;
&:hover {
#content;
}
}
.foo {
#include foo {
background-color: black;
}
}
.foobar {
#include foo {
background-color: transparent;
}
}

Resources