Como arreglar el modelo de cajas (o IE6 hacía algunas cosas bien)

Los navegadores interpretan el código HTML y acomodan el contenido usando un “modelo de cajas”, es decir, van dibujando cajas de diversos tamaños donde acomodan el contenido, le ponen el fondo que indiquemos, los bordes, etc.

Para determinar el ancho y alto se basan en lo que les pasemos con width y height en el CSS. Pero no nada más eso, sino que también toman en cuenta el relleno (padding) y los bordes. Sumando todo eso el navegador determina el ancho de la caja. Por ejemplo si tenemos el siguiente CSS:

width: 300px;
padding: 20px;
border: 2px;

El ancho de nuestra caja no será 300 pixeles, ése será el ancho dedicado al contenido, sino que será de 344 pixeles (300 + 20*2 + 2*2). Esto no estaría del todo mal si no fuera porque nos complica los cálculos a la hora de tratar de acomodar cajas en nuestra página, tenemos que tomar en cuenta que los cambios en padding cambiarán el ancho y eso nos puede alterar la distribución de nuestra página.

IE6 usaba un sistema mejor. Así es, aunque no seguía el estándar IE6 tenía un mejor sistema para determinar el ancho de una caja. Del ejemplo anterior, nuestra caja tendría un ancho de 300 pixeles, incluyendo bordes y relleno. El ancho para el contenido se reduciría a 256 pixeles, pero al momento de calcular la distribución y tamaños de las cajas las cosas serían mucho más sencillas. Después de todo, cuando tienes una caja de verdad y le añades relleno la caja no se hace más grande, sino que se reduce el espacio para meter cosas.

Supongamos que queremos acomodar dos cajas lado a lado en un espacio de 960 pixeles con 20 pixeles entre cada caja. Con el modelo estándar tendríamos que calcular márgenes o rellenos para determinar el ancho, más o menos así:

#caja1 { width: 610px; padding-right: 10px; }
#caja2 { width: 330px; padding-left: 10px; }

Este ejemplo es sencillo, pero cuando empezamos a añadir cajas y distribuciones más complejas puede complicarse bastante rápido. Si queremos cambiar el espacio entre las cajas, deberemos cambiar tanto width como padding. Con el sistema de cajas de IE6, sin embargo, todo resulta mucho más sencillo:

#caja1 { width: 620px; padding-right: 10px; }
#caja2 { width: 340px; padding-left: 10px; }

Si queremos cambiar el espacio entre cajas simplemente cambiamos padding. Si queremos añadir más cajas hacemos una suma simple de width sin tener que preocuparnos por los rellenos y bordes (y recordar que tenemos que sumar cada lado).

¿Hay una manera de regresar a es modelo de cajas más sencillo? ¡Sí la hay! A partir de CSS3 podemos usar la declaración box-sizing para decirle al navegador que modelo de cajas utilizar:

* { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } 

Con esto podemos usar la manera más racional de darle ancho a nuestras cajas. Aunque usamos los prefijos -moz y -webkit es bastante seguro usar esta propiedad desde ya.

Si quieres leer más sobre el tema, en inglés, Paul Irish escribió un excelente artículo sobre box-sizing y su fiabilidad. También Chris Coyier tiene un muy buen artículo de box sizing donde además habla un poco más de los problemas del modelo de cajas actual.