El índice z se cancela configurando transformar (rotar)

84

Usando la propiedad de transformación, el índice z se cancela y aparece en el frente. (Al comentar -webkit-transform, z-index funciona correctamente en el siguiente código)

.test {
  width: 150px;
  height: 40px;
  margin: 30px;
  line-height: 40px;
  position: relative;
  background: white;
  -webkit-transform: rotate(10deg);
}

.test:after {
  width: 100px;
  height: 35px;
  content: "";
  position: absolute;
  top: 0;
  right: 2px;
  -webkit-box-shadow: 0 5px 5px #999;
  /* Safari and Chrome */
  -webkit-transform: rotate(3deg);
  /* Safari and Chrome */
  transform: rotate(3deg);
  z-index: -1;
}
<html>

<head>
  <title>transform</title>
  <link rel="stylesheet" type="text/css" href="transformtest.css">
</head>

<body>
  <div class="test">z-index is canceled.</div>
</body>

</html>

¿Cómo funcionan la transformación y el índice z juntos?

kbth
fuente
Este es el violín que hice, ¿Quieres ocultar el texto con el índice z?
Surjith SM
Funcionando bien jsfiddle.net/raunakkathuria/8MQkP ¿cuál es la duda en realidad?
Raunak Kathuria
Gracias por hacer violín. Quiero mostrar la sombra detrás del rectángulo de texto (como un post-it).
2013

Respuestas:

140

Repasemos lo que está ocurriendo. Para empezar, tenga z-indexen cuenta que en elementos posicionados y transformpor sí mismo crea nuevos " contextos de apilamiento " en elementos. Esto es lo que está pasando:

Su .testelemento se ha transformestablecido en algo diferente a ninguno, lo que le da su propio contexto de apilamiento.

Luego agrega un .test:afterpseudo-elemento, que es hijo de .test. Este hijo tiene z-index: -1, establecer el nivel de pila .test:after dentro del contexto de apilamiento de.test Setting z-index: -1on .test:afterno lo coloca detrás .testporque z-indexsolo tiene significado dentro de un contexto de apilamiento dado.

Cuando eliminas -webkit-transformde .testél, se elimina su contexto de apilamiento, lo que provoca .testy .test:aftercomparte un contexto de apilamiento (el de <html>) y hace que se .test:afterquede atrás .test. Tenga en cuenta que después de eliminar .testla -webkit-transformregla puede, una vez más, darle su propio contexto de apilamiento estableciendo una nueva z-indexregla (cualquier valor) en .test(nuevamente, porque está posicionada).

Entonces, ¿cómo resolvemos tu problema?

Para obtener z-index de trabajo de la forma esperada, asegúrese de que .testy .test:aftercompartir el mismo contexto de pila. El problema es que desea .testrotar con transform, pero hacerlo significa crear su propio contexto de apilamiento. Afortunadamente, colocarlo .testen un contenedor de envoltura y rotarlo permitirá que sus hijos compartan un contexto de apilamiento al mismo tiempo que rotan ambos.

  • Esto es lo que empezó con: http://jsfiddle.net/fH64Q/

  • Y aquí hay una forma en que puede sortear los contextos de apilamiento y mantener la rotación (tenga en cuenta que la sombra se corta un poco debido al .testfondo blanco):

.wrapper {
    -webkit-transform: rotate(10deg);
}
.test {
       width: 150px;
       height: 40px;
       margin: 30px;
       line-height: 40px;
       position: relative;
       background: white;
}
.test:after {
       width: 100px;
       height: 35px;
       content: "";
       position: absolute;
       top: 0;
       right: 2px;
       -webkit-box-shadow: 0 5px 5px #999; /* Safari and Chrome */
       -webkit-transform: rotate(3deg); /* Safari and Chrome */
       transform: rotate(3deg);
       z-index: -1;
}
<div class="wrapper">
    <div class="test">z-index is canceled.</div>
</div>

Hay otras formas de hacer esto, incluso mejores formas. Probablemente haría del fondo "post-it" el elemento que lo contiene y luego pondría el texto dentro, que probablemente sería el método más fácil y reduciría la complejidad de lo que tienes.

Consulte este artículo para obtener más detalles sobre el z-indexorden de apilamiento, o la especificación W3C CSS3 de trabajo sobre el contexto de apilamiento

Lochlan
fuente
4
Esta fue una gran explicación de uno de los aspectos más complejos del diseño CSS. Para lectura futura, consulte la especificación W3
AndyBean
11

Establezca el div que desea permanecer en la parte superior position:relative

AGrush
fuente
1
Funcionó para mí. ¿Está relacionado con el contexto de pilas mencionado anteriormente? Si alguien puede ayudar a aclararlo será muy apreciado.
glihm
7

Tuve un problema similar en el que los hermanos estaban siendo transform: translate()maltratados y z-indexno trabajaban.

La solución más sencilla es establecer position: relativeen todos los hermanos, luego z-indexfuncionaría nuevamente.

buscador_de_bacon
fuente
5

Solución rápida: también puede girar el otro elemento 0 grados.

Chico
fuente
Esto funcionó para mí en un caso en el que no pude rotar el contenedor
Daniel Flippance
1
Tenía un problema extraño con el índice z que no se observaba, y luego la aplicación del estilo lo transform:rotate(0.0rad)solucionó. No pude aplicarlo a través de una regla css, tenía que estar directamente en el elemento. Esto NO tiene sentido, pero gracias por publicar la respuesta que me hizo intentarlo.
Andrew Shepherd
1

Estaba enfrentando un problema similar. Lo que hice fue agregar un div contenedor alrededor de la prueba y le di la propiedad de transformación al div contenedor.

.wrapper{
    transform: rotate(10deg);
}

aquí está el violín http://jsfiddle.net/KmnF2/16/

Ankur Sahu
fuente
-1

Establezca el div que desea permanecer en la parte superior en la posición: absoluta


fuente