Tengo un div semitransparente de color (.box) delante de otros divs (.textDisplay) que contienen texto. Una de estas divisiones de fondo (a la izquierda) se muestra correctamente, con el texto desvanecido debido a la división transparente superpuesta en la parte superior. El otro, sin embargo, no se desvanece en absoluto. Quiero que ambos divs se muestren como el de la izquierda.

EDITAR: no puedo modificar la estructura del HTML (lo genera Elm de forma anidada). ¿Hay alguna manera de hacer esto solo con CSS?

EDIT 2: fue un problema de contexto de apilamiento debido a la propiedad transform. Vea mi respuesta para más detalles.

.textDisplay {
  height: 100%;
  width: 100%;
  text-align: center;
}

.box {
  width: 200px;
  padding: 20px;
  background-color: #8CA8DA;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: 20px;
  transform: translateY(-50%);
  opacity: 0.8;
}

.behind {
  position: absolute;
  transform: translate(-50%, -50%);
}
<div class="behind" style="left: 100px; top: 100px; width: 127px; height: 127px;">
  <div class="content">
    <div>
      <div class="textDisplay">Test Text 0</div>
      <div class="box" style="z-index: 100;">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi molestie ornare ex et cursus. Donec nibh urna, bibendum nec molestie sed, condimentum ut lacus.
      </div>
    </div>
  </div>
</div>
<div class="behind" style="left: 350px; top: 150px; width: 127px; height: 127px;">
  <div class="content">
    <div>
      <div class="textDisplay">Test Text 1</div>
    </div>
  </div>
</div>
0
user2244484 24 dic. 2016 a las 03:37

3 respuestas

La mejor respuesta

La propiedad transform crea un nuevo contexto de apilamiento. Como explica el artículo vinculado, este contexto de apilamiento se incorpora atómicamente (como una cosa ) dentro de su contexto de apilamiento padre. El z-index definido dentro de él no puede trascender el contexto. Hay diagramas que ilustran esto mucho mejor en el artículo.

En lugar de usar transform: translate(-50%, -50%); para centrar, podemos usar left: -50%; top: -50%;, como lo demuestra el fragmento modificado. Tiene que haber un div con el ancho y la altura deseados (.behind) cuya esquina superior izquierda es donde queremos que esté el centro del div objetivo. Vea la clase .content para ver un ejemplo de cómo lograr el centrado del div objetivo.

Una vez que el div está centrado con un método alternativo, todo está en el mismo contexto de apilamiento. Ahora, un simple z-index: 100 en el elemento deseado (o uno de sus elementos secundarios, como en el fragmento) lo elevará por encima del resto, logrando el efecto de transparencia deseado.

.textDisplay {
  height: 100%;
  width: 100%;
  text-align: center;
}

.box {
  width: 200px;
  padding: 20px;
  background-color: #8CA8DA;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: 20px;
  transform: translateY(-50%);
  opacity: 0.8;
}

.content {
  left: -50%;
  top: -50%;
  height: 100%;
  width: 100%;
  position: absolute; /* or relative */
}

.behind {
  position: absolute;
  /*transform: translate(-50%, -50%); REMOVED*/
}
<div class="behind" style="left: 100px; top: 100px; width: 127px; height: 127px;">
  <div class="content">
    <div>
      <div class="textDisplay">Test Text 0</div>
      <div class="box" style="z-index: 100;">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi molestie ornare ex et cursus. Donec nibh urna, bibendum nec molestie sed, condimentum ut lacus.
      </div>
    </div>
  </div>
</div>
<div class="behind" style="left: 350px; top: 150px; width: 127px; height: 127px;">
  <div class="content">
    <div>
      <div class="textDisplay">Test Text 1</div>
    </div>
  </div>
</div>
0
user2244484 28 dic. 2016 a las 18:51

¿Así?

.textDisplay {
  height: 100%;
  width: 100%;
  text-align: center;
}

.box {
  width: 200px;
  padding: 20px;
  background-color: #8CA8DA;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: 20px;
  transform: translateY(-50%);
  opacity: 0.8;
}

.behind {
  position: absolute;
  transform: translate(-50%, -50%);
}
<div class="behind" style="left: 350px; top: 150px; width: 127px; height: 127px;">
  <div class="content">
    <div>
      <div class="textDisplay">Test Text 1</div>
    </div>
  </div>
</div>
<div class="behind" style="left: 100px; top: 100px; width: 127px; height: 127px;">
  <div class="content">
    <div>
      <div class="textDisplay">Test Text 0</div>
      <div class="box" style="z-index: 100;">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi molestie ornare ex et cursus. Donec nibh urna, bibendum nec molestie sed, condimentum ut lacus.
      </div>
    </div>
  </div>
</div>
0
br3t 24 dic. 2016 a las 00:46

Ponga .box fuera de .behind. Modifiqué un poco el CSS para hacer una demostración, pero entenderás la idea.

.textDisplay {
  height: 100%;
  width: 100%;
  text-align: center;
}

.box {
  width: 200px;
  padding: 20px;
  background-color: #8CA8DA;
  position: absolute;
  top: 50%;
  left: 15%;
  margin-left: 20px;
  transform: translateY(-50%);
  opacity: 0.8;
}

.behind {
  position: absolute;
  transform: translate(-50%, -50%);
}
<div class="box" style="z-index: 100;">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi molestie ornare ex et cursus. Donec nibh urna, bibendum nec molestie sed, condimentum ut lacus.
</div>
<div class="behind" style="left: 100px; top: 100px; width: 127px; height: 127px;">
  <div class="content">
    <div>
      <div class="textDisplay">Test Text 0</div>          
    </div>
  </div>
</div>
<div class="behind" style="left: 350px; top: 150px; width: 127px; height: 127px;">
  <div class="content">
    <div>
      <div class="textDisplay">Test Text 1</div>
    </div>
  </div>
</div>
0
Mark Dee 24 dic. 2016 a las 00:46