The solution is using lists and referencing indexes in SASS. Here’s the trick:
Define a list of element types you’ll be stacking, from the bottom to the topmost element. Use names that will make sense to you (or others) when you go back to the code six months from now. I usually place the list in my _variables.scss file, for easy reference.
1 2 3 4 5 6 | [code language="sass"] // Define stacking order of named elements, bottom -> top $z_elements: menu-bar, tooltip, modal, message-bar, popover; [/code] |
According to this list, a popover will be placed above a message-bar, which will be stacked above a modal, which will be stacked above a tooltip, which will be placed above the menu-bar.
When I’m styling my popover, I define the z-index like this:
1 2 3 4 5 6 7 | [code language="css"] .popover { z-index: index($z_elements, popover); } [/code] |
.. which means «what number is “popover” in the list called “z-elements”»?
The answer is “5”, and here’s the resulting CSS:
1 2 3 4 5 6 7 | [code language="css"] .popover { z-index: 5; } [/code] |
What happens when a new layer comes along? Someone tells you to dig up this old code and insert a new ad-element to be visible even when the modal is triggered, but below any possible message bars. Easy – you just add the element to the list, and all the numbers will be adjusted accordingly:
1 2 3 4 5 6 | [code language="sass"] // Define stacking order of named elements, bottom -> top $z_elements: menu-bar, tooltip, modal, ad, message-bar, popover; [/code] |
In the compiled CSS, the new ad will get a z-index of 4, message-bar will go from 4 to 5, and popovers will now have a z-index of 6:
1 2 3 4 5 6 7 | [code language="css"] .popover { z-index: 6; } [/code] |
Easy peasy, right?
Notes
– Lists can be separated with spaces or commas. I prefer using commas.
– SASS indexes start at 1, not 0 (which differs from JS etc.).
– See more about scaling this solution across stacking contexts, error handling etc. in this Smashing Magazine article.