If you have worked on a relative large frontend codebase before, you will realize how messy it gets when dealing with z-indexes. A quick google on “z-index best practices” results in a number of articles providing solutions: some with a certain degree of JavaScript, some uses SCSS with the help of SCSS variables and some just having a list of standardized z-index values on which the development team agrees upon. I would like to provide another solution that is much simpler and straightforward.
VueJS Teleport
component
The Teleport
component is a great solution to not think about what z-index value you should use when creating modals, confirmation dialogs, slide out drawers or any elements that you want to overlap the main interface.
Defining the teleport’s outlet
In the main HTML’s <body>
element we can specify where our modals and dialogs will render at. With the layering properly defined, we wouldn’t need to recall which layer is above or below another.
<!doctype html>
<html lang="en">
<head>
...
</head>
<body>
...
<div id="app-top-menu"></div>
<div id="app-drawers"></div>
<div id="app-dialogs"></div>
<div id="app-poppers"></div>
<div id="app-announcements"></div>
</body>
</html>
Using the <Teleport>
component
The <Teleport>
component has a to
prop to specify which layer we want our element to be rendered at, it doesn’t get as simple as that! So for example, if we have a top fixed navigation menu, we do not need to specify any z-index even though it is declared near the top in document order. We can just wrap the <nav>
with the <Teleport>
component and then specify the id
of the div that it renders on for the to
prop.
<template>
<Teleport to="#app-top-menu">
<nav>...</nav>
</Teleport>
</template>
Conclusion
I believe using the <Teleport>
component leads to cleaner code with less ambiguity on your journey with z-indexes. I hope native HTML supports this pattern in the future.