0

Browser: Chrome Version 71.0.3578.98 (64-bit)

I'm trying to create an easy way to set an opaque image on a background without editing the image in Photoshop, but when I use an absolutely positioned ::before pseudo-class, inside of a position: relative; parent, it blocks the inputs within the section preventing anyone from using them; although the background image displays behind the parents children's. When I noticed this, I tried setting the ::before to z-index: 0; and the parent to z-index: 1; and it didn't solve the problem. However, when I set the parent to z-index: 0; and the pseudo-class to z-index: -1; it works perfectly.

Why does it have to be z-index 0 and -1 instead of the former?

/* z-index: -1 commented out in .box:before */

.box {
  position: relative;
  z-index: 0;
  text-align: center;
  padding: 20px;
}

.box:before {
  content: "";
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: #dddddd;
  //z-index: -1;
  opacity: .5;
}
<div class="box">
  <b>Click Input</b><br /><br />
 <input type="text" class="text">
</div>
Blake Bell
  • 376
  • 5
  • 16

1 Answers1

1

It's all about painting order. The pseudo element is a positionned element thus it will be painted after the content that is not positionned (step (4) then step (8)). Note that initially both have z-index set to auto. Now if you add z-index to the pseudo element, you will either print it in the step (3) if you set a negative value or step (9) if you set a positive value thus you need a negative z-index to paint the pseudo element before the content.

Concerning the parent element, setting its z-index will create a stacking constext making all the element inside it to be painted considering that stacking context and not another one (step (8.1))

.box {
  position: relative;
  z-index: 0; /*remove this to see the difference*/
  text-align: center;
  padding: 20px;
  background:red;
}

.box:before {
  content: "";
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: #dddddd;
  z-index: -1;
  opacity: .5;
}
<div class="box">
  <b>Click Input</b><br>
 <input type="text" class="text">
</div>

As you can see, I have added a background to the parent element and if you remove the z-index this background will cover the pseudo element. In this case, the pseudo element is painted considering the same stacking context as the parent element and since it has a negative z-index it will be painted before.

Temani Afif
  • 245,468
  • 26
  • 309
  • 415