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

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

Related

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; }

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

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; }

SASS Mixin - Use variables to populate class name [duplicate]

This question already has answers here:
Sass #each with multiple variables
(5 answers)
Closed 8 years ago.
I have several colours set up as classes
.black {background: $black;};
.red {background: $red;}
.yellow {background: $yellow;}
.grey {background: $grey;}
.white {background: $white;}
.blue {background: $blue;}
.full-black {background: #000;}
.light-black {background: #222;}
but i want to create a mixin which takes the class name and automatically creates the class name and fills in the background colour so i don't have to type this out every time..
I have tried something like this
#mixin colours ($black,$full-black,$light-black,$red,$blue,$yellow,$white,$grey) {
.(colours): background:{colours};
}
But can't figure out the right code.
you should use "associative array" to define the name of your colors and the code:
$colors: ("emerald": "#2ecc71", "carrot": "#e67e22");
#each $name, $hexa in $colors {
.#{$name} {
color: #{$hexa};
}
}
I made a simple codepen to show you: http://codepen.io/pik_at/pen/MYGJqY

Can I set a Sass variable inside a breakpoint? [duplicate]

This question already has answers here:
Using Sass Variables with CSS3 Media Queries
(8 answers)
Closed 7 years ago.
Is it possible to set the value of a variable once, inside a single sass-breakpoint, rather than each time I use the variable?
In other words, I'd like to do this:
$tab: 600px;
$wp: 100%;
#include breakpoint($tab) {
$wp: 95%;
}
.alpha {
// ...
width: $wp;
}
.beta {
// ...
width: $wp;
}
.gamma {
// ...
width: $wp;
}
... rather than this:
$tab: 600px;
$wp: 100%;
$wp-tab: 95%;
.alpha {
// ...
width: $wp;
#include breakpoint($tab) {
width: $wp-tab;
}
}
.beta {
// ...
width: $wp;
#include breakpoint($tab) {
width: $wp-tab;
}
}
.gamma {
// ...
width: $wp;
#include breakpoint($tab) {
width: $wp-tab;
}
}
I don't think the first approach will work as is. Is there another way to achieve the same result? Is this approach a bad idea?
That is not possible.
Quoting nex3, the developer of Sass:
While this would be pretty cool, it's very much contrary to the
existing semantics of a Sass stylesheet. What you've outlined already
has a meaning: it sets the variable twice in sequence and then
accesses it (modulo some scoping issues). The sequential and largely
imperative nature of Sass means that the sort of automatic duplication
of rules you're describing becomes very complex. We actually
considered something very similar for handling SassScript &, and ended
up realizing that it was effectively impossible to do so and preserve
the existing semantics.
The best approximation you can do right now is to put the styles that
need to vary in a mixin with parameters and include that in your media
queries.
Source: https://github.com/nex3/sass/issues/1227

Sass: Create mixin for input fields

I'm new to Sass so I need help with the creation of a mixing for my input fields.
However, if anyone knows of an already made mixin for this or if Compass has one that accomplishes this, please let me (us) know.
I currently have the following CSS rules in my .scss file:
input[type="text"],
input[type="password"],
input[type="email"],
input[type="search"],
input[type="url"],
textarea,
select { ... }
input[type="text"]:hover,
input[type="text"]:focus,
input[type="password"]:hover,
input[type="password"]:focus,
input[type="email"]:hover,
input[type="email"]:focus,
input[type="search"]:hover,
input[type="search"]:focus,
input[type="url"]:hover,
input[type="url"]:focus,
textarea:hover,
textarea:focus,
select:hover,
select:focus { ... }
Now, as we know HTML5 provides a nice new set of input types, but right now I don't need to add input types like date, month or week, that's why I don't have them listed "yet".
So in the case I need to add them in the future, I'll update that list you see above.
However, my problem is that I feel I'm repeating myself all over here, plus, the work of selecting items, copying, pasting and editing every time for every new input type I add to the list is just plain dumb and I almost sure Sass' mixins can be of help with this. The problem is that creating a mixin for this is honestly very confusing to me.
I've looked around here and the web for something similar but haven't been able to find anything.
Any help with this is greatly appreciated.
Ok, I eventually found the Sass mixing library Bourbon.
They have an 'add-on' for HTML5 input types (here's a link to the .scss file they created), but it doesn't have the :hover or :focus pseudo elements. So I added them.
I honestly don't know if what I did is the best way to write this mixin, but the thing works marvelously:
//************************************************************************//
// Generate a variable ($all-text-inputs) with a list of all html5
// input types that have a text-based input, excluding textarea.
// http://diveintohtml5.org/forms.html
//************************************************************************//
$inputs-list: 'input[type="email"]',
'input[type="number"]',
'input[type="password"]',
'input[type="search"]',
'input[type="tel"]',
'input[type="text"]',
'input[type="url"]',
// Webkit & Gecko may change the display of these in the future
'input[type="color"]',
'input[type="date"]',
'input[type="datetime"]',
'input[type="datetime-local"]',
'input[type="month"]',
'input[type="time"]',
'input[type="week"]';
$unquoted-inputs-list: ();
#each $input-type in $inputs-list {
$unquoted-inputs-list: append($unquoted-inputs-list, unquote($input-type), comma);
}
$all-text-inputs: $unquoted-inputs-list;
// You must use interpolation on the variable:
// #{$all-text-inputs}
//************************************************************************//
// #{$all-text-inputs}, textarea {
// border: 1px solid red;
// }
// :hover and :focus pseudo elements
// Added by Ricardo Zea
// http://ricardozea.net
// #ricardozea
// Tracking: http://stackoverflow.com/questions/13180807/sass-create-mixin-for-input-fields
$inputs-list-hf:'input[type="email"]:hover',
'input[type="number"]:hover',
'input[type="password"]:hover',
'input[type="search"]:hover',
'input[type="tel"]:hover',
'input[type="text"]:hover',
'input[type="url"]:hover',
'input[type="color"]:hover',
'input[type="date"]:hover',
'input[type="datetime"]:hover',
'input[type="datetime-local"]:hover',
'input[type="month"]:hover',
'input[type="time"]:hover',
'input[type="week"]:hover',
'input[type="email"]:focus',
'input[type="number"]:focus',
'input[type="password"]:focus',
'input[type="search"]:focus',
'input[type="tel"]:focus',
'input[type="text"]:focus',
'input[type="url"]:focus',
'input[type="color"]:focus',
'input[type="date"]:focus',
'input[type="datetime"]:focus',
'input[type="datetime-local"]:focus',
'input[type="month"]:focus',
'input[type="time"]:focus',
'input[type="week"]:focus';
$unquoted-inputs-list-hf: ();
#each $input-type-hf in $inputs-list-hf {
$unquoted-inputs-list-hf: append($unquoted-inputs-list-hf, unquote($input-type-hf), comma);
}
$all-text-inputs-hf: $unquoted-inputs-list-hf;
// You must use interpolation on the variable:
// #{$all-text-inputs-hf}
//************************************************************************//
// #{$all-text-inputs-hf}, textarea {
// border: 1px solid red;
// }
As you can see I copied and pasted the original mixing and added the prefix -hf and of course the :hover and :focus to the new rules.
And in my .scss file I added this #import:
#import "html5-input-types"; (no need for the underline _ or file extension .scss)
And in the 'Forms' section of my .scss file I added these rules:
/*Normal state*/
#{$all-text-inputs},
textarea,
select { ... }
/*:hover and :focus states*/
#{$all-text-inputs-hf},
textarea:hover,
textarea:focus,
select:hover,
select:focus { ... }
I know I have textarea and select outside the mixin file (html5-input-types.scss), not sure yet if I'm including them in it or not, gotta think about it.
Anyway, this worked for me pretty well and although I will still need to update the html5-input-types.scss if anything changes in the future, at least I'm handling these input fields way more efficiently than before.
Hopefully what I did here helps someone else.
And if any of you has a suggestion to improve the mixin, by all means let me (us) know.
Thanks.
In case anyone comes across this for the same reason I did. Why not let SASS do the work?
CodePen
$form-background: #f8f8f8;
$form-color: #000;
$form-border: 1px solid lighten($form-color, 50%);
$form-focus-background: darken($form-background, 10%);
$form-focus-color: #999;
$form-focus-border: 1px solid $form-color;
%input-styles {
width: 15em;
min-height: 30px;
margin: 0 0 15px 15px;
background: $form-background;
color: $form-color;
border: $form-border;
transition: .2s ease-in-out;
transition-property: color, background-color, border;
}
%input-styles--focus {
background-color: $form-focus-background;
color: $form-focus-color;
border: $form-focus-border;
}
#mixin input-styles($styles, $focus_styles) {
$types: 'email', 'number', 'radio', 'password', 'search', 'tel',
'text', 'url', 'color', 'date', 'datetime',
'datetime-local', 'month', 'time', 'week';
#each $type in $types {
input[type="#{$type}"] {
#extend #{$styles};
&:focus {
#extend #{$focus_styles};
}
}
}
select,
textarea {
#extend #{$styles};
&:focus {
#extend #{$focus_styles};
}
}
}
#include input-styles('%input-styles', '%input-styles--focus');

Resources