El modelo de cajas II: BoxModel Hack

¿Por qué es necesario ”hackear” el modelo de cajas?

De acuerdo con las especificaciones de la W3C, cuando asignamos un ”ancho” o un ”alto a un bloque de CSS, estas medidas se refieren al área del contenido del bloque. Los rellenos, los bordes y los márgenes son un añadido al total del ancho.

Image

El problema consiste en que los Internet Explorer anteriores a la versión 6 utilizan un modelo de caja distinto. En el modelo que utiliza IE hasta la versión 5 incluen dentro del width tanto el relleno, como los bordes y el margen.

Es decir según la especificación, tu tienes una caja de un tamaño X y a ese tamaño le añades un relleno, un borde y un margen. En cambio en Explorer tu tienes una caja de un tamaño X y a ese tamaño le restas lo que ocupen los rellenos, los bordes y los márgenes. Y esto, a la hora hacer un diseño basado en bloques de CSS es un problema.

Veamos un ejemplo de lo que pasa:

.caja {
width: 100px;
padding: 10 px;
border: 10 px;}

Si aplicamos este estilo a un bloque de css, por ejemplo un div:

En los navegadores que cumplen el estándar, el ancho de extremo a extremo de nuestro div sería de 140píxeles: un borde de 10 + un relleno de 10 + 100 de contenido + relleno de 10 + borde de 10.

En IE5 y anteriores, tendríamos una caja de extremo a extremo de 100 píxeles. 10 de borde + 10 de relleno + 60 de contenido + 10 de relleno + 10 de borde.

Creo que queda claro que la diferencia es notable.

El BoxModelHack lo que intenta es que el IE explorer aplique el mismo ancho que un navegador standard y para ello aprovecha algunos fallos conocidos de Explorer.

ENGAÑAR AL EXPLORER IN HACKEAR EL MODELO DE CAJAS

Recién salido del horno, nos aporta morris, una técnica que permite lograr que el modelo de cajas funcione correctamente en todos los navegadores sin meterse en hacks e historias que invalidan nuestras CSS:

TÉCNICAS PARA ENGAÑAR AL EXPLORER

Meter una caja dentro de otra
Consiste, cómo su nombre indica en quitar los bordes y los rellenos de la caja que te está dando problemas, incluir dentro de ella una segunda caja a la que le aplicaremos los paddings y los bordes. El problema de esto es que lo hacemos dentro del html, con lo que perdemos nuestra ventaja principal de diseñar con CSS que es precisamente separar la estructura de la presentación.

El fallo de esta práctica, es que cuando por fin los navegadores implementen bien el modelo de cajas (de hecho en su última versión ie6 ya lo hace), cambiar un ”hack” en una hoja de estilos es cuestión de un minuto, en tanto que cambiar n páginas html con n cajas puede llegar a ser un perfecto dolor de cabeza.

<style type=”text/css”>
div.externo {
width: 100px;
}

div.interno {
padding: 1em;
border: 5px;
}

</style>

contenido

Modificar la hoja de estilos

Los métodos que modifican la hoja de estilos tienen la ventaja de que cuando quieras hacer cambios en el futuro, te limitas a cambiar la hoja de estilos en lugar de toda la estructura de tus páginas HTML; por lo tanto de cara a las actualizaciones resulta más rápido y más sencillo.

De los innumerables métodos existentes vamos a ver tres, no porque sean los más mejores del mundo, sino porque son los más sencillos y dado que nosotros estamos empezando, mejor nos lo tomamos con calma.

1.- Tan hack

Este Hack utiliza un bug del explorer. La estructura básica es:

div {
border: 10px;
padding: 10 pix solid;
width: 100px;
}

* html div {
width: 140px;
w\idth: 100px;}

En la primera regla hemos definido todas las propiedades que necesitamos en nuestra caja incluidos los bordes y la anchura para los navegadores que implementan correctamente el modelo de cajas.

La segunda línea utiliza un bug de Internet Explorer. Dado que html es el elemento raíz de un documento, el selector * html no tiene ningún equivalente dentro de un documento XHTML válido. Aquí nos aprovechamos de algunas peculiaridades:

IE (win/mac) ignora el selector universal cuando precede a html. También ignora el selector (* * body). Así que gracias a esto, todos los navegadores ignorarán esta regla, salvo IE que lee tranquilamente nuestra primera línea en la que definimos una anchura de 140px;

En cambio la siguiente línea, debido al carácter de escape (\) que contiene no la puede leer IE5x por lo que la ignora. En cambio todos los navegadores que implementan bien el modelo de cajas, incluidos ie6 y Opera, pueden leer la última línea e implementan correctamente el tamaño de la Caja,

Ns4 y Opera cuando se encuentran un carácter de escape (\) ignoran la página entera. Pero cómo en este caso, el selector no coincide con ningún elemento en el documento, ignoran el bloque completo y siguen aceptando el resto de la hoja de estilos CSS.

2.- Tanteck hack

Este hack también está basado en un bug de explorer. (Después de leer este tema uno se acaba alegrando de que IE tenga tantos bugs Razz)

Partimos de la Base de que queremos una caja con un ancho de 300 píxeles, con un borde 20píxeles y un relleno de 30px. Nuestro estilo, normalmente sería así:

div.boxtest {
border: 20px solid;
padding: 30px;
background: red;
width: 300px;}

Esta configuración nos daría una caja con un ancho total de 400px;

10+30+300+30+20=400

Pero… ¿Qué nos ocurre? Que los navegadores que malinterpretan el modelo de caja meten dentro de la caja el borde y el relleno con los que nos queda un ancho total de sólo 300px con un contenido de 200px;

300-20-30-30-20=200

Para evitar esto, vamos a aprovecharnos de un bug del IE5.x/win, para engañarle

div.content {
border: 20px solid;
padding: 30px;
background: #e5e5e5;
width: 400px;
voice-family: "\"}\"";
voice-family: inherit;
width: 300px;}

En este caso, por un Bug, ie5X ignora todo lo que viene después de las declaraciones de voice-family por lo que coge el primer valor. Los navegadores que no tienen este bug, toman el segundo valor (especificidad).

Con esto estaríamos apañados, pero nos falta un navegador por contentar: Opera 5

html>body .content {
width: 300px;
}

Este hack, nos sirve no sólo para contentar a Opera 5, sino también a todos aquellos navegadores que implementan correctamente el modelo de caja y que no tienen el voice-family bug que tiene IE5x/win.

NOTA: IE6 implementa correctamente el modelo de cajas. Sin embargo si aplicamos la declaración xml<?xml versión=”1.0”?>, aplica el modelo de cajas incorrecto.

¿Qué hack utilizar?
Aquí hemos visto sólo dos formas, pero hay varias, cada una con sus venatajas e inconvenientes:

El Tan hack funciona estupendamente, pero hay que hacer la misma declaración del ancho 3 veces. Este hack se basa en uno anterior.

El tanteck hack falla en IE4 y Ns4.

El SBMH que no funciona en Netscape 4, Opera 5 y Konkeror.

Las BoxModelHack alternativas (que no hemos visto aquí) fallan en Konkeror y en netscape 4.8

Parece ser que la solución definitiva es el Mid Pass Filter, también de tanteck

div {
border: 10px solid red;
background-color: #cccccc}

@media tty {
i{content:"\";/*" "*/}} @import 'midpassbefore.css'; /*";}
}/* */

@media tty {
i{content:"\";/*" "*/}} @import 'midpassafter.css'; /*";}
}/* */

midpassbefore.css

div {
width: 100px;}

midpassafter.css

div {
width: 400px;}

Me he leído la explicación, pero francamente, no he entendido absolutamente nada. Lo he probado en ie5 y funciona. Tenéis una explicación del funcionamiento de este hack en http://www.tantek.com/CSS/Examples/midpass.html (en inglés).

En nuestros ejemplos, nosotros vamos a utilizar el tan hack, porque nos parece el más sencillo y también funciona.

Para la realización de este artículo me he basado en el artículo ”BoxModelHack” que podéis encontrar, en inglés, en http://css-discuss.incutio.com/?page=BoxModelHack

Volver al índice

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s