5.1.1.

15 marzo 2005

3 columnas iguales con position: absolute

Categorí­a

Cierta persona me consultó hace poco sobre cómo hacer un esquema de 3 columnas y el problema en particular que tenía usando position: absolute.

Probe con position: absolute y dandole el margen a la izquierda anda bien, sólo que el fondo no se estira junto con el contenido, y queda para la mierda…

Este problema era bastante esperable. Una caja con posicionamiento absoluto es explícitamente desplazada con respecto a su bloque de contención (Posicionamiento absoluto). Dicho de otra manera, la caja que tiene declarado position: absolute deja de existir para su bloque de contención (el que contiene al elemento), por lo que este segundo no está obligado a estirarse para contenerlo. Para colmo viejos trucos como clear: both no funcionan para este tipo de situaciones.

Posiblemente lo que voy a comentar ya aparezca en otro tutorial (en inglés) pero no es mi proposito comentar ésto como una novedad sino como un ejemplo de imaginación y de poder aprovechar los elementos disponibles.

¿Por qué position: absolute en lugar de float?

Todo está en el orden que tienen las secciones (de contenido) en el código. Para una mejor indexación y mejor experiencia cuando las hojas de estilo están desactivas se recomienda incluir primero el contenido más importante del sitio, seguido por aquellos en orden de importancia decreciente.

Supongamos que el proyecto incluye 3 secciones lo bastante largas como para merecer una columna: una que enlace las diferentes secciones del sitio, una segunda con el contenido principal, y una tercera con contenido secundario. Siguiendo los consejos sobre el orden del código, tendríamos lo siguiente:

<div>
 Contenido principal
</div>
<div>
 Contenido secundario
</div>
<div>
 Menú
</div>

La intención es poder ubicar el contenido secundario a la izquierda, el contenido principal en el centro y el menú a la derecha. A los fines de un más fácil seguimiento a los DIV de cada sección se les definirá un id con un valor izquierda, centro y derecha respectivamente.

<div id="centro">

 Contenido principal
</div>
<div id="izquierda">
 Contenido secundario
</div>
<div id="derecha">
 Menú
</div>

Si usaramos float saltarían dos problemas sin solución:

  1. No existe un valor center para poder ubicar el DIV central.
  2. Un elemento flotante se ubica siempre después de los elementos que lo preceden. Aunque el DIV central les hiciera lugar, los DIVs flotantes de los costados no pueden magicamente elevarse para alinearse con éste.

Solución: la libertad de position: absolute.

El secreto mejor guardado de position: absolute

Normalmente una caja es posicionada absolutamente con respecto al elemento BODY en lugar de su bloque contenedor. El truco es que este último esté definido como position: relative. Entonces incluiremos un cuarto DIV que contenga a los otros tres (y permita centrarlos más facilmente).

<div id="contenedor">
 <div id="centro">
  Contenido principal
 </div>
 <div id="izquierda">
  Contenido secundario
 </div>
 <div id="derecha">

  Menú
 </div>
</div>

Definiendo las posiciones con CSS

Por cuestiones de limitacies en el truco, hay que recurrir a un ancho fijo para el elemento contenedor.

#contenedor {
 position:relative;
 width:600px;
 margin:auto;
}

Cada columna tendrá las siguientes medidas:

#centro
300px
#izquierda
200px
#derecha
100px

Para la columna central alcanza con que su ancho no se extienda tanto como para quedar tapada por las siguientes. Definiremos un margen de 200px a la izquierda y de 100px a la derecha para dejar lugar a las siguientes secciones.

#centro {
 width: 300px;
 margin-left: 200px;
 margin-right: 100px;
}

Ahora ubicaremos absolumente las dos columnas siguientes:

#izquierda {
 width: 200px;
 position: absolute;
 top:0px;
 left:0px;
}

#derecha {
 width:100px;
 position:absolute;
 top:0px;
 right:500px;
}

El esquema para este momento debería verse igual que el ejemplo 1.

Finalmente la solución: Aplicando un fondo

Para lograr el efecto de columnas igual habrá que usar una imagen de fondo. Crearemos una de 600px de ancho por 1px de alto coloreada según lo que se vé en el ejemplo 1 —100px desde la izquierda de color #CC0, 200px desde la derecha de color #0CC y el resto en el centro de color #0C0. Imagen de fondo.

El problema es a qué elemento aplicarle este fondo. Una solución sería aplicarla al DIV contenedor que tiene la obligación de extenderse tanto como sea necesario para contener a la columna central. El problema es que la columna central siempre debería ser más larga que sus adyacentes. Solución descartada por no ser infalible.

El truco es simple: el fondo aplicado al elemento body se extenderá siempre hasta contener todos los elementos de la página. Aplicaremos la imagen de la siguiente forma:

body {
 background-image:url(fondo.gif);
 background-position:top center; /* para que se muestre centrada como la columna contenedora */
 background-repeat: repeat-y; /* sólo debe repetirse verticalmente */
}

Pueden ver el ejemplo 2.

Aplicando una cabecera y un pie de página

Aplicar una cabecera es una tarea muy fácil. El DIV contenedor nunca fue removido de su lugar, por lo que sigue estando afectado por los elementos que lo rodean. Si hay un elemento de tipo bloque antes del DIV contenedor, éste último se ubicará debajo sin mayores complicaciones.

<div id="cabecera">

 <h1>Título de la página</h1>
</div>
<div id="contenedor">
 (las tres columnas irían aquí)
</div>

Es recomendable especificar un fondo a la cabecera para que tape el fondo de 3 columnas. Ejemplo 3.

El asunto del pie de página no es tan sencillo. El DIV contenedor crece con la columa central, no con los elementos posicionados absolutamente, por lo que se vuelve imposible (con CSS) controlar que el pie de página se ubique justo debajo de todas las columnas. Una solución sería ubicarlo también absolutamente en el borde inferior de la página pero habría que controlar muy minuciosamente su altura para que no tape el contenido de las demás. La solución más segura es crear otra caja con las mismas propiedades que la columna central, pero ni así sería suficiente. Ejemplo 4.

Conclusión

Pues no debería haber mayor problema entre navegadores. El único que se quejaría sería Internet Explorer 5 pero por problemas ajenos a este tutorial.

Pequeño descargo: quienes conocen demasiado de CSS notarán un pequeño desliz en el código pero dada la simpleza de la intención y la compatibilidad los ejemplos propuestos son suficientes.

Powered by Blogger