How to use sass map-get with sass syntax? [duplicate] - sass

This question already has answers here:
Sass mappings and indented syntax
(2 answers)
Closed 7 years ago.
I'm starting a project using sass and I prefer to write it in .sass syntax.
Also I would like to use the map feature in order to declare some key-value variables...
as the example:
$primary-colors: (
"red": "#ff0000",
"green": "#00ff00",
"blue": "#0000ff"
);
/* Key and value together */
#each $color in $primary-colors {
.thing {
content: "#{$color}";
}
}
/* Key and value separate */
#each $color-name, $color-code in $primary-colors {
.color-#{$color-name} {
background: $color-code;
}
}
My issue is that I could not find how to write those map variables in .sass syntax.
I already tried something like:
$primary-colors: (
"red": "#ff0000"
)
$example: map-get($primary-colors, "red")
And I get this error when I try to compile it:
Error: Illegal nesting: Nothing may be nested beneath variable declarations.
My sass version is:
Sass 3.4.11 (Selective Steve)
Does anyone know how to use it like .sass syntax?

Well, this is a problem which goes with .sass syntax as a free feature. You can join a discussion about it on github. But it's just a pointer to the well-known multiline-issue, and it is also discussed on github.
What you can do about that? Just use one-liners. And map-merge function for long declarations. Read about it in the docs.
$array: (1: '1', 2: '2', 3: '3')
$second_array: (4: '4', 5: '5')
$merged: map-merge($array, $second_array)
#each $num, $str in $merged
.link-#{$str}
z-index: $num
The output will be:
.link-1 { z-index: 1; }
.link-2 { z-index: 2; }
.link-3 { z-index: 3; }
.link-4 { z-index: 4; }
.link-5 { z-index: 5; }

Related

Dynamically create variable with sass in list

Basically, I'm trying to generate a lot of styles, each containing an image and a color. Colors are listed and variables are named the same way. The problem is I can't have Sass to use the dynamically generated name (near a{color }. But is it possible to use it this way ? Thanks !
$color-style-winter: #11111;
$color-style-christmas: #22222;
$styles: 'winter' 'hills',
'christmas' 'xmas';
#each $name, $image in $styles {
.style-#{$name} {
background: url('../../images/styles/#{$image}.jpg');
}
a {
color: $color-style- + $name;
}
}
I'm not sure I understood your question fully but have a look on SASS interpolation Docs and the article provided. Use placeholder.
The code could look like:
%my-style-test1 {color: red;}
%my-style-test2 {color: blue;}
$style: 'test1' 'test2';
#each $name in $style {
  a {
    #extend %my-style-#{$name};
  }
}
CSS:
a {
color: red;
}
a {
color: blue;
}
the example is a bit useless but shows how to use % placholder and interpolation
SASS Docs interpolation
SASS Articel Interpolation

SASS dynamic variable names and nested loops throwing error

I'm not totally sure if what I'm attempting is possible, but I've searched around as much as I can and build the following nested loop to create many variants of hex colors (rather than manually typing out the variable names).
$colors: (
green: #006938,
pink: #9d1e65,
//...
);
$variations: (
30%, 50%, 70%,
);
#each $hex, $name in $colors {
#each $v in $variations {
#{$name}-#{$v}: lighten($hex, $v);
}
}
However, I'm getting the following error on my second loop:
$ gulp sass
[17:01:14] Using gulpfile ~/Sites/webcomponents/gulpfile.js
[17:01:14] Starting 'sass'...
events.js:163
throw er; // Unhandled 'error' event
^
Error: src/scss/app.scss
Error: Invalid CSS after "...n $variations {": expected 1 selector or at-rule, was "#{$name}-#{$v}: lig"
on line 72 of src/scss/app.scss
>> #each $v in $variations {
-----------------------------^
at options.error (/Users/martynbisset/Sites/webcomponents/node_modules/node-sass/lib/index.js:291:26)
Is this not the correct syntax for a nested loop? Also, when I try to do the variable name dynamically without the loop, I also get an error .. sorry, kinda two questions in one but would appreciate any advice on this as I'm quite a noob with SASS/SCSS.
$name: "Hello";
$v: "70%";
#{$name}-#{$v}: lighten($hex, $v); // throws error too :(
You can't declare new css property or dynamic variable name in SASS, but you can definitely do something better by converting variable name into different css classes which we will learn step by step and do corrections in your SASS.
Map: Map is a data-type in SASS which represents one or more key value pairs. Map keys and value can be any SASS datatype(like number, string, color, boolean, map, list of values, null).
Syntax of map
map-name1{
key1: value1,
key2: value2,
...
}
map-name2{
key1:(key11:value11, key12: value12), //value is of map datatype
key2:(key21:value21, key22: value22)
}
So, correct the definition of $variations. Even though if you don't specify key it will work.
SASS also provides map-get() to get the value using key.
example,
$font: ( /*define 'font' map*/
color: #666,
size: 16px
);
body {
color: map-get($font, color); /*get value of 'color' property of 'font'*/
font-size: map-get($font, size);
}
2. As we can't declare variable name dynamically in SASS, so better to create some css class using map and #each loop.
Use the below SASS code:
$color:(
green: #006938,
pink: #9d1e65
);
$variations: (
thirty: 30%,
fifty: 50%
);
#each $name, $hex in $color {
#each $n, $v in $variations {
.color-#{$name}-#{$n}{
color: lighten($hex, $v);
}
}
}
After compilation, it will generate the below css,
.color-green-thirty {
color: #03ff89;
}
.color-green-fifty {
color: #69ffb9;
}
.color-pink-thirty {
color: #e470b1;
}
.color-pink-fifty {
color: #f4c6e0;
}
You cannot create dynamic variables in scss. What you can do is instead convert the variable name to a class name and use that everywhere. You also had a syntax issue in #each. It's key,value so your each will be $name,$hex
$colors: (
green: #006938,
pink: #9d1e65,
//...
);
$variations: (
30, 50, 70,
);
#each $name, $hex in $colors {
#each $v in $variations {
$perc: percentage($v/100);
.#{$name}-#{$v} {
background-color: lighten($hex, $perc);
}
}
}

Concancate loop variable with string to produce another variable on the fly

I am trying make this mixing work.. Any ideas how to concancate a variable name on the fly and make it processed.
$colors: purple pink;
#each $color in $colors {
.box--#{$color} {
background-color: #{'$ui'}-$color;
}
}
In this case $ui-red is a red color variable.
Unfortunately, you can't generate or reference to sass single variables in runtime. But you can store your color codes and names in sass maps (requires sass v3.3) and use it in cycle like this:
$colors: ("purple": #f7f,
"pink": #ffa);
#each $color-name, $color-code in $colors {
.box--#{$color-name} {
background-color: $color-code;
}
}
In CSS you get:
.box--purple {
background-color: #f7f;
}
.box--pink {
background-color: #ffa;
}
Example: http://www.sassmeister.com/gist/c1285109946e5207e441c7ee589dd382

SCSS class names with values as input [duplicate]

This question already has answers here:
Can I use variables for selectors?
(4 answers)
Closed 7 years ago.
I am trying to make a css class that can use a number as input for a style associated with the class. For example:
.font-<size> {
font-size: <size>px;
}
where 'size' is a number.
Is this possible with scss?
MY SOLUTION:
This is what I ended up doing which is hard coded but gets the job done:
// Generates some useful quick font size classes
$f-sizes: 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30;
#each $i in $f-sizes {
&.font-#{$i*2}:before {
font-size: #{$i*2}px;
}
}
Which will allow me to access font sizes 2 through 60 via class .font-28.
You would need a mixin.
http://thesassway.com/advanced/pure-sass-functions
#mixin size-mixin($some-number) {
font-size: $some-number;
}
Then you would just include this mixing on your classes.
.font-class {
#include size-mixin(10px);
}
$number: 10;
.font-#{$number} {
font-size: #{$number}px;
}
The SCSS code above compiles into CSS code as follows:
.font-10 {
font-size: 10px; }

SASS: How to check if a map exist [duplicate]

This question already has answers here:
Checking if a variable is defined in SASS
(3 answers)
Closed 8 years ago.
In SASS I would like to generate some css only if a map exists. For this I have to check first, if the map exists or not. It should work similar to this:
$mymap: (
width: 10px,
color: blue,
);
#if MAP-EXISTS($mymap) {
.myclass {
width: map-get($mymap, width);
color: map-get($mymap, blue);
}
}
Due to the fact that a function 'MAP-EXISTS()' does not exist in SASS:
I am looking for a way to do this on another way. But I cannot figure it out.
So my Question is: How can I check if a map exists in SASS?
(SASS Version is V3.4.9)
Thx for answers and help.
There isn't a way to check if a map exist, but you can check if map-has-key which returns true or false whether map has a value associated with a given key which may help you as an alternative solution.
An example:
$mymap: (
width: 10px,
color: blue,
);
.map-exist {
$map-existance: map-has-key($mymap, width);
$map-existance: map-has-key($mymap, color);
// Uncomment the line bellow to see that if a value doesn't exist
// it won't apply any propertie
// $map-existance: map-has-key($mymap, padding);
#if $map-existance == true {
width: map-get($mymap, width);
color: map-get($mymap, color);
}
}
A demo: http://sassmeister.com/gist/f7ecb5b1fb2781cc3225

Resources