I have a very challenging code for SASS SCSS lovers.
my code and loop challenge:
#for $i from 1 through 8 {
&.-overlay-#{$i} {
#include box-shadow($brand-color-#{$i});
}
}
The mixin ( what inside doesn't matters )
#mixin box-shadow($color: $black) {
box-shadow: inset 194px -7px 200px 0 rgba($color, .42);
}
The list of colors ( I do have 8 colors )
$brand-color-1: red;
$brand-color-2: blue;
$brand-color-3: green; ... so on
The $brand-color-XX variable is passed to the #mixin
What I want to do is, create with #for loop these variations:
.-overlay-1
.-overlay-2
.-overlay-3 ...so on
But that #for is not working at the moment, what do am I missing here?
Regards
M
The #for was working, but you were trying to use variables in a way they're not meant to be used. You can't combine 2 SASS/SCSS variables to make one. You don't have a variable called $brand-color- so the compiler didn't know what to do with that. But you can get the result you want with a list.
DEMO
$brand-color-1: red;
$brand-color-2: blue;
$brand-color-3: green;
$colors: $brand-color-1, $brand-color-2, $brand-color-3;
#mixin box-shadow($color: $black) {
box-shadow: inset 194px -7px 200px 0 rgba($color, .42);
}
#for $i from 1 through length($colors) {
.-overlay-#{$i} {
#include box-shadow(nth($colors, $i));
}
}
You said the result you wanted was, .-overlay-1 .-overlay-2 .-overlay-3 ...so on, so I'm not sure what you were doing with the &. The & is used to refer to the parent class. If you want to nest your created classes, you can do that too...
.cool {
#for $i from 1 through length($colors) {
.-overlay-#{$i} {
#include box-shadow(nth($colors, $i));
}
}
}
...or put them at the same level as the parent...
.cool {
#for $i from 1 through length($colors) {
&.-overlay-#{$i} {
#include box-shadow(nth($colors, $i));
}
}
}
...or create a different class
.cool {
#for $i from 1 through length($colors) {
&-overlay-#{$i} {
#include box-shadow(nth($colors, $i));
}
}
}
Related
I need to create dynamic classes for which I am creating a scss code to create the classes for all the possible values. Below is my code:-
$colors: (
"black": "0,0,0",
"white": "255,255,255",
"red" : "255,0,0"
);
$opacity:9;
#for $i from 0 through $opacity {
$j:$i/10;
#each $color, $rgb in $colors {
$rgba: "#{$rgb},#{$j}";
.background-#{$color}-#{$i} {
background: #{$rgba};
}
}
}
I want it to give out put as :-
.background-black-0 {
background: rgba(0,0,0,0);
}
.background-white-0 {
background: rgba(255,255,255,0);
}
.background-red-0 {
background: rgba(255,0,0,0);
}
.background-black-1 {
background: rgba(0,0,0,0.1);
}
.background-white-1 {
background: rgba(255,255,255,0.1);
}
.background-red-1 {
background: rgba(255,0,0,0.1);
}
struggling with the interpolation for rgba(). Otherwise its getting the exact values I want. If you check my code in https://www.sassmeister.com/ you will see it.
You could use directly your colors as rgb color in your map and then add opacity in your #for loop:
$colors: (
"black": rgb(0,0,0),
"white": rgb(255,255,255),
"red": rgb(255,0,0)
);
$opacity:9;
#for $i from 0 through $opacity {
$j:$i/10;
#each $color, $rgb in $colors {
.background-#{$color}-#{$i} {
background: rgba($rgb, $j);
}
}
}
I have a sass mix-in for my angular to do list, that lightens the color of the app as you go, 1 being dark blue, 50 being white.
How can I go about making the hover make each item's background 50-60% darker?
My mixin:
#mixin shades-of-blue ( $count, $startcolor ) {
#for $i from 0 through $count {
$background-color: lighten( $startcolor, $i + $i );
.tasks:nth-of-type(#{$i}) {
background-color: $background-color;
}
}
}
#include shades-of-blue( 50, #2d89ef);
You should probably be using mix instead of lighten/darken, otherwise everything is white at around 26.
#mixin shades-of-blue ( $count, $startcolor ) {
#for $i from 0 through $count {
$background-color: mix(white, $startcolor, $i + $i);
.tasks:nth-of-type(#{$i}) {
background-color: $background-color;
&:hover {
background-color: mix(black, $background-color, 50);
}
}
}
}
#include shades-of-blue( 50, #2d89ef);
You can try it out here: http://sassmeister.com/
I'm trying to loop through a list of values in Sass and use interpolation of the current key to dynamically output class names that utilize #include and #extend, respectively.
Here is a pen showing the problem, simplified. http://codepen.io/ghepting/pen/vBmLy
As you can see in the markup, I have tried including the "_" inside of the interpolated string as well as outside of it. Is there something I'm missing to work around this limitation of how Sass supports interpolation?
(Note: the OP's pen has disappeared. This is not the original code found in the pen, but a rough approximation of the problem)
$error-light: red;
$error-dark: darken(red, 10%);
$success-light: green;
$success-dark: darken(green, 10%);
$dialogs: error, success;
#each $d in $dialogs {
.#{$d} {
background: $#{$d}-light;
}
}
Interpolation doesn't work on mixins or variables at this point in time. You'll have to come up with a different way to achieve your goal.
As of Sass 3.3, you can use mappings for this purpose for variables:
$dialogs:
( error:
( light: red
, dark: darken(red, 10%)
)
, success:
( light: green
, dark: darken(green, 10%)
)
);
#each $name, $colors in $dialogs {
.#{$name} {
color: map-get($colors, dark);
}
}
And for functions:
#function green() {
#return lighten(green, 10%);
}
#function red() {
#return lighten(red, 10%);
}
#mixin my-bg($function-name) {
background: call($function-name);
}
.foo {
#include my-bg('red');
}
Alternative workaround (for a particular use case):
https://sass-lang.com/documentation/at-rules/mixin#passing-arbitrary-arguments
💡 Fun fact:
Because an argument list keeps track of both positional and keyword arguments, you use it to pass both at once to another mixin. That makes it super easy to define an alias for a mixin!
If you are interested in mixin interpolation because you have a group of mixins, like this:
//_mixins.scss
#mixin text-style-1($args...){ //sass here }
#mixin text-style-2($args...){ //sass here }
#mixin text-style-3($args...){ //sass here }
//_text.scss
.text-style-1 {
#include text-style-1;
}
.text-style-1-contrast {
#include text-style-1($contrast: true);
}
.text-style-2 {
#include text-style-2;
}
.text-style-2-contrast {
#include text-style-2($contrast: true);
}
We can take advantage of passing arbitrary arguments and use an alias for the group:
//_mixins.scss
#mixin text-style-1($args...){ //sass here }
#mixin text-style-2($args...){ //sass here }
#mixin text-style-3($args...){ //sass here }
#mixin text($mixin, $args...) {
#if $mixin == 'style-1' { #include text-style-1($args...); }
#else if $mixin == 'style-2' { #include text-style-2($args...); }
#else if $mixin == 'style-3' { #include text-style-3($args...); }
}
//_text.scss
$text-styles: 'style-1', 'style-2', 'style-3';
#each $style in $text-styles {
.text-#{$style} {
#include text($style);
}
.text-#{$style}-contrast {
#include text($style, $contrast: true);
}
}
Ran into this issue of trying to include an interpolated variable inside a mixin and was able to resolve it with placeholders:
%color-scheme-dark-bg-1 { background-color: #4e5163; }
%color-scheme-dark-color-1 { color: #4e5163 !important; }
%color-scheme-light-bg-1 { background-color: #c7c8ce; }
%color-scheme-dark-bg-2 { background-color: #fd6839; }
%color-scheme-dark-color-2 { color: #fd6839 !important; }
%color-scheme-light-bg-2 { background-color: #fecfc1; }
.card_color {
#mixin CardColorScheme($arg: 1) {
.borderPercent {
#extend %color-scheme-dark-bg-#{$arg};
}
.border {
#extend %color-scheme-light-bg-#{$arg};
}
ul li:before {
#extend %color-scheme-dark-color-#{$arg};
}
.percent {
#extend %color-scheme-dark-color-#{$arg};
}
.heading {
#extend %color-scheme-dark-color-#{$arg};
}
}
&--scheme {
&-1 {
#include CardColorScheme(1);
}
&-2 {
#include CardColorScheme(2);
}
}
}
Hat tip to: https://krasimirtsonev.com/blog/article/SASS-interpolation-in-a-name-of-variable-nest-variables-within-variables
I tried to make the following code look fancier with an #each or a #for loop (without any usable result).
.btn[data-btn-color="black"] {
#include colored-btn($black);
}
.btn[data-btn-color="blue"] {
#include colored-btn($blue);
}
.btn[data-btn-color="red"] {
#include colored-btn($red);
}
// ... and more colors ...
My current approach is to take value from the variable to use it as the value for the data-btn-color attribute and put that snippet into an #each loop.
Something like
#each $color in ($black, $blue) {
#include colored-btn($color);
}
which compiles into:
.btn[data-btn-color="black"] {
background-color: #000; // $black
}
.btn[data-btn-color="blue"] {
background-color: #00f; // $blue
}
Is there any function, which allows me to do such a thing?
You were so close! You don't want the () around what you want to go through in #each. I think Sass would just see what you have as one list item with a two item list inside.
Here is what I think you're trying to do:
$red: #f00;
$blue: #00f;
$black: #000;
$colors: red $red, blue $blue, black $black;
#mixin colored-button($background-color: #000){
background-color: $background-color;
}
#each $color in $colors {
$name: nth($color, 1);
$hex: nth($color, 2);
.btn[data-btn-color="#{$name}"]{
#include colored-button($hex);
}
}
Which would result in:
.btn[data-btn-color="red"] {
background-color: red; }
.btn[data-btn-color="blue"] {
background-color: blue; }
.btn[data-btn-color="black"] {
background-color: black; }
I've been searching all over for an answer to this question for a specific issue I am looking at with SASS. I am wanting to start with an li at 100% opacity but then have it loop through the li's with certain classes and subtract 5% opacity using the transparentize function. The issue though is the foreach loop, as I don't know how many li's with a certain class I'll have. Let me see if I can explain it with code, basically I'll show you the long form and if someone can help me convert it into a short foreach that would be great.
li {
... styles are here ...
&.Language {
background-color: $red
}
&.Language.comp-1 {
background-color: transparentize($red, 0.10);
}
&.Language.comp-2 {
background-color: transparentize($red, 0.20);
}
&.Language.comp-3 {
background-color: transparentize($red, 0.30);
}
&.Language.comp-4 {
background-color: transparentize($red, 0.40);
}
&.Language.comp-5 {
background-color: transparentize($red, 0.50);
}
}
If I was going to do this in PHP this is how I would do it, I just need the SASS version:
$transparency_increment = .10
foreach( $item as $li ) {
background-color: transparentize( $red, $transparency_increment);
$transparency_increment + .10;
}
Hopefully that makes sense, I'm sure I'll have to use the nth item somewhere since the exact count will be unknown. Thanks for help in advance!
What you're looking for is the #for control directive
This should do what you want:
$red: #ff0000;
#mixin foo($prefix, $num, $step){
#for $i from 1 through $num {
#{$prefix}-#{$i} {
background-color: transparentize($red, $i * $step);
}
}
}
li {
#include foo('&.Language.comp', 10, 0.1);
}
Untested and extracted from bootstrap-sass
#mixin transparent_steps_bg($bg_color, $amount, $tranparancy_amount) {
#while $amount> 0 {
.comp-#{$amount} { background-color: transparentize($bg_color, $amount * tranparancy_amount); }
$amount: $amount - 1;
}