CSS: DIV Contenedor de DIVs con Float: IE & FF
08 de Octubre de 2008 en Html, Programación
Lecturas: 4,871

Con este nombre críptico se esconde uno de mis quebraderos de cabeza que estoy teniendo para maquetar de forma que Internet Explorer 6, 7 y Firefox trabajen de la misma forma.

Imaginemos que tenemos un div que contiene un par de divs con float:left. El problema que nos aparece es que el fondo gris no se estira para recoger los elementos que contiene, ya que los divs internos son flotantes.

HTML:
<div style="background-color: grey;">
  <div style="float: left;">
    <img src="images/avatar.jpg">
  </div>
  <div style="float: left;">
    Nombre del Usuario
  </div>
</div>

Como corregimos ésto? Bién, he dado con la solución!
Editado: Gracias a los comentarios, ahora la solución es mejor!

La forma común

Hasta ahora lo que venía haciendo con Firefox era agregar un elemento HTML justo después del último elemento div interno, antes de cerrar el div contenedor, con un clear:both. La teoría es fácil y funciona: El clear:both se encarga de limpiar de elementos a derecha e izquierda para que el contenedor sepa hasta dónde llega él mismo.

HTML:
<div style="background-color: grey;">
  <div style="float: left;">
    <img src="images/avatar.jpg">
  </div>
  <div style="float: left;">
    Nombre del Usuario
  </div>
  <br style="clear: both;">
</div>

Pero en Internet Explorer 6 y 7 ésto no funciona. El navegador lee el BR pero parece que el clear:both no se aplica. La única forma que encontré era poner dos veces el BR. Así parece que sí que funciona pero por contra nos hace dos saltos de línea, con lo que si teníamos la maquetación cuadrada con tamaños y posiciones, veremos como se descolocan con el nuevo espacio inferior.

La nueva solución

Rebuscando por internet he encontrado la solución que plantean en Quircksmode. Se trata de usar la instrucción overflow junto con un width. El primero soluciona el problema en Internet Explorer 7 y el segundo es para que internamente se llame al hasLayout de Internet Explorer 6:

HTML:
<div style="background-color: grey; overflow: hidden;width: 100%;">
  <div style="float: left;">
    <img src="images/avatar.jpg">
  </div>
  <div style="float: left;">
    Nombre del Usuario
  </div>
</div>

El problema aquí es el width, porque el resto de navegadores también lo entienden y lo aplican, desmontando la maquetación que teníamos (por ejemplo, un padding).

Entonces, pensando un poco, necesitamos una instrucción que sólo funcione para Internet Explorer 6 y que active su hasLayout... y aquí entra otro truco que he visto en PositionisEverithing, que aunque su método no me gusta nada, usa la instrucción zoom para activar el hasLayout.

Así que la forma que he visto que funciona en los tres navegadores es una fusión de las 3 soluciones: Por un lado mantenemos el BR con el clear:both y además añadimos al DIV contenedor un par de instrucciones CSS para que en los otros navegadores funcione, dejándolo de la siguiente manera:

HTML:
<div style="background-color: grey; overflow: hidden;zoom:1;">
  <div style="float: left;">
    <img src="images/avatar.jpg">
  </div>
  <div style="float: left;">
    Nombre del Usuario
  </div>
  <br style="clear: both;">
</div>

Editado: He probado la soluciónes de los comentarios y la fórmula que funciona en los tres casos es la siguiente: Añadir al contenedor el binomio overflow y zoom sin el salto de línea con clear:both.

HTML:
<div style="background-color: grey; overflow: hidden;zoom:1;">
  <div style="float: left;">
    <img src="images/avatar.jpg">
  </div>
  <div style="float: left;">
    Nombre del Usuario
  </div>
</div>

Ala, problema resuelto. Y si estáis cuadrando maquetación entre navegadores... paciencia!

Salu10

Tags: , ,
 Enviar a Fresqui

Leer los Comentarios

[ # 39555 ] Comment desde Omar [08 de Octubre de 2008, 02:36]

Hola, creo que hay otra opción sin tener que añadir un nuevo elemento con clear:both. Está muy bien explicado en ésta página http://www.marciobarrios.com/consejos-css

Saludos

[ # 39560 ] Comment desde acido69 [08 de Octubre de 2008, 03:36]

La solución con el “clear:both” (quitar contenedores flotantes a los dos lados) no es la mejor solución, porque si quieres hacer una maquetación más precisa, el “clear:both” está dentro de un div, y este div tiene un tamaño, un tamaño que se nota en la maquetación.
¿solución?
http://code.google.com/p/fcss/source/browse/trunk/css/lib/grid.css?r=2
mira la clase “TR”

[ # 39567 ] Comment desde Xavi [08 de Octubre de 2008, 05:00]

Gracias a los dos.

El truco del after lo vi en Position is Everything, aunque al final la solución que planteo es la que me ha funcionado en todos los casos que he probado (el maquetador anterior ya tuvo en cuenta el tamaño del div extra).

Me apunto las soluciones para mis próximos proyectos. :-)

[ # 39661 ] Comment desde Rafa Garcia [09 de Octubre de 2008, 09:16]

No te compliques tanto la vida. Al div contenedor le añades el par overflow:hidden; en tu declaración de estilos y listo. El clear:both hace que añadas un elemento mas -innecesario- al DOM.

Un saludo

[ # 39666 ] Comment desde Xavi [09 de Octubre de 2008, 09:26]

Rafa, ésto está ya probado. El problema es que entonces en ie6 no funciona. Por éso la coña del zoom:1, para que se ejecute el hasLayout.

Escribe un Comentario





Estadísticas