Every UI has stackable layers and it's important to have control over how these layers play together. Some examples of stackable layers are tooltips, modals, popovers, selects, dropdowns, and menus.
The issues that come up across the usage of these these layers are related to z-index and visibility handling, in other words, "what layer goes on top?"
You might have encountered this if you've worked in codebases with
z-index: 9999
. This technique is an attempt to ensure than an element is
always on top of all other elements.
But this method isn't as safe as you might think:
A stacking context can be created in many ways, and here are just a few examples:
position: absolute
or position: relative
and z-index
value other than auto
.opacity
value less than 1
.transform
or filter
applied.z-index
other than auto
.Once a stacking context is created, the z-index
rules of the any child
stacking context(s) now only have meaning in this parent.
We have some links at the end of this page to help you learn more about stacking contexts.
An alternative to z-index
is to use the DOM's natural stacking order to our
advantage. React's Portals allow us to
insert a child into a different location in the document, whilst not affecting
other behaviours in React such as event bubbling.
Chakra Portal implementation allows for nesting, and defaults to inserting
children at the end of document.body
.
With this approach, you can create a stacking context for your application, and be certain that any children you render with Portal will always appear on top of everything else in your application, regardless of child stacking contexts.
This is particularly useful for components like modals and toast notifications.
Yes, there are many cases where this will make sense.
As a general rule, we recommend not exceeding z-index
values of more than 1
or 2
, and to use stacking contexts to combat more complex stacking issues.
If you're interested in learning more about z-index
and stacking contexts,
check out these great resources: