In the Sass docs, we have this:
#for $i from 1 through 3 {
.item-#{$i} { width: 2em * $i; }
}
I understand the loop. But I don't understand where in .item-#{$i} why the $i variable is encased in #{}? Why not just write $i?
I've looked around and can't find anywhere that explains this.
It's called Interpolation, and is needed when using a variable in a selector or property name. See http://sass-lang.com/documentation/file.SASS_REFERENCE.html#interpolation_
Related
My question is really simple. How can we create rules inside a function. For example we want to create 5 classes for font-size. We will do like
#for $i from 0 through 4{
.size#{$i}{
font-size:($i * 10)
}
}
But what if we want to do that using a function. Actually I want to do that the same for other properties as I did for font-size. So I create a function which will receive some data and then create rulesets.But problem is that I can't use rulesets inside function.
#function createRuleSets(){
#for $i from 0 through 4{
.size#{$i}{
font-size:($i * 10)
}
}
}
Just use a #mixin instead of a #function:
#mixin createRuleSets( $base: 1px ){
#for $i from 0 through 4{
.size#{$i}{
font-size:($base * $i * 10)
}
}
}
#include createRuleSets( 20px );
Functions return values, not rulesets. Mixins allow you to mix in rulesets. https://sass-lang.com/documentation/at-rules/mixin
(I added an argument to the mixin to show how they actually work almost exactly like functions, except for rulesets.)
I want to get data attr which is a number from HTML in my scss file and do a for loop on elements.
so here's what i did :
HTML :
<figure class="inner" data-attr="8"></figure>
SCSS
[data-attr] {
$no: attr('data-attr') !global;
}
and
#for $i from 0 through $no {
&:nth-of-type(#{$i}) {
left: $no;
}
}
but I got an error :
Error: attr("data-attr") is not an integer.$no: attr('data-attr') !global
You'll need to take a different approach.
SASS is a pre-processor that compiles into a CSS file. You can't use a SASS loop to generate CSS output based on a value that you don't have at the time of compilation.
Without knowing what you're actually attempting to do, it's not possible to suggest an alternative solution either.
I have some Sass variables that I want to deprecate soon. How do I do it, without changing the implementation of it?
I want to allow the usage of variables below, but I want to show a message during the compilation step (whenever they are used), that the variables below are going to be deprecated. Is it possible? Also, can I display where the deprecated variable was used?
$screen-xs-min: 320px;
$screen-sm-min: 480px;
$screen-md-min: 768px;
$screen-lg-min: 992px;
$screen-xl-min: 1200px;
$screen-xs-max: ($screen-sm-min - 1);
$screen-sm-max: ($screen-md-min - 1);
$screen-md-max: ($screen-lg-min - 1);
$screen-lg-max: ($screen-xl-min - 1);
I was looking for the solution for this as well and created my own. Maybe this will help someone else.
#use "sass:list";
// The key is the deprecated variable, note the missing $. The value is the newly suggested one.
$deprecated: (
"font-size-h1": "$font-size-h1-clamp",
"font-size-h2": "$font-size-h2-clamp",
"font-size-h3": "$font-size-h3-clamp",
"font-size-h4": "$font-size-h4-clamp",
"font-size-medium": "$font-size-medium-clamp",
"font-size-large": "$font-size-large-clamp",
"font-size-extra-large": "$font-size-extra-large-clamp",
);
#each $variable in $deprecated {
#if variable-exists(list.nth($variable,1)) {
#warn "The scss variable $#{list.nth($variable,1)} is deprecated. Please use #{list.nth($variable,2)} instead.";
}
}
I have the following mapping to contain all of the colours from my theme:
$_base-ocean:rgb(13,176,184);
$_base-hover:10%;
$themes: (
ocean: (
base: $_base-ocean,
hover: darken($_base-ocean, $_base-hover)
)
);
I know how to use an #each loop to get the key/value information from a mapping, but how can I directly access the value of a mapping without using a loop? I tried using square brackets like you would in other languages like JavaScript:
#each $name, $colors in $themes {
[data-page="home"] {
#slider-pagers{
a.#{$name} {
background-color: $colors[base]; // <- line 21
}
}
}
}
But I get a syntax error instead:
error sass/test.scss (Line 21: Invalid CSS after "...d-color: $color": expected ";", was "[base];")
You have the use the map-get function. Sass does not provide a special syntax for accessing values of a mapping.
#each $name, $colors in $themes {
[data-page="home"] {
#slider-pagers{
a.#{$name} {
background-color: map-get($colors, base);
}
}
}
}
Now you get the following output:
[data-page="home"] #slider-pagers a.ocean {
background-color: #0db0b8;
}
A good practice when using SassScript maps (not "source maps"; those are different) is to always quote the keys. For example:
$site-global: (
"ocean": (
"base": $_base-ocean,
"hover": darken($_base-ocean, $_base-hover)
)
);
In order to be compatible with CSS, Sass interprets some unquoted identifiers (including ocean) as color names and translates them internally to color values. When emitting compressed output, Sass will try to produce the smallest possible representation of those colors, which in this case is a hex code. Quoting the keys makes it clear that they should always be strings and should always be emitted with their string values.
Fixed Issue 1 !
It was a case of doing another map-get within a map-get. Once done, I had to reference the default value (this being base). As long as all my default values had a base value this seems to work fine:
#each $theme-colour, $color in $site-global {
[data-page="home"]{
#slider-pagers a.#{$theme-colour}{
background-color:map-get(map-get($site-global, $theme-colour), base);
}
}
}
How it still fails to minify when this code:
#{$variable_here}
Funny enough this code does not:
#slider-pagers a #{$theme-colour}{
or
#slider-pagers a#{$theme-colour}{
Thanks for responding, if anyone knows the is compiling issue that would be great.
I'm not really sure a good name for this question so please rename it if you can think of a better one.
In Bash I have a function that I am using to store certain functions. Consider:
menv_funcs=()
function menv_function {
menv_funcs+=($1)
}
I am then using it in this manner:
menv_function fetch
function fetch {
...
}
I would like to use it like this though:
menv_function fetch {
...
}
Essentially I'm looking for something like the preprocessor macros in C would do but I have been unable to find a way. Any ideas?
As far as I'm aware, you can't directly achieve this. However, I can think of two solutions that may be of interest to you.
First of all, you could just declare the functions as usual, and then obtain the list of declared functions through declare -F. This could be done like:
function fetch {
:
}
menv_funcs=()
while IFS=$"\n" read l; do
menv_funcs+=${l#declare -f }
done < <(declare -F)
Which will cause menv_funcs[#] to list all the functions declared at the point of calling the snippet. Of course, this may catch unwanted functions as well.
To avoid this, you may add some prefix to function names and filter the list:
function menv_fetch {
:
}
menv_funcs=()
while IFS=$"\n" read l; do
if [[ ${l} == 'declare -f menv_'* ]]; then
menv_funcs+=${l#declare -f menv_}
fi
done < <(declare -F)
And if you really want to achieve something like macros, you may try to play with eval:
menv_funcs=()
function menv_function {
local name=${1}
local body=${2}
menv_funcs+=( ${name} )
eval "function ${name} ${body}"
}
menv_function fetch "{
:
}"
But note that you will actually need to quote the whole function body and escape everything appropriately.