How are HTML elements stacked by default?
Published: 2023-08-15 18:21:27

In today's article you'll to learn how HTML elements are stacked by _default_. Therefore, I'll NOT teach you how to change the stacking order of elements (you may use the `z-index` CSS property for this purpose) but only teach you how things work "naturally".

I believe understanding how element stacking works by default will make it easier for you to learn how to control it, which I'll cover in a future article.

## Table of contents

- [Important terms](#terms)
- [The default stacking order](#rules)
- [Demo](#demo)
- [Summary](#summary)
- [Conclusion](#conclusion)

## Important terms <a name="terms"></a>

1. **z-axis**: You may recall from highschool math classes the _3D coordinate system_, which is formed by the _x_, _y_ and _z_ axes. In this system, if you combine two axes you create a two-dimensional _plane_. The remaining axis will always be perpendicular to the plane and form with it the 3D coordinate system. Consider de image below

    <figure><a title="I, Sakurambo, CC BY-SA 3.0 &lt;http://creativecommons.org/licenses/by-sa/3.0/&gt;, via Wikimedia Commons" href="https://commons.wikimedia.org/wiki/File:3D_coordinate_system.svg"><img width="256" alt="3D coordinate system" src="https://upload.wikimedia.org/wikipedia/commons/thumb/2/2c/3D_coordinate_system.svg/256px-3D_coordinate_system.svg.png"></a><figcaption>3D coordinate system</figcaption></figure>

    You can think of the _xy_ plane (the blue layer) as the screen you're looking at right now. Since you're facing the screen (you're perpendicular to the screen) you're on the _z_ axis.

    Although the image only shows one layer on the _xy_ plane, the plane can contain an infinite number of _overlapping_ layers. The overlapping can be total or partial.

2. **Stacking**: Considering the system described above in the context of a web page, _stacking_ is the total or partial superposition of elements. The higher in the stack, the closer to the user facing the screen.
3. **Root element**: The `<html>` element, which is the top-level element of any HTML document, is also known as the _root element_.
4. **Positioned element**:

    > A positioned element is an element whose computed position value is either relative, absolute, fixed, or sticky. (In other words, it's anything except static.)

5. **Descendant element**: A descendant element is an element that is nested within another element, regardless of how deeply nested.
6. **Descendant non-positioned element**: An element that is a descendant of the root element and that has NOT been positioned.
7. **Descendant positioned element**: An element that is a descendant of the root element and that has been positioned.

**Note**: Keep in mind that the `<html>` element is a container for the `<head>` and the `<body>` elements. The former is NOT visible to the user and contains metadata about your page, for instance, it links your page to external style sheets. The latter is a container for the visible portion of your page. Therefore, the descendants of the `<html>` element that matters to us are the one inside the `<body>` element.

## The default stacking order <a name="rules"></a>

Once you understand the terms described above, understanding the default stacking order is pretty straight forward:

- At the very bottom of the stack goes the `<html>` element.
- Then, its non-positioned descendant elements, in order of appearance in the source code.
- And finally, its positioned descendant elements, in order of appearance in the source code.

## Demo <a name="demo"></a>

[![The default stacking of HTML elements](https://img.youtube.com/vi/zac8nGU2RkU/0.jpg)](https://www.youtube.com/watch?v=zac8nGU2RkU)


This is the `<body>` of the page:

```html
<body>
  <div class="static1">Static #1</div>
  <div class="relative">Relative</div>
  <div class="absolute">Absolute</div>
  <div class="fixed">Fixed</div>
  <div class="sticky">Sticky</div>
  <div class="static2">Static #2</div>
</body>
```

You can see from the demo and from the snippet above that both static elements go below the positioned elements when they overlap, even though _Static #2_ comes last in the source code. This proves that in this imaginary _z-axis_ positioned elements are closer the user than non-positioned elements.

The way the positioned elements overlap proves that they are stacked in order of appearance.

What about the _root element_?

⚠️ the next paragraph might blow your mind 🤯

I haven't set any styles to it, which makes it keep its _transparent_ `background-color`. The white background you see comes from the light your device's screen emits. Don't believe me? See the [Formal definition](https://developer.mozilla.org/en-US/docs/Web/CSS/background-color#formal_definition) for the `background-color`.

If you set a different `background-color` to the _root element_ you'll confirm that it is below its descendant elements.

## Summary <a name="summary"></a>

The first thing to consider is that, when we talk about _stacking_, we're talking about a tridimensional conceptualization of HTML pages. Elements are stacked on the z-axis, which is an imaginary axis perpendicular to the screen.

Second, in order to understand how elements are stacked by default, i.e., without the `z-index` property, we need to make a distinction between three types of elements:

- The root element (the `<html>` element) which is a container for every other element you add to your page.
- Non-positioned elements, which have their computed `position` value equals to `static`.
- Positioned elements, which have their computed `position` value equals to anything but `static`.

Third, stacking will only be observable in cases of overlapping between elements.

Fourth, you may not have noticed, but there's no distinction between the different types of positioned elements. By that I mean that absolutely positioned elements do not have precedence over relatively positioned elements or vice-versa, for example. They have the same "weight" and the one that comes later on the source code will be on top.

## Conclusion <a name="conclusion"></a>

Once you understand what _stacking_ means in the context of web pages and the different types of elements that can be stacked, understanding the default stacking order becomes crystal clear.

From a philosophical perspective, when you compare the _Important terms_ section with the _The default stacking order_ section you can see that learning _why_ may be more difficult, but it will make learning the _how_ easier.

Finally, this article does NOT deal with the stacking of nested elements of a stacked element, nor with how to alter the stacking order, but I promise I'll cover that in a future article 🫡

This project's source code is available at this [repo](https://github.com/matheus4lves/article-default-stacking-of-html-elements). Go ahead and give it a star!

Did you like this article? Share it with your friends, or leave a comment, or a reaction. Of course, there's nothing stopping you from doing everything 😄

If you're on HackerNoon, don't forget to subscribe if you want to get my latest articles straight to your inbox.