Connect with us

Technology

Managing CSS Z-Index In Massive Tasks — Smashing Journal


About The Creator

Steven Frieson is a entrance finish developer who loves to resolve issues for individuals, whether or not they’re web site customers or fellow builders. He’s fascinated about many …
Extra about
Steven

Wrangling z-index values is a tough job for a lot of builders. Right here is an easy-to-implement mini-framework primarily based on present conventions that brings readability and confidence to working with z-index.

There are a number of articles that specify z-index (right here’s one), because it continues to journey up builders of all expertise ranges. I don’t assume that the variety of articles is an indication that none of them do job at explaining it, however that there are lots of builders on the market and simply because one developer learn and understood the article doesn’t essentially imply that everybody on their staff learn and understands it now. Whereas taking the time to raised perceive how z-index (or any piece of expertise) works will certainly set you as much as work with it higher, we are able to additionally take one other method: make it simpler to work with z-index.

We use abstractions and conventions to cover away the difficult and error-prone elements, which in flip makes it simpler for everybody who must do the identical job. I had the chance to try to make z-index simpler to work with for my staff whereas engaged on a redesign of our firm’s web site. The system I designed allowed my staff to implement the whole UI whereas by no means having to query what a sure z-index worth was used for, what quantity to make use of when including a brand new z-index declaration, or the best way to repair stacking bugs that crept into the system.

Widespread Resolution

The commonest system I’ve seen for managing z-index values — aside from no system — is setting a number of general-use values, every separated by an arbitrary quantity. This answer undoubtedly tames z-index points, however as I’ve labored on groups that use this technique there nonetheless appears to be confusion about the best way to use it correctly. Right here is an instance from the Bootstrap documentation.

$zindex-dropdown:       1000;
$zindex-sticky:         1020;
$zindex-fixed:          1030;
$zindex-modal-backdrop: 1040;
$zindex-modal:          1050;
$zindex-popover:        1060;
$zindex-tooltip:        1070;

Bootstrap defines z-index values in Sass variables like $zindex-dropdown, $zindex-sticky, and $zindex-fixed. These names appear fairly straight ahead, however when a developer goes to decide on a price for a characteristic they’re engaged on, there could possibly be confusion as to which worth is most applicable for his or her use. They find yourself asking, “Is what I’m implementing a ‘dropdown’ or a ‘popover’?” which may simply be debated and will not have a transparent reply.

A second situation I see with this answer is that the precise values for the variables may appear complicated or result in insecurity. This answer leaves area in between every worth to present builders area so as to add their very own values in between if needed. Bootstrap defines seven values separated by increments of 10, beginning at 1000 and ending at 1070.

Many questions may come to thoughts when studying this:

“Why begin at 1000?

“Is there something lower than 1000?”

“The place is 1010? Is it a bug? Is one thing else utilizing it?”

“Why was 10 chosen? What if I want greater than 9 values to go in between?”

Although I’ve by no means really wanted these “what if” questions answered, they’ll add insecurity and confusion to a system that already appears magical and misunderstood. Can we take away all of those issues, permitting the developer to simply and precisely select the z-index worth they want?

A New Resolution

Since engaged on a redesign gave my staff a recent begin, this was one frequent situation we needed to see if we may keep away from. To align with our normal coding requirements, my objectives for managing z-index was to keep away from magic numbers and to make it simpler for each staff member to confidently contribute. The second purpose of constructing it simpler for others is obscure, so I centered on attempting to resolve these frequent points:

  • Individuals usually select arbitrarily giant z-index values;
  • z-index bug fixes usually lead to a brand new z-index bug;
  • The connection between z-index values is tough to hint.

Let’s take a look at options for every of those points that I used to be capable of apply, leaning on conventions and utilizing present applied sciences.

Giving Z-Index Values Semantics

One purpose individuals usually select arbitrarily giant z-index values is as a result of they don’t know the z-index worth of the merchandise above which they’re attempting to put a brand new merchandise. As soon as they discover an arbitrarily excessive worth that works, they go away it as an alternative of discovering an optimum worth. In a while, when somebody finds this worth they do not know why it’s what it’s, and even the unique writer might have forgotten.

z-index: 9999;

The answer for fixing “magic numbers” like that is by utilizing a named fixed as an alternative. Whereas naming the worth alone doesn’t give us far more worth than the category title does, after we put our z-index constants collectively, their relationship begins to turn into express.

To take away the magic numbers, I first began defining all of our z-index values in a JavaScript file. I used a JavaScript file since our software was utilizing a CSS-in-JS answer, although this and the concepts on this article will be carried out with styling preprocessors like Sass variables in addition to in CSS utilizing customized properties.

export const backdrop = 0;
export const openButton = 1;
export const dropdown = 2;

With z-index constants, the CSS worth has little extra that means, and the precise worth is obscured away.

css`
  z-index: ${backdrop};
`;

This additionally makes the unique worth simple to search out, revealing the associated constants, however there’s a additional enchancment that may be made. We all know by how z-index works that these values are associated to one another, so we are able to change our constants to make that extra obvious.

export const backdrop = 0;
export const openButton = backdrop + 1;
export const dropdown = openButton + 1;

Utilizing easy arithmetic, we are able to use the earlier constants to make the subsequent fixed. Taking this concept one step additional to additional eradicate ambiguity, I added some utility constants to make these definitions learn extra like a sentence.

const base = 0;
const above = 1;

export const backdrop = base;
export const openButton = above + backdrop;
export const dropdown = above + openButton;

Now when somebody sees a line like z-index: ${dropdown}; they’ll look discover the dropdown’s definition and skim, “The dropdown is above the open button.”

This makes future upkeep of the constants simpler. Every time you’ve gotten a brand new worth so as to add, you will be assured that you’re including it to the correct place.

export const backdrop = base;
export const openButton = above + backdrop;
export const dropdown = above + openButton;
export const closeButton = above + dropdown; // new

Deleting values is simple too, however you have to bear in mind to replace another values which can be depending on it. Utilizing JavaScript, the linter highlighted this for me.

Stacking bug tickets usually present up that say one thing like, “the dropdown is overlapping with the button when it needs to be beneath.” When coming throughout these, the repair is so simple as swapping the connection pointers within the definitions.

export const backdrop = base;
export const dropdown = above + backdrop;
export const openButton = above + dropdown;
export const closeButton = above + dropdown; // ???

Now that we’ve swapped the z-index order, we discover one other potential bug earlier than we even examine the browser. The shut button may now battle with the open button. Now you can have the mandatory conversations to resolve bugs earlier than anybody sees an issue in manufacturing.

One additional piece I discovered to be useful in uncommon conditions was a utility for putting gadgets beneath others. To keep away from mixing above and beneath, I made the rule that beneath ought to solely be used for destructive values.

const base = 0;
const above = 1;
const beneath = -1;

export const backdrop = beneath + dropdown;
export const dropdown = beneath + button;
export const button = base;

On this system, each z-index worth is simply as excessive because it must be, and because it’s dynamically chosen, you aren’t involved with what the worth really is.

You can even delete and add values understanding with confidence the way it will have an effect on the opposite stacked components.

As soon as our software ended up with a dozen or so z-index constants, although it began to turn into a little bit bit complicated having a protracted flat record.

Organizing By Stacking Context

When serious about stacking context and the way the values of every stacking context are unbiased of others, it seemed like different front-end options for efficient scoping. I drew similarities to different JavaScript modules, parts, atomic design, and BEM. They’re all attempting to resolve comparable issues of how we are able to independently scope issues, holding them from affecting different areas.

Taking inspiration from BEM, I made a naming conference for our constants to raised set up the values and convey extra order to the flat record of constants. The format I ended up utilizing had a template like this: z<Context><Component>.

The z portion is a prefix denoting the truth that the worth is supposed for use in z-index declarations, contemplating we had different constants outlined in our JavaScript information like coloration variables.

The<Context> portion is changed with the title stacking context the fixed belongs to. That is just like the “block” in BEM and in follow virtually all the time shares the identical title because the element being styled. The principle exception is the foundation HTML stacking context that’s used for web page area stacking.

The ultimate portion of the format, <Component> is for the title of the precise merchandise to be positioned within the stacking context and is most just like “ingredient” in BEM.

Right here is a full instance of what this naming conference may seem like when added to what we’ve talked about beforehand. For an interactive model, you may mess around with the identical instance in a CodePen:

See the Pen [Managing CSS Z-Index in Large Projects Demo](https://codepen.io/smashingmag/pen/xxEvepz) by Steven Frieson.

See the Pen Managing CSS Z-Index in Massive Tasks Demo by Steven Frieson.

For different language variations, take a look at this repository.

// Utils
const base = 0;
const above = 1; // use this for all values above the bottom
const beneath = -1; // and this for all values beneath the bottom

// Web page Format
export const zLayoutNavigation = above + base;
export const zLayoutFooter = above + base;
export const zLayoutModal = above + zLayoutNavigation;
export const zLayoutPopUpAd = above + zLayoutModal;

// NavMenu
export const zNavMenuBackdrop = beneath + base;
export const zNavMenuPopover = above + base;
export const zNavMenuToggle = above + zNavMenuPopover;

Now that our constants are organized by their stacking context, we are able to rapidly see which values are associated and the place a brand new worth or repair ought to go.

Taking It Additional

That’s basically the specification of how this could work. Contemplating this answer was solely designed with one software in thoughts, there are some additional steps that could possibly be taken to make it extra mature and help extra use instances. A few of these concepts are extra particular to the language it’s being carried out in however most concepts carry over.

One space that would presumably be improved round what’s being shipped to the browser. Once I carried out this, the framework we have been utilizing didn’t give us a lot management over the construct instruments, so the JavaScript file of all of the definitions was bundled with the appliance. This didn’t have a measurable efficiency affect on our software, however you’ll have observed that all the values could possibly be computed at compile time. An implementation utilizing Sass would find yourself not delivery any of the Sass variables to the shopper, however as an alternative, insert the derived z-index worth within the CSS. For JS and CSS options, construct instruments like Webpack and PostCSS, respectively, may assist do the identical.

The best way the answer advanced as I labored on it, the z-index constants ended up multi function file. This ended up being a good way to see all the z-index values throughout the appliance without delay, making it simpler to rapidly look for any doable stacking conflicts. They have been additionally filed away with different styling constants like colours and typography, so it made sense to initially have all of them outlined collectively. Because the file grew although, it began to be internally organized by stacking context as defined above. For the reason that stacking contexts usually mapped to a element, it began feeling like every set of constants could possibly be collocated with their element. This is able to convey all the conventional advantages of collocation, being nearer to the information they’re utilized in, inflicting much less friction when needing so as to add, edit, and take away constants. We by no means refactored it, however that looks as if a viable choice to discover.

One further piece has to do with ergonomics and developer expertise. The constants are all exported as a flat record for the time being. The naming conference took inspiration from BEM, however Sass and JavaScript permit us to make use of different methods to set up our knowledge. Sass maps or JavaScript Objects or Maps may have been used to prepare the values hierarchically. If we had all of the values in a z object, it may have led to shorter import statements. We may have gone additional to have an object per stacking context as nicely resulting in a utilization model extra like z.format.navigation. Totally different instruments like TypeScript may guard in opposition to making typos right here, although this is likely to be extra effort than it’s value.

Our Outcomes

The system as spelled out was efficiently carried out and deployed to our manufacturing purposes. Checking again in on the goals, we undoubtedly removed the magic numbers. So far as developer ease and confidence goes, my staff was capable of simply add new z-index values and repair pre- and post-launch bugs with out concern that the adjustments would introduce new bugs. On a number of events, we fastened bugs earlier than they have been filed.

We additionally have been capable of keep away from the difficulty of coming throughout a random z-index: 9999;. Although the appliance had sticky headers, floating motion buttons, dropdowns, modals, pop up advertisements, and extra within the stacking context, the very best worth we had was 5. Even then, nobody knew it for the reason that values have been all abstracted away from us in variables.

Fixing developer expertise points resulted in a z-index mini-framework, serving to individuals make the proper resolution with much less effort and transfer extra rapidly.

One thing else we observed was that typically we have been assigning a z-index after we didn’t essentially want one. Since stacking contexts will be created by a number of totally different properties, declarations like place: sticky; can act in the same method as setting z-index: 1;. In these instances, we continued so as to add a continuing and declaration anyway. Holding them allowed for higher consistency within the system as an alternative of permitting there to be particular instances, which might degrade confidence about whether or not all the things was working accurately or not. Holding the fixed record full aided in understanding the system and set us up higher for rearranging the values when needed.

What It Doesn’t Remedy

Like all framework, there are elements that it doesn’t not do job at fixing for you. Naming issues continues to be exhausting, and this framework barely exacerbates the issue by requiring that you just title your entire z-index values. Even nonetheless, we discovered that the gained readability overcame the chore of getting to call all of them.

This technique additionally doesn’t essentially assist you determine which stacking context a bug is in. Coming throughout a z-index bug the place you don’t know the place the brand new stacking context is created or the place the z-index worth is ready just isn’t solved by this framework, however upon getting discovered the difficulty, the trail to creating the proper repair is evident.

Utilizing It In Your App

The concepts shared right here needs to be actionable in most purposes relying in your styling answer and browser help. Migrating to make use of this technique just isn’t very dangerous since stacking contexts are already scoped individually; you may migrate one context because it already exists at a time. Altering to make use of these conventions forces you to explain extra clearly what you have already got in your app, shining a lightweight on what may at present appear to be a darkish, scary nook.

In case your z-index values are in a state the place you might be uncertain about most or all of them, then the finest option to convert to this technique will in all probability be to begin by creating a continuing for every worth in a single record in a single file. Because the stacking contexts turn into extra clear, you can begin grouping them and renaming them (if needed) to evolve to the naming conference.

My staff was not working with any exterior CSS libraries or frameworks that included z-index values, however that would presumably add some issue to adopting this technique. Hopefully, the utilities are configurable sufficient to cope with most makes use of and to even incorporate the third-party values into the system.

Lastly, all the examples right here have been written as a single file of z-index values, however you could possibly collocate these values with the element to make an excellent stronger connection between the 2. Utilizing a file naming conference will make it simpler to search out all the values all through the appliance.

Strive It Out Your self

If you’re having bother wrangling z-index values in your website and find yourself attempting out these recommendations, I might love to listen to about your expertise. This mini-framework was developed over only a few months and has solely been utilized in one manufacturing codebase, so there are actually unexplored use instances and opinions that could possibly be added or tweaked.

Smashing Editorial(vf, yk, il)



Click to comment

Leave a Reply

Your email address will not be published. Required fields are marked *