Logo de Mosaic
CSS
Posicionamiento absoluto y fijo con CSS

37. Posicionamiento absoluto y fijo con CSS

Tommy Olsson. 26 de septiembre del 2008. Última modificación: 18 de septiembre de 2013 (equipo docente del grado de Multimedia). Publicado en: índice z, apilamiento, recipiente, bloque, continente

Este es el momento de fijarnos en el segundo par de valores de propiedad de position: absolute (absoluto) y fixed (fijo). El primer par de valores: static (estática) y relative (relativo) están íntimamente relacionados, y ya los vimos en el apartado anterior.

Los elementos posicionados absolutamente se eliminan completamente del flujo del documento. Esto significa que no tienen ningún efecto sobre su elemento padre ni sobre los elementos que aparecen después de ellos en el código fuente. Por lo tanto, un elemento posicionado absolutamente se superpondrá sobre otros contenidos a no ser que se tome alguna medida para evitarlo. En ocasiones, por supuesto, esta superposición es exactamente lo que queréis, pero deberíais ser conscientes de ello para aseguraros de que obtenéis la composición que queréis.

El posicionamiento fijo es de hecho una forma especializada del posicionamiento absoluto; los elementos con posicionamiento fijo están fijos en relación con la ventana o viewport del navegador en vez de estarlo en relación con el elemento continente; incluso si se desplaza la página, se mantienen exactamente en la misma posición en la ventana del navegador.

En este apartado os daremos algunos ejemplos prácticos del uso de los posicionamientos absolute y fixed, observaremos algunos pequeños problemas de compatibilidad de navegadores y nos fijaremos en el concepto de índice z.

Pero antes de empezar a hablar de todo esto, trataremos un concepto previo esencial: los bloques contenedores.

Los contenidos de este apartado son los siguientes:

37.1. Bloques contenedores

Un concepto fundamental respecto al posicionamiento absoluto es el bloque contenedor: la caja de bloque respecto a la que se encuentran la posición y las dimensiones de la caja posicionada absolutamente.

Para las cajas estáticas y posicionadas relativamente, la caja contenedora es la antepasada del bloque más próximo o, dicho de otro modo, el elemento padre. No obstante, para los elementos posicionados absolutamente es algo más complicado. En este caso, la caja contenedora es el antepasado posicionado más próximo. Con posicionado nos referimos a un elemento cuya propiedad position está establecida en relative, absolute o fixed, es decir, cualquier cosa excepto elementos estáticos normales.

De manera que, establecer position:relative para un elemento lo convierte en bloque contenedor de cualquier descendiente posicionado absolutamente (elementos hijos), tanto si aparecen inmediatamente debajo del elemento posicionado relativamente en la jerarquía, o más abajo.

Si un elemento posicionado absolutamente no tiene un antepasado posicionado, entonces el bloque contenedor es lo que se llama bloque contenedor inicial, que en la práctica equivale al elemento html. Si estáis mirando la página web en pantalla, se refiere a la ventana del navegador; si vais a imprimir la página, se refiere a los límites de la página.

Los elementos con posicionamiento fijo difieren ligeramente, ya que su bloque contenedor siempre es el bloque contenedor inicial.

Así pues, resumimos en una serie de sencillos pasos; para encontrar el bloque contenedor de un elemento con position:absolute, esto es lo que debéis hacer:

  1. Mirad el elemento padre del elemento posicionado absolutamente: ¿la propiedad position de este elemento tiene uno de los valores relative, absolute o fixed?

  2. Si es así, habéis encontrado el bloque contenedor.

  3. En caso contrario, pasad al elemento padre del padre y empezad de nuevo desde el paso 1 hasta que encontréis el bloque contenedor u os quedéis sin antepasados.

  4. Si habéis llegado al elemento html sin encontrar un antepasado posicionado, entonces el bloque contenedor es el elemento html.

37.2. Posicionamiento absoluto

El posicionamiento fijo es una forma especial de posicionamiento absoluto, de manera que lo estudiaremos más adelante y ahora nos concentraremos en el caso más generalizado. A no ser que se indique lo contrario, cuando utilizamos el término posicionado absolutamente desde ahora hasta el final del apartado, nos estaremos refiriendo tanto a elementos con position:fixed como a elementos con position:absolute.

37.2.1. Especificación de la posición

Con el posicionamiento relativo, habéis aprendido que las propiedades top, right, bottom y left se pueden utilizar para especificar la posición de la caja. Para especificar la posición de una caja posicionada absolutamente se utilizan las mismas propiedades, pero la manera de utilizarlas es bastante diferente.

Para un elemento posicionado relativamente, las cuatro propiedades especifican la distancia relativa para desplazar la caja generada. Recordad que en el caso del posicionamiento relativo se complementan entre sí, de manera que top:1em y bottom:-1em quieren decir lo mismo, y no tiene mucho sentido especificar tanto top como bottom (o left y right) para el mismo elemento porque uno de los valores se ignorará.

Estos puntos no son ciertos en el caso del posicionamiento absoluto. En este caso, se pueden utilizar las cuatro propiedades al mismo tiempo para especificar la distancia desde cada borde del elemento posicionado hasta el borde correspondiente del bloque continente. También se puede especificar la posición de una de las esquinas del cuadro posicionado absolutamente, por ejemplo utilizando top y left, y entonces especificar las dimensiones del cuadro mediante width y height (o simplemente no utilizar width y height si queréis dejar que se ajuste para encajar su contenido).

La versión 6 de Microsoft Internet Explorer (y anteriores) no acepta el método de especificar los cuatro bordes, pero sí el método de especificar una esquina más las dimensiones.

/* Este método funciona en IE6 */
#foo {
   position: absolute;
   top: 3em;
   left: 0;
   width: 30em;
   height: 20em;
}
/* Este método funciona en IE6 */
#foo {
   position: absolute;
   top: 3em;
   right: 0;
   bottom: 3em;
   left: 0;
}

Lo que debéis recordar en este caso es que los valores que habéis establecido para las propiedades top, right, bottom y left especifican las distancias desde los bordes del elemento hasta los bordes de su bloque continente correspondiente. No es como en un sistema de coordenadas donde cada valor es relativo a un punto de origen. Por ejemplo, right:2em significa que el borde derecho del cuadro posicionado absolutamente estará a 2 em del borde derecho del bloque contenedor.

Es absolutamente esencial saber cuál es el bloque contenedor cuando se utiliza el posicionamiento absoluto. Por ello es tan útil configurar position:relative en el bloque contenedor, incluso si no se desplaza realmente la posición del cuadro. Esto permite hacer que un elemento sea el bloque contenedor de sus descendientes posicionados absolutamente, es decir, os proporciona el control.

Probemos un ejemplo para ver cómo funciona.

  1. Copiad el código siguiente en vuestro editor de texto y guardad el documento como absolute.html.

    <!DOCTYPE html>
    <html>
    <head>
       <meta charset="utf-8">
       <title>Absolute Positioning</title>
       <link rel="stylesheet" type="text/css" href="absolute.css">
    </head>
    <body>
       <div id="outer">
          <div id="inner"></div>
       </div>
    </body>
    </html>
  2. A continuación, copiad el código siguiente en un nuevo archivo y guardadlo como absolute.css.

    html, body {
       margin: 0;
       padding: 0;
    }
    #outer {
       margin: 5em;
       border: 1px solid #f00;
    }
    #inner {
       width: 6em;
       height: 4em;
       background-color: #999;
    }
  3. Guardad los dos archivos y cargad el documento HTML en vuestro navegador. Veréis un rectángulo gris rodeado de un marco algo más ancho de color rojo. El elemento #inner tiene una anchura y altura especificadas y un color gris de fondo. El elemento #outer, que es el padre estructural de #inner, tiene un marco rojo. También tiene un margen de 5 em alrededor para alejarlo de los bordes de la ventana del navegador y dejarnos ver más claramente qué es lo que ocurre.

    Nada sorprendente hasta ahora, ¿verdad? La altura del elemento #outer viene dada por su elemento hijo (#inner) y la anchura por los márgenes horizontales.

  4. Mirad qué sucede ahora si hacéis que el elemento #inner esté posicionado absolutamente. Añadid la siguiente línea resaltada en la regla de #inner:

    #inner {
       width: 6em;
       height: 4em;
       background-color: #999;
       position: absolute;
    }
  5. Guardad y recargad. En vez de un marco rojo en torno al rectángulo gris, ahora vemos lo que parece un marco más grueso sólo en la parte superior. Y el cuadro gris no se ha movido en absoluto. ¿Os lo esperabais?

    Pasan dos cosas interesantes aquí: en primer lugar, hacer que #inner esté posicionado absolutamente lo ha eliminado completamente del flujo del documento. Esto significa que su padre, #outer, ahora no tiene hijos que se encuentren en el flujo normal y, por lo tanto, su altura se reduce a cero. Lo que parece una línea roja de 2 píxeles de grueso es realmente un borde de 1 píxel alrededor de un elemento con altura cero: estáis viendo los bordes superiores e inferiores sin nada en medio.

    Lo segundo interesante es que el cuadro posicionado absolutamente no se ha movido. El valor predeterminado para las propiedades top, right, bottom y left es auto, lo que significa que el cuadro posicionado absolutamente aparecerá exactamente donde habría estado si no hubiera sido posicionado. Pero como se ha eliminado del flujo, se superpondrá a cualquier elemento del flujo normal que lo siga.

    Esto es realmente muy útil: podéis utilizarlo si sólo queréis mover un cuadro generado en una dimensión. Por ejemplo, en un menú desplegable de CSS, los paneles "desplegables" se pueden posicionar absolutamente especificando sólo la propiedad top. Entonces aparecerán automáticamente en la coordenada prevista a lo largo del eje X (igual que su padre).

  6. A continuación, establecemos una altura para el elemento #outer de manera que vuelva a parecer un rectángulo y movemos #inner lateralmente. Añadid las siguientes líneas resaltadas a las reglas de CSS:

    #outer {
       margin: 5em;
       border: 1px solid #f00;
       height: 4em;
    }
    #inner {
       width: 6em;
       height: 4em;
       background-color: #999;
       position: absolute;
       left: 1em;
    }
  7. Guardad y recargad y veréis algunos cambios. El elemento #outer ahora es un rectángulo otra vez, ya que le habéis especificado una altura. El elemento #inner se ha desplazado lateralmente, pero no donde se podría esperar encontrarlo. No está a 1 em del borde izquierdo de su padre, sino a 1 em del borde izquierdo de la ventana.

    El motivo es que, como se ha explicado antes, #inner no tiene un antepasado posicionado, de manera que su bloque continente es el bloque continente inicial. Si especificáis una posición diferente de auto, es relativa al borde correspondiente del bloque continente. Cuando habéis establecido left:1em, el borde izquierdo de #inner ha acabado a 1 em del borde izquierdo de la ventana.

  8. Si en vez de esto lo queréis a 1 em del borde izquierdo de su elemento padre, debéis hacer padre al bloque contenedor. Para hacerlo, ahora utilizaréis el truco que hemos mencionado anteriormente en este apartado: hacer que el bloque padre esté posicionado relativamente. Añadid la siguiente línea resaltada a la regla #outer:

    #outer {
       margin: 5em;
       border: 1px solid #f00;
       height: 4em;
       position: relative;
    }
  9. Guardad y recargad: ¡pasen y vean! El rectángulo gris ahora está a 1 em del borde izquierdo del elemento padre. Establecer position:relative en la regla #outer ha hecho que esté posicionado y lo ha establecido como bloque contenedor para cualquier descendiente posicionado relativamente que pueda tener. El left:1em que habéis establecido para #inner ahora cuenta a partir del borde izquierdo de #outer, no del borde izquierdo de la ventana del navegador.

37.2.2. Especificación de las dimensiones

Los elementos posicionados absolutamente se ajustarán para encajar su contenido a no ser que especifiquéis sus dimensiones. Podéis especificar la anchura o bien definiendo las propiedades left y right, o bien definiendo la propiedad width. Podéis especificar la altura definiendo las propiedades top y bottom, o definiendo la propiedad height.

Cualquiera de estas seis propiedades se puede especificar como porcentaje. Los porcentajes son, por su propia naturaleza, relativos a alguna otra cosa. En este caso, son relativos a las dimensiones del bloque contenedor.

Para un elemento posicionado absolutamente, los valores de porcentaje para las propiedades left, right y width son relativos a la anchura del bloque continente. Los valores de porcentaje para las propiedades top, bottom y height son relativos a la altura del bloque continente.

El navegador Internet Explorer 6 y anteriores, y también Opera 8 y anteriores, lo interpretaron de manera totalmente errónea y utilizaron las dimensiones del bloque padre en su lugar. Vamos a probar con otro ejemplo para ver cómo esto puede suponer una gran diferencia.

  1. Empezad especificando las dimensiones de #inner mediante valores de porcentaje; haced los siguientes cambios en la regla #inner:

    #inner {
       width: 50%;
       height: 50%;
       background-color: #999;
       position: absolute;
       left: 1em;
    }
  2. Guardad y recargad, y veréis que el rectángulo gris se hace más ancho y más corto (como mínimo si estáis utilizando un navegador moderno). El bloque continente es todavía #outer porque tiene position:relative. La anchura del elemento #inner ahora es la mitad de la de #outer, y su altura es la mitad de la altura de #outer.

  3. Hacemos que el viewport sea el bloque contenedor una vez más, para ver la diferencia. Haced el siguiente cambio en #outer:

    #outer {
       margin: 5em;
       border: 1px solid #f00;
       height: 4em;
       position: static;
    }
  4. Guardad y recargad; una diferencia notable, ¿verdad? El cuadro gris es ahora la mitad de ancho y la mitad de alto que la ventana del navegador.

Como podéis ver, saber cuáles son vuestros bloques contenedores es absolutamente esencial.

37.2.3. La tercera dimensión: índice Z

Es natural considerar que una página web tiene dos dimensiones. La tecnología no ha evolucionado tanto como para que las pantallas 3D estén generalizadas, de manera que nos debemos conformar con anchura, altura y falsos efectos 3D. Pero la representación CSS realmente se produce en tres dimensiones. Esto no quiere decir que pueda hacer que un elemento vuele delante del monitor (aún), pero puede hacer otras cosas útiles con los elementos posicionados.

Los dos ejes principales de una página web son el eje horizontal X y el eje vertical Y. El origen de este sistema de coordenadas se encuentra en la esquina superior izquierda de la ventana, es decir, donde tanto el valor X como Y son 0.

Pero también hay un eje Z, que podemos imaginar como perpendicular a la superficie del monitor (o del papel, si se trata de una impresión). Los valores Z más altos indican una posición de "delante" de los valores Z más bajos. Los valores Z también pueden ser negativos, y en este caso indican una posición "detrás" de algún punto de referencia (explicaremos este punto de referencia a continuación).

Nota

Antes de continuar, debemos advertiros que éste es uno de los temas más complicados de CSS, así que no os desmoralicéis si no lo entendéis a la primera.

Los elementos posicionados (incluidos los elementos posicionados relativamente) se representan dentro de lo que se conoce como contexto de apilamiento. Los elementos dentro de un contexto de apilamiento tienen el mismo punto de referencia a lo largo del eje Z. A continuación lo explicaremos más detalladamente. Podéis cambiar la posición Z (también denominada nivel de pila) de un elemento posicionado utilizando la propiedad z-index. El valor puede ser un número entero (que puede ser negativo) o una de las palabras clave auto o inherit. El valor predeterminado es auto, lo que quiere decir que el elemento tiene el mismo nivel de pila que su padre.

Debéis tener en cuenta que sólo podéis especificar una posición índice a lo largo del eje Z. No podéis hacer que un elemento aparezca 19 píxeles detrás o 5 centímetros delante de otro. Pensad en eso como si fuera una baraja de cartas: Podéis apilar las cartas y decidir que el as de espadas esté sobre el tres de diamantes; cada carta tiene su nivel de pila, o índice Z.

Si especificáis z-index como un entero positivo, le asignáis un nivel de pila "delante de" el resto de elementos del mismo contexto de apilamiento que tienen un nivel de pila inferior. Un z-index de 0 (zero) significa lo mismo que auto, pero hay una diferencia de la que hablaremos en un momento. Un valor entero negativo para z-index asigna un nivel de pila "detrás de" el nivel de apilamiento padre.

Cuando dos elementos del mismo contexto de apilamiento tienen el mismo nivel de pila, lo que aparece posteriormente al código fuente aparecerá encima de sus hermanos predecesores.

De hecho, no puede haber menos de siete capas en un contexto de apilamiento, y en cada una de estas capas puede haber cualquier número de elementos, pero no os preocupéis: lo más probable es que nunca tengáis que tratar con siete capas en un contexto de apilamiento. El orden en el que los elementos (todos los elementos, no sólo los posicionados) se representan en un contexto de apilamiento, desde detrás hacia adelante, es el siguiente:

  1. El fondo y los bordes de los elementos que forman el contexto de apilamiento.

  2. Descendientes posicionados con niveles de pila negativos.

  3. Descendientes de nivel de bloque en el flujo normal.

  4. Descendientes flotantes.

  5. Descendientes de nivel en línea en el flujo normal.

  6. Descendientes posicionados con el nivel de pila definido como auto o 0 (cero).

  7. Descendientes posicionados con niveles de pila positivos.

Las entradas resaltadas son los elementos con un nivel de pila que se puede cambiar mediante la propiedad z-index.

Todo puede ser bastante difícil de imaginar, de modo que, hagamos algunos experimentos prácticos para ilustrar el índice Z.

  1. Empezad añadiendo la siguiente línea resaltada a vuestro pequeño documento de muestra:

    <body>
       <div id="outer">
          <div id="inner"></div>
          <div id="second"></div>
       </div>
    </body>
  2. A continuación os explicaremos cómo restaurar el CSS de manera que #outer sea el bloque contenedor y cómo establecer dimensiones no porcentuales de #inner. Hagamos que #outer sea un poco más alto, también, para tener más espacio para hacer pruebas. Haced los siguientes cambios resaltados en las dos reglas:

    #outer {
       margin: 5em;
       border: 1px solid #f00;
       height: 8em;
       position: relative;
    }
    #inner {
       width: 5em;
       height: 5em;
       background-color: #999;
       position: absolute;
       left: 1em;
    }
  3. Añadid una regla para el elemento #second, también:

    #second {
       width: 5em;
       height: 5em;
       background-color: #00f;
       position: absolute;
       top: 1em;
       left: 2em;
    }
  4. Guardad y recargad y veréis un cuadro azul brillante que se superpone a uno gris. Ambos cuadros tienen el mismo nivel de pila (auto, el valor inicial, que significa un nivel de pila 0), pero el cuadro azul se representa ante el cuadro gris porque aparece más tarde en el código fuente. Podéis hacer que el cuadro gris aparezca delante asignándole un nivel de pila positivo. Sólo debéis especificar que sea mayor que 0: no hace falta exagerar y utilizar un valor como 10.000. Añadid la siguiente línea resaltada en la regla #inner:

    #inner {
       width: 5em;
       height: 5em;
       background-color: #999;
       position: absolute;
       left: 1em;
       z-index: 1;
    }
  5. Guardad y recargad, y veréis cómo el cuadro gris aparece ante el cuadro azul.

Contextos de apilamiento local

El resto de este subapartado trata de los contextos de apilamiento locales. Muy probablemente, no os encontraréis con eso muy a menudo trabajando como diseñadores, a no ser que intentéis hacer algo realmente avanzado con posicionamiento absoluto, pero hemos decidido incluirlo igualmente por completitud. Si queréis, podéis saltaros esta sección.

Cada elemento que tenga el z-index especificado como un entero establece un contexto de apilamiento nuevo, "local", en el que el propio elemento tiene un nivel de pila 0. Ésta es la diferencia que hemos mencionado antes entre z-index: auto y z-index: 0. El anterior no establece un nuevo contexto de apilamiento, pero el último, sí.

Cuando un elemento establece un contexto de apilamiento local, los niveles de pila de sus descendientes posicionados se aplican sólo en este contexto local. Estos descendientes se pueden volver a apilar los unos respecto a los otros, y respecto a su padre, pero no respecto a los hermanos del padre. Es como si el padre formara una jaula alrededor de sus descendientes de manera que no pueden abandonarla. Los descendientes se pueden mover arriba y abajo en esta jaula, pero no pueden abandonarla. El padre y sus descendientes formarán una unidad indivisible en el contexto de apilamiento que rodea al padre.

Imaginaos que estáis clasificando el papeleo antes de entregarlo al contable que se ocupa de vuestros asuntos fiscales. Tenéis informes de gastos, recibos, confirmaciones de pedidos, etcétera y apiláis un papel encima del otro: para facilitarle la vida a vuestro gestor, introducís los tipos de documentos que van juntos en diferentes sobres.

Un contexto de apilamiento local es parecido a este tipo de sobre. Mantiene los elementos relacionados juntos e impide que otros elementos se mezclen entre ellos. Podéis clasificar el contenido de cada sobre como queráis, pero este orden de clasificación sólo se aplica a este sobre y no afecta a la pila de documentos en conjunto. Vuestra pila contiene ahora una mezcla de documentos independientes (elementos con el nivel de pila auto) y sobres (elementos con un nivel de pila entero). Los sobres con niveles de pila positivos quedan por encima de los documentos independientes, mientras que los sobres con niveles de pila negativos aparecen debajo del todo de la pila.

Cada vez que asignáis un valor entero en la propiedad z-index de un elemento, se crea un "sobre" que contiene este elemento y sus descendientes.

Veamos cómo funcionan estos contextos de apilamiento local. Puede parecer confuso, pero realmente no es muy diferente de todo lo que ya habéis visto. Si seguís los ejemplos, acabaréis haciéndoos una buena idea de cómo funciona todo.

  1. Empezad añadiendo algún contenido a vuestros dos elementos internos; añadid las líneas resaltadas a vuestro documento HTML:

    <div id="inner">
       <span></span>
    </div>
    <div id="second">
       <span></span>
    </div>
  2. Añadid una regla CSS que se aplicará a estos dos elementos span:

    span {
       position: absolute;
       top: 2em;
       left: 2em;
       width: 3em;
       height: 3em;
    }

    Esto hace que los elementos span queden posicionados absolutamente y establece sus posiciones y dimensiones. Pero, un momento, los elementos span son en línea... ¿Cómo se pueden especificar las dimensiones de los elementos en línea? La respuesta es que los elementos posicionados absolutamente, como los elementos flotantes, generan automáticamente cajas de bloque.

    Las posiciones que especificáis se aplicarán con relación al bloque contenedor de cada span. Como ambos elementos span tienen un div posicionado absolutamente como padre, estos padres asumen la función de bloques contenedores.

  3. Añadimos ahora un poco de color a los elementos span para que podáis ver dónde aparecen; añadid las siguientes reglas a vuestra hoja de estilos:

    #inner span {
       background-color: #ff0;
    }
    #second span {
       background-color: #0ff;
    }
    
  4. Guardad y recargad y veréis un cuadrado amarillo en la esquina inferior derecha del cuadrado gris mayor y un cuadrado de color cian en la esquina inferior derecha del cuadrado azul mayor. Los cuadrados gris y amarillo aparecen ante los cuadrados azul y cian porque el cuadrado gris tiene un z-index:1.

  5. ¿Y si queréis que el cuadrado cian quede por delante de todos los otros cuadrados? Todo lo que debéis hacer es aplicarle un nivel de pila más alto que al cuadrado gris. De hecho, basta con darle exactamente el mismo nivel de pila que el cuadrado gris, ya que el cuadrado cian aparece más adelante en el etiquetado. Probémoslo; efectuad el siguiente cambio en vuestro CSS:

    #second span {
       background-color: #0ff;
       z-index: 1;
    }
  6. Guardad y recargad. Si vuestro navegador admite correctamente la recomendación CSS, el cuadrado cian debería estar ahora delante.

El cuadrado gris tiene un z-index:1, que quiere decir que establece un contexto de apilamiento local. En otras palabras, habéis creado uno de estos "sobres" y habéis colocado el cuadrado gris y su cuadrado hijo de color amarillo en el interior.

¿Seguís sin verlo del todo claro? A ver si con el siguiente experimento lo acabamos de aclarar.

  1. Estableced un nivel de pila alto para el cuadrado amarillo para llevarlo adelante; haced el siguiente cambio en vuestro CSS:

    #inner span {
       background-color: #ff0;
       z-index: 4;
    }
  2. Si guardáis y recargáis, veréis... que no ha habido ningún cambio en absoluto. El nivel de pila que hemos especificado para el cuadrado amarillo se aplica en el contexto de apilamiento local establecido por el cuadrado gris, es decir: el cuadrado amarillo se encuentra en un sobre junto con su padre gris. Podríais mover el cuadrado cian hasta adelante porque su padre (el cuadrado azul) no establece un contexto de apilamiento local: tiene un z-index:auto implícito. El cuadrado azul es un papel independiente en la pila. Los cuadrados amarillo y cian están en realidad solos en pequeños sobres individuales (tienen un nivel de pila entero y establecen contextos de apilamiento local por su cuenta).

  3. Si hacéis que el cuadrado azul establezca un contexto de apilamiento local, no podréis mover el cuadrado cian hacia adelante a no ser que también llevéis a su padre (el cuadrado azul) adelante. Probémoslo. Haced los siguientes cambios en vuestro CSS:

    #inner {
    
    ...
    
    z-index: 2;
    }
    #second {
    
       ...
    
       z-index: 1;
    }
    #second span {
    
       ...
    
       z-index: 3;
    }
  4. Guardad y recargad. Ahora, tanto el cuadrado gris como el cuadrado azul establecen contextos de apilamiento local, de manera que se crean dos sobres. En la parte inferior de la pila hay un sobre con el nivel de pila 1 que incluye dos sobres interiores (el cuadrado azul y el cuadrado cian). En la parte superior de la pila hay un sobre con nivel de pila 2 que incluye dos sobres interiores (el cuadrado gris y el cuadrado amarillo). En el primer sobre, el cuadrado azul tiene un nivel de pila local 0 y, por lo tanto, se muestra detrás del cuadrado cian, que tiene un nivel de pila local 3. En el segundo sobre, el cuadrado gris tiene un nivel de pila local 0, de manera que aparece detrás del cuadrado amarillo con nivel de pila local 4.

La figura 1 muestra los cuatro cuadros y los dos contextos de apilamiento local desde el lateral, a lo largo del eje Z.

El cuadro azul está debajo de todo, seguido por el cuadro cian, el gris y el amarillo.

Figura 1. Ilustración de diferentes contextos de apilamiento. Los elementos que aparecen dentro de "2" siempre aparecerán por delante de todos los elementos dentro de "1". Después, dentro de cada contexto de apilamiento, los elementos con un número de índice z mayor aparecen por delante de los elementos con un número de índice z más pequeño. Si dos elementos tienen el mismo número de índice z, lo que aparece más tarde en el etiquetado aparecerá delante.

Esta parte probablemente os haya resultado bastante complicada, especialmente si sois nuevos con CSS. La cuestión es que debéis conocer vuestros contextos de apilamiento si estáis intentando cambiar los niveles de apilamiento de diferentes elementos. Si un elemento pertenece a un contexto de apilamiento local, sólo podéis cambiar su posición a lo largo del eje Z en este contexto local. Un elemento en un contexto de apilamiento local no se puede colar entre dos elementos de otro contexto de apilamiento local.

La buena noticia es que muy probablemente nunca os encontraréis con estos problemas. Los cambios en z-index no son muy comunes en las buenas composiciones, y en caso de que se produzcan, generalmente siempre es en un único contexto de apilamiento.

37.3. Posicionamiento fijo

Un elemento con position:fixed está fijo respecto a la ventana. Se mantiene donde está aunque se desplace el documento. Para media="print" se repetirá un elemento fijo en cada página impresa.

Tened en cuenta que las versiones 6 y anteriores de Internet Explorer no admiten el posicionamiento fijo de ninguna forma. Si utilizáis uno de estos navegadores, no podréis ver los resultados de los ejemplos de este subapartado.

Mientras que la posición y las dimensiones de un elemento con position:absolute son siempre relativas a su bloque continente, la posición y las dimensiones de un elemento con position:fixed son siempre relativas al bloque continente inicial. Este suele ser el viewport: la ventana del navegador o el cuadro de la página impresa.

Para demostrarlo, en el ejemplo siguiente haréis fijo uno de vuestros elementos. Haréis el otro muy alto para que se genere una barra de desplazamiento y así hacer más fácil el efecto que tiene.

  1. Haced los siguientes cambios en vuestro código CSS:

    #inner {
       width: 5em;
       height: 5em;
       background-color: #999;
       position: fixed;
       top: 1em;
       left: 1em;
    }
    #second
       width: 5em;
       height: 150em;
       background-color: #00f;
       position: absolute;
       top: 1em;
       left: 2em;
    }
  2. Guardad y recargad. Si no obtenéis una barra de desplazamiento vertical, aumentad el valor height para #second (pero ¿qué tipo de monitor gigante tenéis?).

El elemento azul alto se alarga más allá de la parte inferior de la ventana. Desplazad la página hacia abajo y observad el cuadrado gris de la esquina superior izquierda. Ahora #inner queda fijo en la posición a 1 em de la parte superior de la ventana y a 1 em del lado izquierdo y, por lo tanto, a medida que os desplacéis, el cuadro gris se quedará en el mismo lugar de la pantalla.

Resumen

Los elementos posicionados absolutamente se eliminan completamente del flujo del documento. Se superpondrán sobre otros contenidos a no ser que les hagáis espacio. Si todos los elementos hijos de un contenedor están posicionados absolutamente, la altura del padre se reducirá a cero.

Los elementos posicionados absolutamente lo están respecto a un bloque contenedor, que es el antepasado posicionado más próximo. Si no hay antepasado posicionado, el viewport será el bloque contenedor.

Los elementos con posicionamiento fijo lo están respecto a la ventana: ésta es siempre su bloque contenedor. Siempre aparecen en el mismo lugar de la ventana del navegador cuando se ven en pantalla; cuando se imprimen, aparecen en cada página.

Las posiciones de cada borde de un elemento posicionado absolutamente se pueden especificar mediante las propiedades top, right, bottom y left. El valor de cada propiedad especifica la distancia de este borde al borde correspondiente del bloque continente del elemento.

Todos los elementos posicionados se representan en un nivel de pila determinado en un contexto de apilamiento. Podéis cambiar el nivel de pila de un elemento posicionado utilizando la propiedad z-index. Cuando se especifica z-index como un valor entero, el elemento establece un contexto de apilamiento local para sus descendientes.

Preguntas de repaso

Preguntas a las que deberíais poder responder:

  1. Deshaced los cambios del ejemplo de posicionamiento fijo y, a continuación, cambiad el orden de apilamiento entre los cuatro cuadrados posicionados absolutamente, de manera que el cuadrado gris esté en la parte de atrás, seguido de los cuadrados azul, amarillo y cian en este orden (consejo: eliminad todas las declaraciones de z-index y empezad de nuevo).

  2. Moved el cuadrado amarillo hacia arriba y a la derecha especificando top:-1em y left:8em. A continuación, haced que aparezca detrás del elemento #outer, de manera que el borde rojo aparezca a través del cuadrado amarillo.

  3. Replicad la disposición de tres columnas que creamos en el apartado de posicionamiento estático y relativo utilizando el posicionamiento absoluto en su lugar. Como será imposible tener un pie de anchura completa, podéis eliminar el elemento #footer, pero no podéis cambiar nada más en el etiquetado (aparte del enlace a la hoja de estilos).

  4. Modificad la disposición del ejercicio anterior para hacer que la navegación utilice el posicionamiento fijo. Deberéis eliminar los márgenes horizontales automáticos del elemento body para hacerlo posible. Añadid bastante contenido a la columna principal y/o la barra lateral para que aparezca una barra de desplazamiento, de manera que podáis verificar que funciona.

Logo Creative Commons
Los contenidos recogidos en este artículo están sujetos a una licencia Creative Commons
Reconocimiento, No comercial - Compartir bajo la misma licencia 3.0 No adaptada
.
: Ir al índice :