I was wondering whether there is a certain way to use variables that affect the style in SCSS.
I'm looking for something like:
var x = 1
.class1 {
if (x==1) {
background-color: red;
} else {
background-color: blue;
}
}
.class2 {
if (x==1) {
background-color: blue;
} else {
background-color: red;
}
}
You can use #if and #else
$x:1;
.class1 {
#if $x == 1 {
background-color: red;
} #else {
background-color: blue;
}
}
.class2 {
#if $x == 1 {
background-color: blue;
} #else {
background-color: red;
}
}
Related
I have code like this:
.outer1 {
&.same-inner {
background-color: white;
}
}
.outer2 {
&.same-inner {
background-color: white;
}
}
.outer3 {
&.same-inner {
background-color: white;
}
}
How do I reuse .same-inner selector?
.outer1, .outer2, .outer3 {
&.same-inner {
background-color: white;
}
}
Translates to CSS:
.outer1.same-inner, .outer2.same-inner, .outer3.same-inner {
background-color: white;
}
Or if you wanted to give each of the outer's there own properties, but also inherit same-inner
.same-inner {
background-color: white;
}
.outer1 {
width:10px;
#extend .same-inner
}
.outer2 {
width:20px;
#extend .same-inner
}
.outer3 {
width:30px;
#extend .same-inner
}
Translates to CSS:
.same-inner, .outer1, .outer2, .outer3 {
background-color: white;
}
.outer1 {
width: 10px;
}
.outer2 {
width: 20px;
}
.outer3 {
width: 30px;
}
Or maybe what you want is:
.same-inner {
background-color: white;
&.outer1 {
width:10px;
#extend .same-inner
}
&.outer2 {
width:20px;
#extend .same-inner
}
&.outer3 {
width:30px;
#extend .same-inner
}
}
Which churns out CSS:
.same-inner, .same-inner.outer1, .same-inner.outer2, .same-inner.outer3 {
background-color: white;
}
.outer1.same-inner {
width: 10px;
}
.outer2.same-inner {
width: 20px;
}
.outer3.same-inner {
width: 30px;
}
You can reuse a selector by #extend.
follow this sass documentation about #extend.
I'm trying to create a color weight mixin. The result would be something like Google Material's color weights ( https://material.io/guidelines/style/color.html#color-color-palette ).
I'm hoping for a function where I could pass the base color and it would lighten / darken for each weight creating variables and classes for each weight.
Take the following manually done weights:
$color-blue: #1483ff;
$color-blue-100: lighten($color-blue, 30%);
$color-blue-200: lighten($color-blue, 20%);
$color-blue-400: lighten($color-blue, 10%);
$color-blue-500: $color-blue;
$color-blue-600: darken($color-blue, 10%);
$color-blue-700: darken($color-blue, 20%);
$color-blue-800: darken($color-blue, 30%);
$color-blue-900: darken($color-blue, 40%);
I was experimenting with something like this:
$colors: $color-blue-100, $color-blue-200, $color-blue-300;
#for $c from 1 through length($colors)-1 {
.bg-blue-#{$i} {
background: $c;
}
}
but that doesn't work and I still have to manually define the variables.
I took the approach of iterating over a predefined "palette" where the weights and percentages are static as well for colors. All you would have to do going forward is to add/change the colors defined.
$colors : (
"blue" : #1483ff,
"green" : #4CAF50,
"yellow" : #FFEB3B,
);
$palette : (
100 : 40%,
200 : 30%,
300 : 20%,
400 : 10%,
500 : 0,
600 : 10%,
700 : 20%,
800 : 30%,
900 : 40%
);
#each $name, $hex in $colors {
#each $weight, $percentage in $palette {
#if $weight < 500 {
.bg-#{"" + $name}-#{$weight} {
background-color: lighten($hex, $percentage);
}
} #else if $weight > 500 {
.bg-#{"" + $name}-#{$weight} {
background-color: darken($hex, $percentage);
}
} #else {
.bg-#{"" + $name}-#{$weight} {
background-color: $hex;
}
}
}
}
Which compiles to
.bg-blue-100 {
background-color: #e0efff;
}
.bg-blue-200 {
background-color: #add4ff;
}
.bg-blue-300 {
background-color: #7ab9ff;
}
.bg-blue-400 {
background-color: #479eff;
}
.bg-blue-500 {
background-color: #1483ff;
}
.bg-blue-600 {
background-color: #006ae0;
}
.bg-blue-700 {
background-color: #0052ad;
}
.bg-blue-800 {
background-color: #003a7a;
}
.bg-blue-900 {
background-color: #002247;
}
.bg-green-100 {
background-color: #d9eeda;
}
.bg-green-200 {
background-color: #b5dfb7;
}
.bg-green-300 {
background-color: #92cf94;
}
.bg-green-400 {
background-color: #6ec071;
}
.bg-green-500 {
background-color: #4CAF50;
}
.bg-green-600 {
background-color: #3d8b40;
}
.bg-green-700 {
background-color: #2d682f;
}
.bg-green-800 {
background-color: #1e441f;
}
.bg-green-900 {
background-color: #0e210f;
}
.bg-yellow-100 {
background-color: white;
}
.bg-yellow-200 {
background-color: #fffbd4;
}
.bg-yellow-300 {
background-color: #fff5a1;
}
.bg-yellow-400 {
background-color: #fff06e;
}
.bg-yellow-500 {
background-color: #FFEB3B;
}
.bg-yellow-600 {
background-color: #ffe608;
}
.bg-yellow-700 {
background-color: #d4be00;
}
.bg-yellow-800 {
background-color: #a19100;
}
.bg-yellow-900 {
background-color: #6e6300;
}
This should do it and no variables to define. You can see the output on sassmeister.
#mixin color-weight ($class, $base-color, $weight: 4) {
$bg-color: null;
#for $i from 1 through 8 {
#if $i < 4 {
$weight: $weight - 1;
$bg-color: lighten($base-color, $weight * 10%);
} #else if $i == 4 {
$weight: 0;
$bg-color: $base-color;
} #else {
$weight: $weight + 1;
$bg-color: darken($base-color, $weight * 10%);
}
.#{$class}-#{$i} { background-color: $bg-color; }
}
}
#include color-weight(bg-blue, #1483ff);
#include color-weight(mad, red);
Is is possible in SaSS to only extend the css properties of a class, and avoid rendering a concatenated classname:
.class_A {
background-color: #f0f;
}
.class_B {
color:#555;
#extend class_A;
}
desired result:
.class_B {
color:#555;
background-color: #f0f;
}
If you still need .class_A then you can do this
%bg-color {
background-color: #f0f;
}
.class_A {
#extend %bg-color;
}
.class_B {
color:#555;
#extend %bg-color;
}
Output CSS:
.class_A, .class_B {
background-color: #f0f;
}
.class_B {
color: #555;
}
If you don't need .class_A just use a variable:
$bg-color: #f0f;
.class_B {
color:#555;
background-color: $bg-color;
}
I don't know if Sass is able to do this, but it doesn't hurt to ask.
The Problem
Basically I have three colors pattern that are repeated in multiple sections of application, like blue, green and orange. Sometimes what changes is the background-color, or the border-color of the component... Sometimes is the text color of a child element, etc.
What I thought?
1. Replace a string pattern inside a content.
.my-class {
#include colorize {
background-color: _COLOR_;
.button {
border-color: _COLOR_;
color: _COLOR_;
}
}
}
2. Providing a callback variable for #content.
// This is just a concept, IT DOESN'T WORK.
#mixin colorize {
$colors: blue, green, orange;
#each $colors in $color {
// ...
#content($color); // <-- The Magic?!
// ...
}
}
// Usage
#include colorize {
background-color: $color;
}
I tried to implement such solutions, but without success.
Instead of it...
See below my workaround to get it partially working:
#mixin colorize($properties) {
$colors: blue, green, orange;
#for $index from 1 through length($colors) {
&:nth-child(#{length($colors)}n+#{$index}) {
#each $property in $properties {
#{$property}: #{nth($colors, $index)};
}
}
}
}
You can use this mixin that way:
.some-class {
#include colorize(background-color);
}
What will come output:
.some-class:nth-child(3n+1) {
background-color: blue;
}
.some-class:nth-child(3n+2) {
background-color: green;
}
.some-class:nth-child(3n+3) {
background-color: orange;
}
The problem? Well, I can't use it with child selectors.
Based on the above information, there is some magic solution for this case?
I think I figured out what you meant; it is a little (very) messy, but it should do what you want:
#mixin colorize($parentProperties,$childMaps) {
$colors: blue, green, orange;
#for $index from 1 through length($colors) {
&:#{nth($colors, $index)} {
#each $property in $parentProperties {
#{$property}: #{nth($colors, $index)};
}
}
#each $mapped in $childMaps {
$elem: nth($mapped,1);
$properties: nth($mapped,2);
#{$elem}:nth-child(#{length($colors)}n+#{$index}) {
#each $property in $properties {
#{$property}: #{nth($colors, $index)};
}
}
}
}
}
It would turn out to be:
/* -------------- USAGE ------------------*/
.some-class {
#include colorize(
background-color,( //Parent properties
(button, background-color), //Child, (properties)
(span, (background-color,border-color)) //Child, (properties)
)
);
}
/* --------------- OUTPUT ----------------*/
.some-class:nth-child(3n+1) {
background-color: blue;
}
.some-class button:nth-child(3n+1) {
background-color: blue;
}
.some-class span:nth-child(3n+1) {
background-color: blue;
border-color: blue;
}
.some-class:nth-child(3n+2) {
background-color: green;
}
.some-class button:nth-child(3n+2) {
background-color: green;
}
.some-class span:nth-child(3n+2) {
background-color: green;
border-color: green;
}
.some-class:nth-child(3n+3) {
background-color: orange;
}
.some-class button:nth-child(3n+3) {
background-color: orange;
}
.some-class span:nth-child(3n+3) {
background-color: orange;
border-color: orange;
}
Hope that that is what you are looking for :)
I'm creating a Sass mixin with 3 arguments one of them is optional & I want to print it out if it's passed otherwise I don't want to print anything.
Here is how my mixin looks like:
#mixin name($arg1, $arg2, $arg3: false){
#if $arg3 { #{$arg3} , }
& {
color: #{$arg1};
> #{$arg2}{
&:before{
something...
}
}
}
}
but this doesn't work & it throws an error
Warning: Syntax error: Invalid CSS after "...$arg3}": expected "{", was "}"
So how can I achieve the desired result?
This would be how you would write it:
#mixin name($arg1, $arg2, $arg3: false) {
$sel: ();
#if $arg3 {
$sel: append($sel, unquote($arg3));
}
$sel: append($sel, unquote('&'), comma);
#{$sel} {
color: #{$arg1};
> #{$arg2} {
&:before{
border: 1px solid;
}
}
}
}
.foo {
#include name(yellow, blue, '.bar');
}
Output:
.foo .bar, .foo {
color: yellow;
}
.foo .bar > blue:before, .foo > blue:before {
border: 1px solid;
}
However, it might be better written like this:
#mixin name($arg1, $arg2) {
color: #{$arg1};
> #{$arg2} {
&:before{
border: 1px solid;
}
}
}
%foo, .foo {
#include name(yellow, blue);
}
.foo .bar {
#extend %foo;
}