Skip to content

Instantly share code, notes, and snippets.

@jlong
Created February 1, 2014 22:53
Show Gist options
  • Star 49 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save jlong/8760275 to your computer and use it in GitHub Desktop.
Save jlong/8760275 to your computer and use it in GitHub Desktop.
Navigate a nested maps with map-fetch() in Sass
// ----
// Sass (v3.3.0.rc.2)
// Compass (v1.0.0.alpha.17)
// ----
//
// map-fetch($map, $keys)
//
// An easy way to fetch a deep value in a multi-level map. Works much like
// map-get() except that you pass multiple keys as the second parameter to
// go down multiple levels in the nested map.
//
@function map-fetch($map, $keys) {
$key: nth($keys, 1);
$length: length($keys);
$value: map-get($map, $key);
@if ($length > 1) {
$rest: ();
@for $i from 2 through $length {
$rest: append($rest, nth($keys, $i))
}
@return map-fetch($value, $rest)
} @else {
@return $value;
}
}
$config: (
themes: (
mist: (
header: #dcfac0,
content: #00968b,
footer: #85c79c
),
spring: (
header: #f4fac7,
content: #c2454e,
footer: #ffb158
)
)
);
@each $theme in map-keys(map-get($config, themes)) {
.#{$theme} {
.header { background-color: map-fetch($config, themes $theme header ); }
.content { background-color: map-fetch($config, themes $theme content ); }
.footer { background-color: map-fetch($config, themes $theme footer ); }
}
}
.mist .header {
background-color: #dcfac0;
}
.mist .content {
background-color: #00968b;
}
.mist .footer {
background-color: #85c79c;
}
.spring .header {
background-color: #f4fac7;
}
.spring .content {
background-color: #c2454e;
}
.spring .footer {
background-color: #ffb158;
}
@agrobbin
Copy link

@jlong here is a newer version of this nested fetching:

@function map-deep-get($map, $keys...) {
  $value: $map;
  @each $key in $keys {
    $value: map-get($value, $key);
  }
  @return $value;
}

In your example above, you could do this to get the mist header color #dcfac0:

map-deep-get($config, "themes", "mist", "header");

@Jim-Domco
Copy link

+1, Great function! Had the exact same thought about themes and found this before I wrote my own. Thanks for the time-saver!

@dernetzjaeger
Copy link

Great! Exactly what I was looking for!

@antonlvovych
Copy link

+1, Thanks for the saving my time ☺️

@Dan503
Copy link

Dan503 commented Feb 7, 2015

THANK YOU! 😄

@strarsis
Copy link

Could this be moved into a repository and published as eyeglass module on npm?

@callumflack
Copy link

@agrobbin this is great. As I don't completely understand it, is there any chance you could write an error warning into it?

@jessicaschilling
Copy link

Thaaaaaank you!

@dallas
Copy link

dallas commented Feb 6, 2018

What’s the advantage of this over something more standard & built-in like:

Input:

$config: (
  themes: (
    mist: (
      header: #dcfac0,
      content: #00968b,
      footer: #85c79c
    ),
    spring: (
      header: #f4fac7,
      content: #c2454e,
      footer: #ffb158
    )
  )
);

@each $theme-name, $theme-values in map-get($config, themes) {
  .#{$theme-name} {
    @each $section, $color in $theme-values {
      .#{$section} { background-color: $color; }
    }
  }
}

Output:

.mist .header {
  background-color: #dcfac0;
}
.mist .content {
  background-color: #00968b;
}
.mist .footer {
  background-color: #85c79c;
}

.spring .header {
  background-color: #f4fac7;
}
.spring .content {
  background-color: #c2454e;
}
.spring .footer {
  background-color: #ffb158;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment