How do I access a specific element of a mapping?

2019-01-26 02:00发布

问题:

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];")

回答1:

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


回答2:

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.



回答3:

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.



标签: sass