CSS Display table: maquetación como tablas y solución para IE7



Una de las cosas que todos hemos hecho cuando empezábamos a curiosear con la maquetación web es usar tablas por todos lados, algo desaconsejado.

Pero naturalmente es tan cómodo: quiero algo a dos columnas, pues dos celdas; tengo alineación vertical del contenido; ajuste del ancho según contenido; puedo hacer que una celda ocupe varias filas y/o columnas para hacer casi cualquier maquetación basada en celdas. Pero semánticamente es incorrecto usar tablas para algo que no sean datos tabulados. Así que este tipo de maquetación estaba prohibida.... hasta ahora.



O no tan ahora, ya hace varias generaciones que los navegadores soportan dar funcionalidad de tabla a algo que no lo es. Como se puede ver en la página siguiente solo tendríamos problemas en Internet Explorer 7 y anteriores:



Con esta propiedad css podemos dar al display del css los valores table, table-row y table-cell correspondientes a tablas, filas; y celdas y tener casi todas las ventajas de una tabla, sin ser una tabla. Lo que no podemos es unir filas o celdas, pero si tendremos la alineación vertical del contenido y la distribución fácil de elementos en columnas, olvidándonos de apaños con floats o inline-block (que tampoco funciona en IE7).

Semánticamente ya no tenemos el problema de trabajar con tablas, pero si sus ventajas para maquetar, es algo aceptado y recomendable, así que se puede usar sin remordimientos. Vamos a ver qué ventajas puede tener respecto a usar floats o inline-block. Partiendo del html-base:

<div class=”comoUnaTabla”>
<div class=”comoUnaFila”>
<div class=”comoUnaCelda”>
blabla
<br/>
blabla
<br/>
blabla
</div>
<div class=”comoUnaCelda”>
<img …./>
</div>
</div>
</div>

Básicamente tenemos dos columnas, una con texto y otra con una imagen. Y las hemos envuelto en divs de fila y tabla para que podamos ver cada ejemplo con el mismo código html básico.

Si hacemos que comoUnaCelda tenga propiedades:

float:left;
width: 400px;

Funcionará bien en el sentido de tener dos columnas de 400 píxeles, pero los elementos comoUnaFila y comoUnaTabla no tendrán el alto de sus hijos, no se adaptarán al contenido y es fácil que se monte el contenido con otra parte de la web, o que tengamos que usar un div con clear:both.

Si hacemos que el css de comoUnaCelda sea:

display:inline-block;
width:400px;

Entonces veremos que la columna de la derecha está más abajo que la de la izquierda, ya que los br que hemos puesto en la celda izquierda provocan este comportamiento (también pasa con listas). Si damos el siguiente estilado a comoUnaCelda:

display: table-cell;
width: 400px;

Tendríamos 2 columnas de 400px, las dos a la misma altura, sus padres cogerían el alto del contenido de los hijos, y la posibilidad de alineación vertical. Lo que puede tener en nuestra contra es el ajuste automático de ancho en las tablas. Si la imagen de la celda derecha fuera más ancha de los 400px esa celda sería más ancha haciendo más estrecha la izquierda y nos podría trastocar la maquetación.

Al usar table-cell solo, el navegador en realidad crea unos divs anónimos alrededor para la fila y la tabla, es mejor que creemos esos divs nosotros para poder dar posteriormente una solución a los navegadores que no lo soportan. Lo mejor es que usemos las clases “como*” solo para dar el valor display, y pongamos en otra clase o Id otras propiedades concretas como el ancho. Quedaría:

.comoUnaTabla{
display:table;
}

.comoUnaFila{
display:table-row;
}

.comoUnaCelda{
display:table-cell;
}


La solución más sencilla que conozco para que esto funcione en Internet Explorer 7 es poner un trozo de jQuery condicionado:

<!--[if lt IE 8]>
<script>
$(document).ready(function(){
$(".comoUnaCelda").wrap("<td />");
$(".comoUnaFila").wrap("<tr />");
$(".comoUnaTabla").wrapInner("<table />");
});
</script>
<![endif]-->

Así en IE7 tendremos una tabla de verdad, que ya emborrona el html, pero como es para un caso de un navegador en concreto y no el html general de la web (el que validamos) pues no hay tanto problema. Hay que tener en cuenta que al hacer este cambio, las celdas van a sufrir cambios de otras propiedades a los valores por defecto que tienen en una tabla, algo que no pasa con el display: table-cell; Por ejemplo que la alineación vertical sea middle por defecto.

También hay que tener en cuenta que IE7 creará un elemento TBODY entre TABLE y TR, por lo que si en el estilado tenemos una regla de tipo: .comoUnaTabla > .comoUnaFila dejará de funcionar.

Esta solución es la más sencilla que conozco, hay una más compleja, con un fichero htc que se explica en el siguiente enlace: display table htc.