Z-index en Css: el apilamiento de cajas y sus valores negativos

Una mirada a la propiedad z-index y el comportamiento / significado de los valores negativos declarados en ella.

Z-index en Css: el apilamiento de cajas y sus valores negativos

Por Kseso ✎ 10

Z-index es esa propiedad que nos permite colocar los elementos encima/sobre unos de otros cuando hay superposiciones.

Pero recuerda que por el modelo de cajas de Css, por definición, los elementos del html ocupan su lugar y fuerzan al resto a que lo respeten. Muy educados ellos. Así que para haya solapamientos hay que modificar dicho comportamiento desplazando alguno de ellos.

Lo que dicen las especificaciones es muy sencillo: se aplica a cualquier elemento posicionado (position≠static), los valores posibles admitidos son auto | Nº entero | inherit (por defecto: auto) y que no se hereda.

Aquí surge el primer malentendido. Porque pese a no heredarse, resulta que el elemento con valor z-index crea una "caja" para él y todo su contenido. Así que sus hijos, a efectos del apilamiento, estarán en el mismo nivel de z-index.

El segundo malentendido surge cuando se declaran valores negativos para z-index.

Valores negativos en Z-index

Por muy elevado que sea su valor en negativo no salen de la caja de apilamiento de su padre. Si para el padre z-index vale 10, aunque le asignes un valor de -50 a sus hijos, estos hijos siempre estarán sobre otros elementos hermanos de su padre que tengan un valor menor de 10.

Vamos con un ejemplo y sus códigos:
Tengamos dos familias de div´s, la de D. Antonio y la de D. José, con sus respectivos hijos y nietos:

<div id=DonJose> <div id="SrPepe"> <div id="Pepin"></div> <div id="Pepito"></div> </div> </div> <div id="DonAntonio"> <div id="SrAnton"> <div id=Toni></div> <div id="Tonino"></div> </div> </div>

Le aplicamos el Css correspondiente para que monten unos sobre otros y para poderlos diferenciar le asignamos fondos y bordes. Y ahora aplicamos el z-index:

DonJose {z-index: 5;} SrPepe, Pepin, Pepito {z-index: 25;} DonAntonio {z-index: 6;} SrAnton {z-index: -10;} Tonino {z-index: -100;}

Fíjate bien en los valores de z-index de la familia de DonJose y la de DonAntonio (su hijo SrAnton con -10 y su nieto (Tonino -100). Y este es el resultado, tanto en Firefox, Chrome, IE9, Safari y Opera en Windows:

Efecto del valor de z-index en padres e hijos

DonAntonio y toda su familia se posicionan sobre DonJose y la suya por tener un z-index mayor. Y no importa qué valores se declaren a los hijos y nietos. El valor de los padres mandan. Pese a que SrPepe y sus dos hijos tienen un z-index de 25 y SrAnton y Toni de -10 y Tonino de -100 siguen estando arriba tanto de la familia DonJose como del mismo DonAntonio.

Para el único que influye el z-index -100 de Tonino es para posicionarlo respecto a su hermano Toni. Pese a tener un -100 está sobre toda la familia de DonJose (z-index=5), sobre su abuelo DonAntonio (z-index=6) y su padre SrAnton (z-index=-10).

Dicho de una manera menos familiar, y utilizando la nomenclatura de la especificidad de los selectores, podría decirse que el valor final del z-index está compuesta por cada uno de los valores de sus ancestros y el suyo propio:
DonJose = 5
SrPepe = 5,25
DonAntonio = 6
SrAnton = 6,-10
Tonino = 6,-10,-100

Padres sobre los hijos

Entonces, si quieres que los hijos se coloquen bajo su padre ¿cómo hacer? Sencillo, no declarar z-indez en el padre. Y no declarar es no declarar. Si das un valor cualquiera, incluido el 0, ya crea la caja de apilamiento y coloca a sus hijos dentro.

Y si algún ancestro ya tiene z-index

En el caso que el abuelo tenga declarado un z-index y quieras que los nietos de éste estén sobre su padre (Tonino sobre DonAntonio) te remito al inicio del artículo, a sobre qué elementos aplica el z-index: basta que al padre le declares position: static . Y eureka: hijos con z-index negativo debajo del padre.

Así que si quieres esconder un elemento debajo del body, sólo tienes que aplicarle un valor negativo al elemento y al body no declararle z-index (o que su position sea static). Sin olvidar que el elemento debe ser hijo directo del body o que los ancestros del elemento no tengan z-index.

Z-index y los vídeos

Otro quebradero de cabeza muy frecuente es la mala costumbre de los vídeos de no hacer caso a la propiedad z-index.
Por mucho que declares position y por más z-index que apliques tienen la mala costumbre de ignorarlo y quedar siempre arriba.

La solucción es sencilla, pero en este caso no es vía css, tienes que ir al código html y añadir al objet el atributo v-mode y uno de los dos valores opaque || transparent tal que así:

<objet ... > ... <param name="wmode" value="transparent" /> ... </objet>

Un caso real con el código que suministra youtube:

<iframe width="640" height="480" src="http://www.youtube.com/embed/QbYoIy1taYY" frameborder="0" wmode="transparent" allowfullscreen> </iframe>

Artículo publicado originalmente el 16/05/012 y actualizado el 15/10/2014

Ramajero Argonauta, Enredique Amanuense de CSS.
#impoCSSible inside
Dicen que, en español, EsCss es el mejor blog de CSS. Posíblemente exageren.
@Kseso EsCss Don Kseso Kseso

Comentarios: 10

  1. Yo creo q la única regla para poner a los hijos por debajo del padre es:
    z-index(del hijo) + z-index(del padre) < z-index(del padre), luego poner a los hijos position:relative;, pero no al padre.

    entonces este es mi codigo:

    .padre{z-index:1;}
    .hijo{position:relative; z-index:-2; }

    ResponderEliminar
    Respuestas
    1. Wilson te remito al apartado "Padres sobre los hijos"
      Posíblemente ese código que propones te funcione porque tu .padre pese a tener declarado un z-index no aplica.
      La razón: que su valor para position es static.

      Un saludo

      Eliminar
  2. Muy buen trabajo con los artículos que vas publicando, interesantes e instructivos. Saludos

    ResponderEliminar
  3. Excelente explicación, me sirvió mucho, para poner ventanitas popup con css y que no se vean afectadas por videos, imagenes y/o menus

    ResponderEliminar
  4. Como puedo hacer q un elemento en un contexto de apilamiento menor este por delante de uno de apilamiento mayor, en tu ejemplo seria q un elemento de DonJose e.g (Pepin) este por delante de DonAntonio, por supuesto manteniendo q DonAntonio siga estando por delante de DonJose y el resto de la familia

    ResponderEliminar
    Respuestas
    1. Vaya un galimatías familiar que hemos montado, Yandy

      No declares z-index a los padres. El que quieras que aparezca "encima" (eje Z) que lo haga por aparecer después en el html, así los hijos de ambos tendrán un valor igual en el contexto de apilamiento.
      Al hijo de primero en aparecer un valor mayor en z-index que los hijos del segundo.

      Pero en el momento que un elemento crea una caja de apilamiento, ese valor es la base para todo su contenido.

      Un saludo.

      Eliminar
    2. gracias por la respuesta, pero es q tengo un caso bastante particular donde los padres necesitan tener definidos z-index y no puedo invertirlos el html, por lo q lei creo q esta dificil q Pepin este por encima de DonAntonio pero si te haces con la respuesta te agreadeceria mucho q la compartieras.

      PD: espero q quien lea nuestross comentarios se ubique en el contexto o pensara q tenemos un debate familiar jajaja

      Eliminar
  5. Hola
    Gracias a este artículo he losgrado entender z-index: Lo he aplicado a la web, que tengo en localhost y me ha funcionado. Se lo he puesto a un menú fijo, al principio, luego tengo el logo y un slider en un widget que he creado, porque el tema Olse Ligth, sólo me deajba meter el logo y yo quería los dos.
    Ahora, con esta explicación, el menú está fijo en scroll pero, tanto el logo como el slider se quedan pegados al menú y me gustaría separarlos... ¿podéis ayudarme con esto?
    Gracias.

    ResponderEliminar
    Respuestas
    1. "¿podéis ayudarme con esto?"
      Lo siento pero no. Es imposible por dos razones:

      1ª: Yo no soy adivino
      2ª: Usted no facilita la información mínima necesaria.

      Creo le vendrá bien leer este post.

      Un saludo

      Eliminar

EsCss RSS del Blog RSSS Comentarios Humans.txt ᛯ Diseno por Kseso SiteMap