问题
I'm making my own plugins that makes multiple media queries automatically by writing single @include
line in SCSS.
So when I type @include medias($bp-values, width);
, the output should be like this:
@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;
}
And this is the code:
$breakpoints: (
564,
768,
992,
1200
);
$bp-values: (
width: (
200px, 300px, 400px, 500px
),
font-size: (
20px, 30px, 40px, 50px
)
);
@function gridnum($m, $v) {
@return map-get($m, $v);
}
@mixin medias($map, $key) {
$myList: map-get($map, $key);
@each $value in $myList {
$number: index($myList, $value);
$grid: gridnum($breakpoints, $num);
@if $value == $num {
@media all and (min-width: $grid + px) {
#{$key}: $value;
}
} @else {
@warn "There is an error to make @media queries.";
}
}
}
What I need is to get the $values
of $breakpoints
for setting it as prefixes of @media queries' width.
But the code doesn't run, and I get this:
Error: Undefined variable: "$num".
Most idle solution would be to merge 2 $maps in single @each directive, but seems like SCSS doesn't support this.
Is there any ways to fix this problem?
回答1:
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);
来源:https://stackoverflow.com/questions/53579774/how-to-get-values-of-array-in-scss