Compiled css failed with nested mixin with ampersand - css

I am trying to nest mixin together to update style. But I found that the output css seems not what I expected.
I am wondering if there is any way can nest mixin together and having ampersand on the right.
Below are some sample code and expected result.
Thanks.
HTML:
<html class="classA">
<div class="itemA">
<div class="itemB">Item B</div>
</div>
</html>
SCSS:
#mixin add-style-when-classA-exist() {
.classA & {
#content;
}
}
#mixin add-style-when-classB-notExist() {
html:not(.classB) & {
#content;
}
}
.itemB {
color: blue;
#include add-style-when-classB-notExist() {
color: green;
}
#include add-style-when-classA-exist() {
color: red;
#include add-style-when-classB-notExist() {
color: yellow;
}
}
}
Actual CSS Output:
.itemB {
color: blue;
}
html:not(.classB) .itemB {
color: green;
}
.classA .itemB {
color: red;
}
html:not(.classB) .classA .itemB {
color: yellow;
}
Expected CSS Output:
.itemB {
color: blue;
}
html:not(.classB) .itemB {
color: green;
}
.classA .itemB {
color: red;
}
html:not(.classB).classA .itemB {
color: yellow;
}

Related

SCSS, how to #extend Nested ampersand "prefix"?

The nested ampersand prefix doesn't get expanded with #extend
.firstClass{
color: green;
&-a{
color: red;
}
}
.secondClass{
#extend .firstClass;
}
The expected output would be
.firstClass, .secondClass{
color: green;
}
.firstClass-a, .secondClass-a{
color: red;
}
But the actual output doesn't have the .secondClass-a at all.
.firstClass, .secondClass{
color: green;
}
.firstClass-a{
color: red;
}
I found this is an intended behavior to use #extend https://github.com/sass/sass/issues/2154
But is there a workaround that can extend nested ampersand prefix?
Maybe the versions I worked on were older but I don't believe it was possible. You could change your properties to a mixin as such:
#mixin classStyle {
color: green;
&-a{
color: red;
}
}
.firstClass {
#include classStyle;
}
.secondClass {
#include classStyle;
}

How can I pass a tag in as a scss mixin argument?

I am creating a mixin to target a child element.
Example.
Targeting all <a> tags of the parent that has a parent of section---blue
I figure that I can pass the tag as an argument as follows
But I am not getting the desired result
SCSS
#mixin themeParent ($child) {
&--blue $child {
color: getColour("theme", "bluehighlight");
}
&--green $child {
color: getColour("theme", "greenhighlight");
}
&--purple $child {
color: getColour("theme", "purplehighlight");
}
}
.section {
#include themeParent(a);
}
I would have thought that this would compile to
.section--blue a {
color: blue;
}
Can someone please explain to me why?
#mixin themeParent ($child) {
&--blue #{$child} {
color: blue;
}
}
outputs: .section--blue a { color: blue; }
If you want more specificity, just add another &:
#mixin themeParent ($child) {
&#{&}--blue #{$child} {
color: blue;
}
}
outputs: .section.section--blue a { color: blue; }
If you want more scability, just iterate over colors you want:
#mixin themeParent ($child) {
$colors: red, blue, green;
#each $color in $colors {
&#{&}--#{$color} #{$child} {
color: $color;
}
}
}
Put $child in #{$child}.
#mixin themeParent ($child) {
#{$child} {
color: #000;
}
}
.section {
#include themeParent(a)
}
Output:
.section a {
color: #000;
}
If I put this in a simple way, there is no need to pass the tag as a parameter to the mixin function instead, u should pass the color of the element.
<div className="section--blue">
<a>section blue</a>
</div>
<div className="section-green">
<a>section green</a>
</div>
mixin and css
#mixin themeParent ($color) {
color:$color;
}
.section{
&--blue {
a{
#include themeParent(blue);
}
}
--green{
a{
#include themeParent(green);
}
}
}
Hope this is useful.

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.

Manage nesting in LESS

I want to get something like
.classA, .classB, .classC, .classD, .classE {
color: white;
}
.classA .classI, .classB .classI, classC .classI {
background: red;
}
is this possible with something like
.classA, .classB, .classC {
color: white;
.classI {
background: red;
}
}
class D and E shouldn't geht the class I.
hopefully you know, what I mean
For your case you shouldn't use .classD and .classE at the top level because the nested selector doesn't apply to all of them.
You should just use .classA, .classB, .classC and then use :extend for the other two.
.classA, .classB, .classC {
color: white;
.classI {
background: red;
}
}
.classD, .classE {
&:extend(.classA);
}
When compiled it would result in the following CSS:
.classA, .classB, .classC, .classD, .classE {
color: white;
}
.classA .classI, .classB .classI, .classC .classI {
background: red;
}
Yes like that:
.classA {
color: white;
&.classI {
background: red;
}
}

Resources