Gaps in sass css output - css

I'm writing some sass to generate a set of icons based on a series of parameters. I have a function that analyses a set of variables and then returns a 'scenario' variable which in turn is used to filter the information taken from the nested map where everything is stored.
The code which retreives the information from the nested map is as follows:
#each $key-lv0, $lv0 in $icon-config {
#if($key-lv0 == $scenario) {
.icon{
#each $key-lv1, $lv1 in $lv0 {
#if type-of($lv1) != "map" {
#{$key-lv1}: $lv1;
}
#each $key-lv2, $lv2 in $lv1 {
#if type-of($lv2) != "map" {
.#{$key-lv1} {
#{$key-lv2}: $lv2;
}
}
#each $key-lv3, $lv3 in $lv2 {
#if($key-lv2 == "hover") {
.#{$key-lv1}:#{$key-lv2} {
#{$key-lv3}: $lv3;
}
} #else {
.#{$key-lv1} #{$key-lv2} {
#{$key-lv3}: $lv3;
}
}
}
}
}
}
}
}
... and this produces something along these lines:
.icon .icon-header {
background-color: #00a9f0;
}
.icon .icon-header:hover {
border-color: #040100;
}
... etc ...
... which is fine - repeated statements aside whicvh I'll deal with later.
The problem is the cap between ".icon" and ".icon-header". These classes will all be used in a single element and for the css to be interpretted correctly it needs to generate something like this:
.icon.icon-header {
background-color: #00a9f0;
}
.icon.icon-header:hover {
border-color: #040100;
}
I've tried bringing ".icon" down like so:
#if type-of($lv1) != "map" {
.icon#{$key-lv1}: $lv1;
}
and removing it from the top but sass rejects this with the following error:
Error: Properties are only allowed within rules, directives, mixin includes, or other properties.
It seems such a minor thing but it's nagging me and I can't seem to find an answer.

Related

sass-lint restrict partial BEM rule

Let's say I have a class: myclass__button-create--success.
I want to limit the usage of -create part in:
.myclass__button {
&-create {
}
}
As it's not a new block, element or modifier.
Allowed structures:
.myclass__button-create {
&--success {
}
}
.myclass {
&__button-create {
}
}
.myclass__button-create--success {
}
Any idea how to achieve this restriction using sass-lint?

SASS functions check if value is map returns error

I want to check if the value provides to a function is a map or not.
#function func($props...) {
#if(is-map($props)) {
#return 'something';
}
#else {}
}
h1 {
color: func((color: red));
}
I'm getting the error:
(color: red) isn't a valid CSS value.
What am I doing wrong?
I personally never heard about any native Sass function called is-map. If you want to check the type of something, use the type-of function, so for example, checking for type-of($props) == map would solve your problem in this case.
#function func($props...) {
#if(type-of($props) == map) {
#return 'something';
}
#else {}
}
Because function returns map. Not a color as expected. Use map-get to get the access to properties values.
#return map-get($props, color);
And you have the variable argument. To get the first of arguments use nth($props, 1).
Sassmeister demo.
Update
If parameters in map are dynamic you can use this mixin instead of function.
#mixin print($declarations) {
#if $declarations {
#each $property, $value in $declarations {
#{$property}: $value
}
} #else {
#error "mixin print: $declarations is not specified";
}
}
Mixin sassmeister demo.

How does :local(.class) { } work in CSS Modules?

I've started using CSS modules, however I cannot find any examples of how exactly this works:
:local(.class){
/* some property */
}
All classes are local by default, so what does :local or :global mean?
That's right, all classes are local by default. But if you switched a block to global and you need a local selector inside, this where you need local applied.
:global {
.a {
...
}
:local(.b) {
...
}
}
compiles to
.a {
...
}
.b___1bJNe {
...
}

Sass each function is compiling with dollar sign in front of it

I'm trying to use an each loop in Sass but the css is compiling with the variable name instead of the content of the variable.
$green-1: #9ae200;
$green-2: #5ea600;
$color-list: green-1 green-2;
#each $single-color in $color-list {
&.#{$single-color} {
background-color: $single-color;
}
}
The output I am looking for is:
.green-1 {
background-color:#9ae200;
}
.green-2 {
background-color:#5ea600;
}
But the css is compiling as:
.green-1 {
background-color:green-1;
}
.green-2 {
background-color:green-2;
}
So to try to get the dollar sign in there I tried this:
#each $single-color in $color-list {
#function create-variable($variable){
#return "$" + $variable;
}
&.#{$single-color} {
background-color: create-variable($single-color);
}
}
But that compiled as:
.green-1 {
background-color:$green-1;
}
.green-2 {
background-color:$green-2;
}
Sass is not reading the variables for some reason and is taking them literally. Anyone know how to make this work?
You cannot create dynamic variable in sass. Instead you can achieve your desired result using map
example:
$green-1: #9ae200;
$green-2: #5ea600;
$color-map: (
green-1: $green-1,
green-2: $green-2,
);
.body{
#each $key,$value in $color-map {
&.#{$key} {
background-color: $value;
}
}
}

LESS CSS define variables when another variable is true

I've used guard expressions elsewhere in my CSS to achieve IF statements in LESS, however these don't work for me when trying to declare variables like so...
#neutral: false;
#warm: true;
when (#neutral = true) {
#green: #91C95B;
#red: #F15647;
etc...
}
when (#warm = true) {
#green: #91AD3C;
#red: #BF2A23;
etc...
}
This is an example of how I would like to be able to use that variable
h1 {
color:#green;
}
This is how I would expect it to compile down to CSS
h1 {
color: #91AD3C;
}
Is this possible with LESS or would I need to modify my code to use mixin guards?
You can use Guarded Mixins like this :
#neutral: false;
#warm: true;
.color() when (#neutral) {
#green: #91C95B;
}
.color() when (#warm) {
#green: #91AD3C;
}
.color();
h1 {
color:#green;
}

Resources