Artículo original publicado en A list apart, 15 junio 2004 -No. 183
Traducido con el permiso de A List Apart Magazine y del autor.
Hace poco tuve que enfrentarme a la tarea de crear una composición de página líquida de dos columnas con un cabecera y pie de página en los que el contenido tenía que aparecer antes que la barra lateral en el código fuente. Tuve la oportunidad de demostrar un aspecto infrautilizado de las hojas de estilo en cascada (CSS en adelante): los márgenes negativos. Los márgenes negativos nos permiten ubicar el área del contenido lejos de los bordes del navegador, dejando sitio para la barra lateral.
Para mostrar cómo los márgenes negativos pueden ser útiles para crear composiciones de página líquidas, comenzaremos con una composición de dos columnas con cabecera y pie de página. El área principal de contenido estará a la izquierda, con la barra lateral a la derecha. Esto sería normalmente un proceso muy sencillo, pero estamos cambiando las cosas un poco porque queremos que nuestro código fuente esté estructurado de un cierto modo.
Dada la forma en que funciona en CSS el flujo de flotación, sería más fácil poner en el código fuente la barra lateral antes que el área de contenido, permitiendo así a esta barra lateral que flote a la derecha. Sin embargo, como es preferible que el contenido de la página venga antes que la barra lateral en los navegadores de texto, lectores de pantalla y navegadores antiguos que no muestren nuestros estilos, buscamos una solución que nos permita que el contenido esté antes en el código fuente ?y que funcione en la inmensa mayoría de los navegadores.
Echemos un vistazo al código fuente que buscamos para una composición de página de dos columnas, con cabecera y pie de página:
<div id="contenedor">
<h1>Contenido</h1>
<p>Lorem ipsum dolor sit amet,
consectetuer adipiscing elit.
Phasellus varius eleifend.</p>
<p class="ultimoparrafo">Donec euismod.
Praesent mauris mi, adipiscing non,
mollis eget, adipiscing ac, erat.
Integer nonummy mauris sit.</p>
</div>
<div id="barralateral">
<h1>barra lateral</h1>
<ul>
<li>enlace uno</li>
<li>enlace dos</li>
</ul>
</div>
<div id="piedepagina">Pie de página</div>
Mire el ejemplo 1 para ver el aspecto que tendría el contenido sin aplicar estilos. Una vez que lo haya visto, será obvio por qué buscamos que el contenido venga antes que la barra lateral, ya que los navegadores que no leen correctamente nuestras hojas de estilo lo mostrarán de esta forma.
Sabemos que necesitamos que el área de contenido de la izquierda adopte toda la anchura disponible, menos el espacio que necesita la barra lateral de la derecha. Por tanto, ¿qué tal si pudiéramos especificar nuestra anchura como el 100% -200px? Usando los márgenes negativos, podemos crear justamente ese efecto. ¡En realidad, no!
Destripemos el código CSS que necesitaremos para conseguir nuestro objetivo. Como hemos prometido, vamos a configurar la anchura de nuestra capa “contenedor” al 100%, flotando a la izquierda, y dándole un margen negativo a la derecha de -200px. Es muy importante que hagamos flotar este elemento, ya que los márgenes (y, por tanto, los márgenes negativos) se manipulan de manera diferente si se trata de elementos en flotación o en línea o bien si se trata de elementos no flotados o de nivel de bloque (o párrafo).
El margen negativo derecho tiene más que ver con permitir a la barra lateral flotar hacia arriba en el espacio que deja libre este elemento, que con cualquier elemento de posicionamiento/apariencia por sí mismo, como se puede comprobar en el ejemplo 2, más abajo. Hacemos flotar nuestra barra lateral a la derecha, y configuramos su anchura en los 200px que justamente hemos creado para ella. Finalmente, damos a nuestro <div> de pie de página un estilo clear: both para garantizar que permanece debajo del resto de nuestro contenido, independientemente de qué lado sea más largo. También daremos a nuestra cabecera y pie de página colores de fondo para distinguirlos del resto de la página.
#cabecera {
background: #d7dabd;
}
#contenedor {
width: 100%;
float: left;
margin-right: -200px;
}
#barralateral {
width: 200px;
float: right;
}
#piedepagina {
background: #d7dabd;
clear: both;
}
Este CSS nos dará los resultados del ejemplo 2. Como se puede ver, todavía necesitamos empujar el área del contenido fuera de la parte derecha del documento. Hemos decidido utilizar otra <div> para hacer esto, ya que el soporte de los navegadores será mejor para este método que el que hay para otras alternativas. Por tanto, cambiamos nuestro XHTML para que sea como este:
<div id="contenedor">
<div id="contenido">
<h1>contenido</h1>
<p>Lorem ipsum dolor sit amet,
consectetuer adipiscing elit.
Phasellus varius eleifend.</p>
<p class="ultimoparrafo">Donec euismod.
Praesent mauris mi, adipiscing non,
mollis eget, adipiscing ac, erat.
Integer nonummy mauris sit.</p>
</div>
</div>
Ahora añadimos un margen negativo y un color de fondo a la capa de contenido, que debemos poner justo donde necesitamos, separada de la barra lateral.
#contenido {
background: #f1f2ea;
margin-right: 200px;
}
Saliéndolos un poco de los ejemplos visuales, vamos a intentar resolver otro problema. Necesitamos configurar el primer elemento en nuestra capa de contenido, para no tener margen superior y que el último elemento no tenga margen inferior. En nuestro caso, simplemente vamos a fijar el margin-top (margen superior) del elemento h1 en 0, y creamos una regla CSS class para el último párrafo de nuestra capa de contenido, que tendrá fijado el margin-bottom en 0. Ahora que ya lo tenemos, estamos listos para ver el ejemplo 3.
Esto ya está mejorando, pero, por supuesto, se habrá dado cuenta de que la barra lateral de la derecha no se extiende hasta la parte de abajo. Gracias al truquito de usar imágenes como fondo, como nos enseña Dan Cederholm en su artículo “Faux Columns” (columnas postizas), podemos solucionar fácilmente este problema.
Primero, creamos la imagen de más abajo. Tiene 200 píxeles de anchura porque su anchura debe corresponderse con la de nuestra barra lateral.
![]()
Para poner en marcha el truco de Dan, añadimos una capa que envuelva las capas de nuestro contenedor y barra lateral, y también añadimos una nueva capa con la instrucción clear: both justo debajo de ellas. Nuestro XHTML ahora será como sigue:
<div id="envoltorio">
<div id="contenedor">
<div id="contenido">
<h1>Contenido</h1>
<p>Lorem ipsum dolor sit amet,
consectetuer adipiscing elit.
Phasellus varius eleifend.</p>
<p class="ultimoparrafo">Donec euismod.
Praesent mauris mi, adipiscing non,
mollis eget, adipiscing ac, erat.
Integer nonummy mauris sit.</p>
</div>
</div>
<div id="barralateral">
<h1>Barra lateral</h1>
<ul>
<li>Enlace uno</li>
<li>Enlace dos</li>
</ul>
</div>
<div class="despejador"> </div>
</div>
Ahora que ya lo hemos hecho, podemos añadir el fondo a la capa que hace de envoltorio. Hemos configurado el fondo para que se repita en vertical (repeat-y) y situado a la derecha. Para solucionar un error de Internet Explorer, también necesitamos añadir el mismo fondo a nuestra >div> contenedor.
#envoltorio {
background:
#f1f2ea url(background.gif) repeat-y right;
}
#contenedor {
width: 100%;
background:
#f1f2ea url(background.gif) repeat-y right;
float: left;
margin-right: -200px;
}
También configuramos los estilos para nuestra capa que hace el papel de “despejador”, para asegurar que el pie de página caerá bajo las dos columnas y que se vea todo correctamente
.despejador {
height: 0;
clear: both;
}
Esto nos dará una bonita composición de página de dos columnas líquidas que se degrada muy bien en ausencia de CSS. Fíjese en el ejemplo 4. Simplemente añadiendo algunos bordes y relleno (padding) a los elementos, se puede conseguir un esbozo de composición de página líquido de dos columnas. Por supuesto, si hubiéramos querido la barra lateral a la derecha, simplemente tendríamos que haber cambiado los valores del atributo float y los márgenes a sus opuestos. Donde veamos float: left, lo cambiaríamos por float:right, donde veamos un margin-right: 200px, lo cambiaríamos a margin-left: 200px, y así.
Pero ¿qué pasa si pudiéramos incluso adaptar esta composición de página para el caso de tres columnas con un área fluida de contenido? No sólo podemos hacerlo, sino que es sorprendentemente fácil. Necesitaremos que hacer unos pocos cambios a nuestro XHTML para añadirle algunas capas más, y después ya estaremos listos para escribir un poco más de CSS.
<div id="envoltorio_exterior">
<div id="envoltorio">
<div id="contenedor">
<div id="contenido">
<div id="izquierda">
<h1>Barra
de navegación</h1>
<ul>
<li>Enlace uno</li>
<li>Enlace dos</li>
</ul>
</div>
<div id="principal">
<h1>Contenido</h1>
<p>Lorem
ipsum dolor sit amet,
consectetuer
adipiscing elit.
Phasellus varius
eleifend.</p>
<p
class="ultimoparrafo">Donec euismod.
Praesent mauris
mi, adipiscing non,
mollis eget,
adipiscing ac, erat.
Integer nonummy
mauris sit.</p>
</div>
</div>
</div>
<div id="barralateral">
<h1>Barra lateral</h1>
<p>Aquí va la barra
lateral.
Cualquier contenido que se
quiera.</p>
</div>
<div class="despejador"> </div>
</div>
</div>
Otra vez, como queremos que todas nuestras columnas tengan la misma altura, vamos a crear más “columnas postizas”. Hemos creado las dos imágenes siguientes:
![]()
![]()
Como puede verse en el XHTML de más arriba, hemos añadido otra capa de envoltorio además de la barra lateral de la izquierda, y otra capa alrededor del contenido del medio. Nuestra nueva capa de envoltorio, contendrá la imagen de fondo de nuestra nueva columna, situada a la izquierda y repetida verticalmente hasta el final de la capa. Además, hemos eliminado el fondo de la capa de contenido, y añadiremos ahora el color de fondo deseado a nuestra capa “envoltorio_exterior”.
#envoltorio_exterior {
background: #fff url(background_3.gif) repeat-y left;
}
#envoltorio {
background: url(background_2.gif) repeat-y right;
}
El fondo blanco mostrará dónde la imagen no se está mostrando, coloreando, así, nuestra columna central. También vamos a añadir fondos a nuestros elementos más internos para evitar algunos feos huecos que aparecen en la mayoría de las versiones de Internet Explorer.
#contenedor {
width: 100%;
float: left;
margin-right: -200px;
background: url(background_2.gif) repeat-y right;
}
#contenido {
margin-right: 200px;
background: url(background_3.gif) repeat-y left;
}
Después añadiremos estas sencillas instrucciones de estilo para usar de Nuevo márgenes para situar nuestras columnas izquierda y central donde tienen que ir.
#principal {
margin-left: 150px;
}
#izquierda {
width: 150px;
float: left;
}
Finalmente, hemos añadido las siguientes instrucciones de estilo a nuestras div de cabecera y pie de página para dar a la composición un aspecto mejor acabado:
border: 1px solid #cecea5;
Eche un vistazo al ejemplo 5 y siéntase libre para mirar el código fuente para comprobarlo en su totalidad.
Por supuesto, usar la regla @import en la publicación final del sitio sería una buena idea para que nuestro trabajo no sea sorprendido con los pantalones bajados en los navegadores más antiguos.
Como se puede comprobar, los márgenes negativos son un aspecto infrautilizado de CSS que facilitan otras opciones a aquellos que quieren controlar el orden de los elementos en el código fuente y a quienes no les importa añadir algunas divs no semánticas para conseguirlo.