Thoughts on z-index and UI Kit
When working on a UI Kit library, things get messy pretty quickly with z-index.
Troubles can start as soon as you introduce modals or a search bar. Which one should stay on top? And what about the type head?
Here are some thoughts on possible approaches using SCSS, CSS variables, and documentation.
Basic approach: documentation
This approach rely on having some sort of in codebase documentation, let’s say a docs folder with an z-index.md
In here, you can write the order you wish to apply to your components.
The main benefits of this approach are that at least you’ll state in the docs the correct z-index order, and it’s cheap to apply — you don’t have custom classes or variables to code.
Once you decide the order, you can proceed with common utility classes eg .z-1, .z-2, .z-3 etc…
The downside of this approach is that docs can get out of sync with the code pretty quickly. Devs have to remember to keep the two in sync.
SCSS approach: scss map
In your _variables.scss you can have a map with your components and the z-index order.
// _variables.scss
$z-index-cmp: (
"navbar": 1,
"search-bar": 1,
"search-result": 2,
"modals": 3
);
and then in each cmp create a custom class where you use these values
// _navbar.scss
@use sass:map
.navbar {
z-index: map.get($z-index-cmp, "navbar");
}
This approach is a little bit more expensive in terms of effort as you have to create the map and apply the custom classes, but on the other side the code is in sync with the wanted order.
Also, even if someone messes up adding a utility instead of the custom class, it’s easy to recover.
The downside of this approach is if you need to distribute the UI Kit lib and your final user still need to reorder the z-index.
There’s no clean way for them to manage that.
The CSS variable approach
This is an evolution of the SCSS approach.
In this case, in the custom class, we’ll leverage a CSS variable scoped in :root.
// this could be in the reset
// or you can call it _css_variables.scss
@use sass:map
:root {
--z-navbar: map.get($z-index-cmp, "navbar");
--z-search-bar: map.get($z-index-cmp, "search-bar");
.
.
.
--z-modals: map.get($z-index-cmp, "modals");
}
Then, in the component SCSS file, you can use the CSS variable.
// _navbar.scss
.navbar {
z-index: var(--z-navbar);
}
This will allow someone to be able to override this order even if they don’t have access to the scss files, as the CSS variables will act as a bridge.
Let’s assume you have a different theme that changes the order.
<style>
.theme1 {
--z-modals: 1;
}
</style>
<body class="theme1">
</body>