Box-Sizing, eligiendo el modelo de caja en CSS3


       En las entradas escritas hasta ahora, ha sido Internet Explorer quien se ha llevado más palos, pero en la de hoy voy a criticar a Firefox. Además vamos a ver una propiedad muy interesante para no volvernos locos en la maquetación, box-sizing.

       El modelo de caja que se usa por defecto, y el único en CSS2, es el “content-box”, según este modelo, una caja (por ejemplo un div) ocupa su ancho + padding + borde. Osea que el padding y el borde son externos. En vertical sería análogo. Esto hace que si queremos calcular el valor de ancho real de una caja, de borde a borde tengamos que hacer:

       ancho real = ancho + padding izquierdo + padding derecho + borde izquierdo + borde derecho

       Pero no siempre sabemos estos datos, al menos a priori. Imaginemos una maquetación donde tenemos dos columnas, una del 70% del ancho y otra del 30% del ancho. En este caso, a priori no sabemos el ancho de cada columna. Así que si ponemos un padding a una de las columnas, como ese espacio se añade al ancho, acabamos teniendo que las columnas se salen del ancho de 100% de la página.

       Se han utilizado remedios CSS como hacer que sea el contenido de la columna el que tenga margin, en lugar de utilizar padding en el contenedor externo, aunque esto lleva a usar más divs, o soluciones javascript, calculando el ancho en tiempo de ejecución.

       En realidad muchas veces no es este funcionamiento de caja el que deseamos, sino que nos vendría mejor que el padding fuera espacio interior y no exterior. A veces es hasta más intuitivo. Eso es lo que podemos elegir con box-sizing, el modelo de caja. Vamos a ver un ejemplo:

Texto contenido en un div con content-box, por defecto.


Texto contenido en un div con border-box.


       Ambas cajas tienen un ancho de 200 píxeles, un padding de 20 píxeles y un borde de 4 píxeles. La caja superior ahora tiene un ancho de 244 píxeles, pero la de abajo sigue siendo de 200 píxeles.

       El código css para cambiar de una a otra caja es el siguiente:

#div1{
box-sizing: content-box;
-moz-box-sizing: content-box;
}

#div2{
box-sizing: border-box;
-moz-box-sizing: border-box;
}

       Con esto nos podemos ahorrar muchos quebraderos de cabeza, sobre todo cuando tenemos tamaños como porcentajes o contenido generado dinámicamente.

       Está soportado, ya sin prefijo, por IE a partir del 8, Chrome a partir del 10, Opera desde el 9.5, Safari desde el 5.1, Opera mini, IOS, Android desde el 4. Por lo que está bastante extendido. Con la excepción de Firefox, que lo mantiene, pero con prefijo propietario y algún pequeño bug.

       Y es que en Firefox se niegan a que se toque el modelo de caja y no le ven futuros, están empeñados y ofuscados en que esto no será necesario con la función calc().

       La función calc permitirá establecer un estilo como el siguiente:

#div{
padding: 20px;
width: calc(70% - 40px);
}

       En la practica tendríamos un efecto similar y no se tendría que cambiar el modelo de caja. Pero tiene una desventaja clara, nos toca hacer los cálculos en cada elemento, mientras que podríamos elegir el modelo de caja en un elemento superior y heredar en todos los demás elementos y no tendríamos que hacer los cálculos 1 a 1.

       Firefox está empeñado en algo que va en contra de la W3C, en contra del estándar de facto, ya que todos los demás navegadores lo recogen sin prefijo, y solo está consiguiendo que tengamos que poner CSSs más largos, o que, si siguen así algunas páginas se vean bien en todos los navegadores, excepto Firefox, bajando su uso por parte de usuarios.