Maintaining z-index properties

March 23, 2020

CSS books

Every web developer has probably been in this kind of situation. If not this exact one, some similar madness has most probably dawned upon you at some point. You're making a webpage, where some modal needs to go over other content. Then, you add a sidebar that needs to cover the modal when open. That's where you assign it a higher z-index than the modal. Then, you need to make sure, that the mobile header appears under the modal and the sidebar. That's where you need to set the z-indices manually again. In a few months, you need to position some new elements between the existing elements. Again, you change all the z-indices, but now you make them spaced by 10 so that you could fit some new potential elements in between in the future. The z-indices over time turn into values with more zeroes than needed (I've already seen z-indices with more than 6 digits in production). It is obvious that there are not more than a million elements stacked on a webpage. How could we tackle this? I was fed up one day and I thought:

"Well ... if I can create some sort of priority list in other technical challenges, why can't I do this here as well?"

Well, turns out, I can. With a little bit of help from a CSS preprocessor like SCSS, which supports lists and iteration. In that way, we can create a list where we organize items (classes) by priority and then let SCSS generate the z-index properties for us automatically and in order:

$itemsByPriority: '.level-1', '.level-2', '.level-3', '.level-4';
@for $priority from 1 through length($itemsByPriority) {
  $selector: nth($itemsByPriority, $priority);
  #{$selector} {
    z-index: $priority;
  }
}

When built, this will output the following CSS:

.level-1 {
  z-index: 1;
}
.level-2 {
  z-index: 2;
}
.level-3 {
  z-index: 3;
}
.level-4 {
  z-index: 4;
}

Mission accomplished.