Why does position:relative; appear to change the z-index?
Asked Answered
D

3

9

So I have this markup and inside it there is <div class="mask"></div> which sets the blue overlay ontop of the image.

If I don't make the .container position:relative, the title text gets hidden behind the blue layer... Almost as if it's usage is mimicking z-index

Why is this the case?

Pen: https://codepen.io/anon/pen/OBbbZB

body {
  margin: 0;
  font-family: arial;
}
section {
  position: relative;
  background: url(https://preview.webpixels.io/boomerang-v3.6.1/assets/images/backgrounds/slider/img-41.jpg)
    no-repeat left center/cover;
  height: 70vh;
  display: flex;
  justify-content: center;
}
.container {
  position: relative;
  width: 100%;
  max-width: 1280px;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
}
.mask {
  position: absolute;
  width: 100%;
  height: 100%;
  background: #3452ff;
  opacity: 0.7;
}
<section>
  <div class="mask"></div>
  <div class="container">
    <h1>Hello World</h1>
  </div>
</section>
Deck answered 8/10, 2018 at 2:13 Comment(0)
L
11

You need to refer to the specification and more precisely the painting order to understand when each layer is painted.

Without position:relative your element is not positioned and will be painted at the step (4):

  1. For all its in-flow, non-positioned, block-level descendants in tree order: If the element is a block, list-item, or other block equivalent:

Then we paint the positioned elements (including the .mask) at the step (8)

  1. All positioned, opacity or transform descendants, in tree order that fall into the following categories

Now when you add position:relative you make the container also positioned thus it will fall in the step (8) too and as described there we consider the tree order since both don't have any z-index specified. So the .container will painted later in this case.

If you change the order of the element (you make the container before the mask) you will notice that position:relative won't have any effect because in both cases the painting order will be the same:

body {
  margin: 0;
  font-family: arial;
}
section {
  position: relative;
  background: url(https://preview.webpixels.io/boomerang-v3.6.1/assets/images/backgrounds/slider/img-41.jpg)
    no-repeat left center/cover;
  height: 70vh;
  display: flex;
  justify-content: center;
}
.container {
  position: relative; /* you can remove this*/
  width: 100%;
  max-width: 1280px;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
}
.mask {
  position: absolute;
  width: 100%;
  height: 100%;
  background: #3452ff;
  opacity: 0.7;
}
<section>
  <div class="container">
    <h1>Hello World</h1>
  </div>
  <div class="mask"></div>
</section>

If we check the step (8) it also said opacity or transform which means that if you also change the opacity of the container or add a transform, the order will change too.

body {
  margin: 0;
  font-family: arial;
}
section {
  position: relative;
  background: url(https://preview.webpixels.io/boomerang-v3.6.1/assets/images/backgrounds/slider/img-41.jpg)
    no-repeat left center/cover;
  height: 70vh;
  display: flex;
  justify-content: center;
}
.container {
  transform:translate(0); /*added this*/
  width: 100%;
  max-width: 1280px;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
}
.mask {
  position: absolute;
  width: 100%;
  height: 100%;
  background: #3452ff;
  opacity: 0.7;
}
<section>
  <div class="mask"></div>
  <div class="container">
    <h1>Hello World</h1>
  </div>
</section>

It's also trivial to notice that if you add z-index (either negative or positive) you will also affect the painting order and in this case the tree order will have no effect.

  1. Stacking contexts formed by positioned descendants with negative z-indices (excluding 0) in z-index order (most negative first) then tree order

....

  1. Stacking contexts formed by positioned descendants with z-indices greater than or equal to 1 in z-index order (smallest first) then tree order.

We paint the element with negative z-index at (3) and the positive ones at (9) and between those steps we have all the cases where z-index is not involved like described initially.

Leavenworth answered 8/10, 2018 at 9:1 Comment(2)
Is painting order different stacking context? I understand what happens due to stacking context but this whole painting order goes over my head.Deck
@AshleyBrown yes they are different, stacking context is a small part of the painting order. As you can see stacking context is involved there and used to define painting order ... so when you create a stacking context it's like you force all the element inside to be painted together then the result will be painted considering an upper stacking context.Leavenworth
M
0

This is a fascinating question. It appears that when the .mask div is made absolute and taken out of the document flow, it's the positions that are affected, but the stacking order of the elements is still in place. So an element placed before the absolute div appears under the div, and an element placed after the absolute div is stacked after.

This isn't really an answer, I just wanted to demo what I looked at:

body {
  margin: 0;
  font-family: arial;
}

section {
  position: relative;
  background: url(https://preview.webpixels.io/boomerang-v3.6.1/assets/images/backgrounds/slider/img-41.jpg) no-repeat left center/cover;
  height: 70vh;
  display: flex;
  justify-content: center;
}

.container0 {
  width: 100%;
  max-width: 1280px;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
}

.container {
  position: relative;
  width: 100%;
  max-width: 1280px;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
}

.mask {
  position: absolute;
  width: 100%;
  height: 100%;
  background: #3452ff;
  opacity: 0.7;
}
<section>
  <div class="container0">
    <h1>Another Hello World</h1>
  </div>
  <div class="mask"></div>
  <div class="container">
    <h1>Hello World</h1>
  </div>
</section>
Moorefield answered 8/10, 2018 at 2:30 Comment(3)
there is no fascinating, this is by design and well explained in the specification ;)Leavenworth
@TemaniAfif I think people are allowed to have their own opinion because after all, it is but that - a personal opinion.Deck
@AshleyBrown but SO is not about opinion :) we all have opinions/thoughts but it's not the place to share them. I am not against them and of course everyone is free. I simply commented to explain that this not a suprise if it happens, it's defined in the Spec and I think it's good if he understand it ... I myself found a lot of suprising things and I learned them.Leavenworth
K
-1

Simply a position relative except a position absolute to be relative to. the position fixed is already relative to the viewport.

Knighten answered 24/1 at 12:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.