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?


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


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


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.


5

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


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/


-1

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.