z-index se cancela estableciendo transformar (rotar)


Usando la propiedad transform, z-index se cancela y aparece en el frente. (Al comentar hacia fuera-webkit-transform, z-index está funcionando correctamente en el código de abajo)

.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 juntos transform y z-index?

Author: Lionel, 2013-12-31

3 answers

Caminemos a través de lo que está ocurriendo. Para empezar, tenga en cuenta que z-index en los elementos posicionados y transform por sí mismo crean nuevos "contextos de apilamiento" en los elementos. Esto es lo que está pasando:

Su elemento .test tiene transform establecido en algo que no sea ninguno, lo que le da su propio contexto de apilamiento.

Luego agrega un pseudo-elemento .test:after, que es un hijo de .test. Este hijo tiene z-index: -1, estableciendo el nivel de pila de .test:after dentro del contexto de apilamiento de .test Establecer z-index: -1 en .test:after no lo coloca detrás de .test porque z-index solo tiene significado dentro de un contexto de apilamiento dado.

Cuando elimina -webkit-transform de .test elimina su contexto de apilamiento, haciendo que .test y .test:after compartan un contexto de apilamiento (el de <html>) y haciendo que .test:after vaya detrás de .test. Tenga en cuenta que después de eliminar la regla .test de -webkit-transform puede, una vez más, darle su propio contexto de apilamiento estableciendo una nueva regla z-index (cualquier valor) en .test (de nuevo, porque es posicionado)!

Entonces, ¿cómo resolvemos su problema?

Para que z-index funcione como se espera, asegúrese de que .test y .test:after comparten el mismo contexto de apilamiento. El problema es que desea que .test se gire con transform, pero hacerlo significa crear su propio contexto de apilamiento. Afortunadamente, colocar .test en un contenedor de envoltura y girar que todavía permitirá a sus hijos compartir un contexto de apilamiento mientras también gira ambos.

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

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

.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 maneras de hacer esto, incluso mejores maneras. Probablemente haría el fondo "post-it" el elemento que lo contiene y luego pondría el texto dentro, ese probablemente sería el método más fácil y reduciría la complejidad de lo que tienes.

Echa un vistazo a este artículo para obtener más detalles sobre z-index y el orden de apilamiento, o la especificación de trabajo de W3C CSS3 sobre el contexto de apilamiento

 92
Author: Lochlan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-12 16:28:24

Me enfrentaba al mismo problema. Lo que hice fue, agregué un div de envoltura alrededor de la prueba y le di la propiedad transform al div de envoltura.

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

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

 0
Author: Ankur Sahu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-24 13:04:04

Solución rápida: También puedes rotar el otro elemento en 0 grados.

 0
Author: Guy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-14 16:51:18