Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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>
like image 434
ProEvilz Avatar asked Oct 08 '18 02:10

ProEvilz


1 Answers

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.

like image 194
Temani Afif Avatar answered Sep 28 '22 01:09

Temani Afif