Accessing an array key in SASS
$color-collection: ('red', 'orange', 'green', 'blue');
@for $i from 0 to length($color-collection) {
.color-#{$i} {
color: unquote(nth($color-collection, $i+1));
}
}
Use nth()
, also unquote()
if you want to pass quoted strings.
Though, I personally wouldn't:
$color-collection: (red, rgba(50,50,80, .5), darken(green, 50%), rgba(blue, .5));
@for $i from 0 to length($color-collection) {
.color-#{$i} {
color: nth($color-collection, $i+1);
}
}
Because then you can pass any color object.
How to get $values of Array in SCSS?
In my opinion you did not understand very well the difference between maps and lists.
The list is an array
of values:
$breakpoints: (
564,
768,
992,
1200
);
or
$breakpoints: 564, 768, 992, 1200;
or
$breakpoints: 564 768 992 1200;
So this @return map-get($m, $v);
will get you always errors because $breakpoints
is not a map.
The maps have keys and values:
$breakpoints: (
xs: 564,
md: 768,
lg: 992,
xl: 1200
);
To help you in your project, maybe it is better to write a map of nested maps:
$myMap:(
xs:(
min-width: 564px,
width: 200px,
font-size: 20px
),
md:(
min-width: 768px,
width: 300px,
font-size: 30px
),
lg:(
min-width: 992px,
width: 400px,
font-size: 40px
),
xl:(
min-width: 1200px,
width: 500px,
font-size: 50px
)
);
It is more clear the correlation to every values. Now we can write a @mixin to get those values:
@mixin medias($map, $key) {
@each $keyMap, $valueMap in $map {
@media all and (min-width: map-get($valueMap, min-width)) {
#{$key}: map-get($valueMap, $key);
}
}
}
And now we can include it!
@include medias($myMap, width);
This is the result you asked for:
@media all and (min-width: 564px) {
width: 200px;
}
@media all and (min-width: 768px) {
width: 300px;
}
@media all and (min-width: 992px) {
width: 400px;
}
@media all and (min-width: 1200px) {
width: 500px;
}
I posted your new sass file, much more understandable, I think
$myMap:(
xs:(
min-width: 564px,
width: 200px,
font-size: 20px
),
md:(
min-width: 768px,
width: 300px,
font-size: 20px
),
lg:(
min-width: 992px,
width: 400px,
font-size: 20px
),
xl:(
min-width: 1200px,
width: 500px,
font-size: 20px
)
);
@mixin medias($map, $key) {
@each $keyMap, $valueMap in $map {
@media all and (min-width: map-get($valueMap, min-width)) {
#{$key}: map-get($valueMap, $key);
}
}
}
@include medias($myMap, width);
SASS - Accessing Multidimensional Array's Value
You're making this considerably harder than it needs to be. Arrays are useful if you need to loop over variables, you would need to make your own sass function for this which uses map-get
. I strongly recommend just using namespaced variables which are simpler and more portable e.g. $content-width
$content-main-width
.
If you really want to do it see https://css-tricks.com/snippets/sass/deep-getset-maps/
/// Map deep get
/// @author Hugo Giraudel
/// @access public
/// @param {Map} $map - Map
/// @param {Arglist} $keys - Key chain
/// @return {*} - Desired value
@function map-deep-get($map, $keys...) {
@each $key in $keys {
$map: map-get($map, $key);
}
@return $map;
}
map-deep-get($content, "content-header", "width");
SASS : Using lists as associative array
You could use nested maps along with a function like such:
$colors : (
redG : (
1 : #ff0000,
2 : #fff
),
blueG : (
1 : #00ff00,
2 : #ff4544
),
greenG : (
1 : #0000ff,
2 : #123456
)
);
@function color($color, $position: 1) {
@return map-get(map-get($colors, $color), $position)
}
a {
background-color: color(redG, 1);
color: color(redG, 2);
}
a {
background-color: color(blueG, 1);
color: color(blueG, 2);
}
a {
background-color: color(greenG, 1);
color: color(greenG, 2);
}
Which will return:
a {
background-color: #ff0000;
color: #fff;
}
a {
background-color: #00ff00;
color: #ff4544;
}
a {
background-color: #0000ff;
color: #123456;
}
Accessing specific value from SASS nested list
You can use SASS's maps to store values inside variables:
$color-config:(
white: #FFF,
black: #303133
);
Then use map-get()
to access it (see here):
content: map-get($color-config, white); # will return #FFF
In other words, don't use double quotes "
around your variable name.
How can I use the key name instead of value in map-get?
use map-keys()
to get all keys in the list.
Sample:
@each $person-name, $person-details in $people {
$age: map-get($person-details, 'age');
$sex: map-get($person-details, 'sex');
$keys: map-keys($person-details);
.#{$person-name} {
height: 100 px;
width: 100 px;
background: #FF3C00;
margin: 0 auto;
&:before {
content:"#{$person-name} #{nth($keys, 1)} : #{$age} ";
}
&:after {
content: "#{nth($keys, 2)}: #{$sex}";
}
}
}
Associative Array SCSS/SASS
In Sass < 3.3 you can use multidimensional lists:
$numbers: (3 "three") (4 "four");
@each $i in $numbers {
.#{nth($i,2)}-#{nth($i,1)} {
/* CSS styles */
}
}
DEMO
In Sass >= 3.3 we get maps:
$numbers: ("3": "three", "4": "four");
@each $number, $i in $numbers {
.#{$i}-#{$number} {
/* CSS styles */
}
}
DEMO
So in terms of fractions, you could just do something in this direction, so that you don't need multiple lists or maps:
$number: 6;
$name: (
("one"),
("two" "halv" "halves"),
("three" "third" "thirds"),
("four" "quarter" "quarters"),
("five" "fifth" "fifths"),
("six" "sixth" "sixsths")
);
and then whatever you want to do with your loops ... maybe even something like this =D
@for $i from 1 to $number {
@for $j from 2 through $number {
.#{ nth( nth( $name, $i ), 1 ) }-#{
if( $i>1,
nth( nth( $name, $j ), 3 ),
nth( nth( $name, $j ), 2 )
)} {
/* CSS styles */
}
}
}
DEMO
(I wrote it this way so that you can notice in @for
, that using to
goes to n - 1
)
How to get a nested value from a key inside of a @each loop in SCSS Map
I have figured it out with a lot of experimenting, perhaps this will help someone who is looking.
if you change up the map a little bit you can do this.
$character-map: (
billy: (
name: 'billy',
color: $colour-light-blue,
left: (
default: -9px,
mobile: -2px
),
)
);
@each $key, $value in $character-map {
left: map-get(map-get($value, left), default);
}
Will compile to left: 9px;
How to get the nth value and key of a Sass list?
That is not a list, it's a map. So you can use map functions to extract a value or a key. There are many interesting functions and work very well with loops.
To answer your question, you could use for example 2 of these functions (map-keys()
& map-values()
) to create a list of keys and values from your map and than use the nth()
function to get your desired value or key:
$map: (
'foo1': 11,
'foo2': 22,
'foo3': 33
);
div{
content:nth(map-keys($map), 2);
z-index:nth(map-values($map), 2);
}
The output:
div {
content: "foo2";
z-index: 22;
}
nth()
tells Sass to step through each value of the map. Otherwise, you'd just assign the first value of the map, 11
, to each variable in your list (if there were multiple variables).
SASS - error parsing associative array
Use sass 3.3.7 and compass 1.0 (it's in alpha gem install compass --pre
) If you got wdm related error then also install wdm(require "Ruby Development Kit") gem. If you keep your gem list clean it will be easier to catch dependency errors. Run gem list --local
and uninstall all previous versions of compass and sass if you don't need them.
Related Topics
Make Scrollbars Only Visible When a Div Is Hovered Over
Table Border Color in CSS with Border Collapse
Css: Background Image Does Not Fill When Scrolling
Webkit Transform Blocking Link
How to Add a Custom Font to Rails App
Clip/Crop Background-Image with CSS
Force Footer on Bottom on Pages with Little Content
Do I Not Understand the Flex-Grow Property
How to Remove Border from Specific Primefaces P:Panelgrid
Single VS Multiple Stylesheets in Responsive Web Design
CSS Focus Not Working in Safari and Chrome
Combining Border-Top,Border-Right,Border-Left,Border-Bottom in CSS
How to Inspect and Tweak :Before and :After Pseudo-Elements In-Browser
Bootstrap Drop Down Cutting Off