Sassier z-index Management For Complex Layouts
In 2014, Jackie Balzer wrote an excellent piece for Smashing Magazine on using Sass to automatically manage the z-index
es of elements using lists.
I've been using this technique since an ex-colleague introduced me to it in early 2015, but the disconnect between maintaining multiple lists was starting to bug me.
So, I've come up with a variation which uses Sass maps and lists instead, and allows me to clearly see the hierarchy of the different elements.
The Sass function
@function z-index($key1, $key2: null) {
$map: $z-indexes;
$found-index: null;
@if (map-has-key($map, $key1)) {
$found-index: index(map-keys($map), $key1);
@if ($key2) {
$map: map-get($map, $key1);
$found-index: index($map, $key2);
}
}
@return $found-index;
}
@function z($key1, $key2: null) {
@return z-index($key1, $key2);
}
Our CSS
Then, we set up a $z-indexes
map like so:
$z-indexes: (
main: (
foo,
bar,
tooltip
),
header: (),
modal: ()
);
and we can use it with:
/* .header */
.header { z-index: z(header); }
/* .main elements */
.main { z-index: z(main); }
.foo { z-index: z(main, foo); }
.bar { z-index: z(main, bar); }
.tooltip { z-index: z(main, tooltip); }
/* .modal */
.modal { z-index: z(modal); }
which results in:
/* .header */
.header { z-index: 2; }
/* .main elements */
.main { z-index: 1; }
.foo { z-index: 1; }
.bar { z-index: 2; }
.tooltip { z-index: 3; }
/* .modal */
.modal { z-index: 3; }
In this example, nothing within .main
will ever be able to be above .header
, and .modal
sits atop everything.
Basically, you'll never have z-index
conflicts again \o/
Taking it further
If you didn't want to be limited to 2 levels of nesting, this recursive z-index()
version allows you to use as many levels as you like, with every level except the last being a map.