{
  "$type": "site.standard.document",
  "content": {
    "$type": "site.standard.content.markdown",
    "text": "From the days of working with design tools like Photoshop, layering compositions in 3D space on a computer has been part of the job. Managing what appears on top can be dozens of elements, maybe even groups of elements, and carefully curating the order of the layers is often a necessary unit of work.\n\nAs you can expect, this sort of exercise has translated to the web, and traditionally we think the `z-index` property is meant to manage this ordering in a similar way to how layers would work in a design tool. When you are working alone on your own project, this is reasonable because you are in control of the elements, the order, and the composition as a whole. You can decide if the `z-index` you added yesterday isn’t good enough today and make modifications. You can tweak this part here, and make a small change there to get everything just right. In fact, I use `z-index` right here on the blog in a few specific places to get things looking just right artistically.\n\nBut for larger teams where elements are coming together from all across the organization to be composed into a single experience, trying to manage `z-index` is a political battlefield. It’s not possible to just make a `--dropdown-elevation` variable, because that dropdown might be on another surface that itself has an elevation higher than the dropdown.\n\nPopular public design systems like [Shopify Polaris](https://polaris-react.shopify.com/tokens/z-index) include `z-index` tokens which don’t mention where the token is meant to be used, we just know they exist.\n\nThere are certainly attempts at making sense of this. [A recent article on CSS-Tricks](https://css-tricks.com/the-value-of-z-index/) suggest naming the elements where they are expected to appear. Semantically, this makes sense on the surface. But as mentioned earlier, it’s very possible that a flyout that is normally underneath a modal is meant to later be on top of it. And it would be inappropriate to make an entirely separate component meant for “modal dropdowns”. Maybe it’s OK to set your own `z-index`? Well, how do you know it isn’t conflicting with another element that will appear later in the lifecycle. You’re essentially playing whack-a-mole, goldilocking the perfect `z-index` value, tokens or no tokens.\n\nBut what if you didn’t need `z-index` at all? There’s two approaches I want to highlight and both related to a very simple concept. **Elements are visible in the order they appear in the DOM.**\n\n## Top layer\n\nFor what purpose do we set elements in 3D space on the web at all? Certainly, we can stylistically show something is a little bit raised for some personality but when we are creating flyouts and popovers, why are we using them. Overall, these are meant for focused attention. The user was currently navigating the general interface but needs to either focus on something further to continue. Sometimes that’s to choose an option, or maybe be notified of something. This means that there’s a hierarchy to what is being presented. This thing is currently important, then this thing is important, and so on. So this means as we introduce elements to the user, this is conveying a sense of importance. The most recent thing that is added, is the thing the user needs to see more than any other.\n\nThis is how the [top layer](https://developer.mozilla.org/en-US/docs/Glossary/Top_layer) works in HTML. It is a separate layer from the rest of the DOM where anything placed within it will be on top anything that would be placed in the normal DOM. No amount of `z-index` can place elements higher than the top layer. Additionally, z-index doesn’t work in the top layer. So your question might be, how do I provide the correct order of elements? The order of the elements is how they are added to the top layer. That way, if you want some messaging to be the newly most important thing, you simply append it to the top layer.\n\nElements that can apepar in the top layer are restricted to the following [according to MDN](https://developer.mozilla.org/en-US/docs/Glossary/Top_layer):\n\n-   Fullscreen elements, i.e., elements that have been caused to display in fullscreen mode by a successful `Element.requestFullscreen()` call.\n-   `<dialog>` elements displayed as a modal via a successful `HTMLDialogElement.showModal()` call.\n-   Popover elements shown via a successful `HTMLElement.showPopover()` call.\n\nIt seems you can also declaratively get popover elements into the top layer. There’s an [example at MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/popover) using the `popover` attribute which successfully renders into the top layer.\n\nNow, it’s more clear what is supposed to be on top. You can see all the elements and their visual order in devtools. Here’s an gif from the [Chrome for Developers article on the top layer](https://developer.chrome.com/blog/what-is-the-top-layer) showing how to inspect these elements.\n\n![Devtools top layer inspection](/images/devtools-top-layer.gif)\n\nDevon Govett, one of the engineers behind Adobe Spectrum, [recently described some of the drawbacks](https://github.com/adobe/react-spectrum/discussions/9696#discussioncomment-15942257) about using the top layer. I’ve made a response to the comments about `<dialog/>` in [a recent Wireframe episode](https://www.youtube.com/watch?v=-blEWN_jM64). But it’s important to reiterate that you *do* have control of the order, and I’d argue better control than spraying a new `z-index` number and praying it doesn’t conflict with something else.\n\n## Grid positioning\n\nThe other common reason why `z-index` is used is to compositionally place elements on top of each other. This was very common when we used to use the [aspect ratio hack](https://css-tricks.com/aspect-ratio-boxes/) years ago for video. In this hack we’d need to use a padding value as a percentage which is based on the width of the element to maintain the aspect ratio of the box. Then we’d break the inner container out of the flow, and make it fill the parent’s dimensions.\n\n```\n.aspect-ratio-box {\n  height: 0;\n  overflow: hidden;\n  padding-top: calc(100% / (16/9));\n  position: relative;\n}\n\n.aspect-ratio-box-inside {\n  position: absolute;\n  inset: 0;\n}\n```\n\nThese days, if we needed a similar effect, we can just use `aspect-ratio: 16/9` on the parent, but having a child fill a container is still important today. And it is commonly done using this combination of `position` values.\n\nUsing position creates a new [stacking context](https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Positioned_layout/Stacking_context) which you probably don’t want and may have not even known was happening. While it might be harmless to use in one place, when you start positioning many shared elements, you might find putting a `z-index` on one of them causes something else that was positioned to conflict. Understanding stacking contexts is very important when working with positioned elements, and there’s a [great article by Josh Comeau](https://www.joshwcomeau.com/css/stacking-contexts/) about them.\n\nBut you can avoid creating a stacking context altogether using CSS grid! Assuming a similar HTML setup for the aspect ratio hack, here’s what that looks like with grid. I’ve removed the padding hack since we don’t need that any longer with modern CSS.\n\n```\n.aspect-ratio-box {\n  aspect-ratio: 16/9;\n  display: grid;\n}\n\n.aspect-ratio-box-inside {\n  grid-area: 1 / 1 / -1 / -1;\n}\n```\n\n<p>See the Pen <a href=\"https://codepen.io/fauxserious/pen/yyagwjq\"> Untitled</a> by Donnie D’Amato (<a href=\"https://codepen.io/fauxserious\">@fauxserious</a>) on <a href=\"https://codepen.io\">CodePen</a>.</p>\n\nAny time you want to have an element match the dimensions of its parent, this is the technique that you should think of first. This approach avoids using `position` and works with the order in which elements are provided.\n\nYou can also place elements relative to the container. For example, maybe you’d like to place a close button at the top corner.\n\n<p>See the Pen <a href=\"https://codepen.io/fauxserious/pen/emdgXLx\"> Grid positioning banner</a> by Donnie D’Amato (<a href=\"https://codepen.io/fauxserious\">@fauxserious</a>) on <a href=\"https://codepen.io\">CodePen</a>.</p>\n\nI wouldn’t recommend this specific approach for handling a close button because [the composition’s elements might conflict with each other](/posts/close-thy-enemy/). You should see the problem with this if you resize the example, heading will appear over the button. But it should give you some ideas of what else you might use CSS grid positioning for. Want the button on top, reorder the elements in the HTML.\n\nWhen we use and promote techniques that avoid pitfalls, we produce more robust applications and consistent systems of composition. Sure, CSS gives us a lot of tools, but it’s up to us to use them in thoughtful ways. Reaching for `z-index` should be a last resort when everything else doesn’t work. There’s better ways in a modern web, we just need to take a moment while our chatbots are working to explore novel solutions on our own.",
    "version": "1.0"
  },
  "coverImage": {
    "$type": "blob",
    "ref": {
      "$link": "bafkreigjarlkicpgxbgo55sftyytrz7eopbtwssd3p5sxhwijn4qjqxjie"
    },
    "mimeType": "image/png",
    "size": 221800
  },
  "description": "My thing is more important than your thing",
  "path": "/posts/avoiding-z-index",
  "publishedAt": "2026-03-13T00:00:00.000Z",
  "site": "https://blog.damato.design",
  "tags": [
    "css",
    "components",
    "tokens",
    "organization"
  ],
  "textContent": "From the days of working with design tools like Photoshop, layering compositions in 3D space on a computer has been part of the job. Managing what appears on top can be dozens of elements, maybe even groups of elements, and carefully curating the order of the layers is often a necessary unit of work.\n\nAs you can expect, this sort of exercise has translated to the web, and traditionally we think the  property is meant to manage this ordering in a similar way to how layers would work in a design tool. When you are working alone on your own project, this is reasonable because you are in control of the elements, the order, and the composition as a whole. You can decide if the  you added yesterday isn’t good enough today and make modifications. You can tweak this part here, and make a small change there to get everything just right. In fact, I use  right here on the blog in a few specific places to get things looking just right artistically.\n\nBut for larger teams where elements are coming together from all across the organization to be composed into a single experience, trying to manage  is a political battlefield. It’s not possible to just make a  variable, because that dropdown might be on another surface that itself has an elevation higher than the dropdown.\n\nPopular public design systems like Shopify Polaris include  tokens which don’t mention where the token is meant to be used, we just know they exist.\n\nThere are certainly attempts at making sense of this. A recent article on CSS-Tricks suggest naming the elements where they are expected to appear. Semantically, this makes sense on the surface. But as mentioned earlier, it’s very possible that a flyout that is normally underneath a modal is meant to later be on top of it. And it would be inappropriate to make an entirely separate component meant for “modal dropdowns”. Maybe it’s OK to set your own ? Well, how do you know it isn’t conflicting with another element that will appear later in the lifecycle. You’re essentially playing whack-a-mole, goldilocking the perfect  value, tokens or no tokens.\n\nBut what if you didn’t need  at all? There’s two approaches I want to highlight and both related to a very simple concept. Elements are visible in the order they appear in the DOM.\n\nTop layer\n\nFor what purpose do we set elements in 3D space on the web at all? Certainly, we can stylistically show something is a little bit raised for some personality but when we are creating flyouts and popovers, why are we using them. Overall, these are meant for focused attention. The user was currently navigating the general interface but needs to either focus on something further to continue. Sometimes that’s to choose an option, or maybe be notified of something. This means that there’s a hierarchy to what is being presented. This thing is currently important, then this thing is important, and so on. So this means as we introduce elements to the user, this is conveying a sense of importance. The most recent thing that is added, is the thing the user needs to see more than any other.\n\nThis is how the top layer works in HTML. It is a separate layer from the rest of the DOM where anything placed within it will be on top anything that would be placed in the normal DOM. No amount of  can place elements higher than the top layer. Additionally, z-index doesn’t work in the top layer. So your question might be, how do I provide the correct order of elements? The order of the elements is how they are added to the top layer. That way, if you want some messaging to be the newly most important thing, you simply append it to the top layer.\n\nElements that can apepar in the top layer are restricted to the following according to MDN:\nFullscreen elements, i.e., elements that have been caused to display in fullscreen mode by a successful  call.\nelements displayed as a modal via a successful  call.\nPopover elements shown via a successful  call.\n\nIt seems you can also declaratively get popover elements into the top layer. There’s an example at MDN using the  attribute which successfully renders into the top layer.\n\nNow, it’s more clear what is supposed to be on top. You can see all the elements and their visual order in devtools. Here’s an gif from the Chrome for Developers article on the top layer showing how to inspect these elements.\n\nDevon Govett, one of the engineers behind Adobe Spectrum, recently described some of the drawbacks about using the top layer. I’ve made a response to the comments about  in a recent Wireframe episode. But it’s important to reiterate that you do have control of the order, and I’d argue better control than spraying a new  number and praying it doesn’t conflict with something else.\n\nGrid positioning\n\nThe other common reason why  is used is to compositionally place elements on top of each other. This was very common when we used to use the aspect ratio hack years ago for video. In this hack we’d need to use a padding value as a percentage which is based on the width of the element to maintain the aspect ratio of the box. Then we’d break the inner container out of the flow, and make it fill the parent’s dimensions.\n\nThese days, if we needed a similar effect, we can just use  on the parent, but having a child fill a container is still important today. And it is commonly done using this combination of  values.\n\nUsing position creates a new stacking context which you probably don’t want and may have not even known was happening. While it might be harmless to use in one place, when you start positioning many shared elements, you might find putting a  on one of them causes something else that was positioned to conflict. Understanding stacking contexts is very important when working with positioned elements, and there’s a great article by Josh Comeau about them.\n\nBut you can avoid creating a stacking context altogether using CSS grid! Assuming a similar HTML setup for the aspect ratio hack, here’s what that looks like with grid. I’ve removed the padding hack since we don’t need that any longer with modern CSS.\n\nSee the Pen  Untitled by Donnie D’Amato (@fauxserious) on CodePen.\n\nAny time you want to have an element match the dimensions of its parent, this is the technique that you should think of first. This approach avoids using  and works with the order in which elements are provided.\n\nYou can also place elements relative to the container. For example, maybe you’d like to place a close button at the top corner.\n\nSee the Pen  Grid positioning banner by Donnie D’Amato (@fauxserious) on CodePen.\n\nI wouldn’t recommend this specific approach for handling a close button because the composition’s elements might conflict with each other. You should see the problem with this if you resize the example, heading will appear over the button. But it should give you some ideas of what else you might use CSS grid positioning for. Want the button on top, reorder the elements in the HTML.\n\nWhen we use and promote techniques that avoid pitfalls, we produce more robust applications and consistent systems of composition. Sure, CSS gives us a lot of tools, but it’s up to us to use them in thoughtful ways. Reaching for  should be a last resort when everything else doesn’t work. There’s better ways in a modern web, we just need to take a moment while our chatbots are working to explore novel solutions on our own.",
  "title": "Avoiding z-index",
  "updatedAt": "2026-06-13T19:13:31.270Z"
}