Solución al problema de float en maquetación CSS

  • Por
  • CSS
Cuando una capa tiene un float la capa contenedor sobre la que está situada muchas veces no acompaña. Lo solucionamos con el atributo CSS overflow:hidden y definiendo un width al contenedor.
Si estamos maquetando con CSS nuestras páginas web, algo que deberíamos estar haciendo ya desde hace tiempo, podremos haber observado un problema que a veces tiene la maquetación cuando utilizamos float para alinear capas a la izquierda o la derecha. En este artículo vamos a tratar de explicar el problema, cuándo se produce y dar una sencilla solución.

Esta solución que publicamos en el Taller de CSS de DesarrolloWeb.com está ampliamente divulgada y aceptada por diversos desarrolladores.

El problema del float y el crecimiento de las capas contenedor

Imaginemos que tenemos un contenedor en una capa DIV que tiene sus características, como un color de fondo, un borde o lo que queramos poner. Ahora imaginemos que en ese contenedor colocamos dentro un par de capas DIV y que estas están flotando a la izquierda y derecha, con el atributo float: left y float: right.

Esta configuración de capas, que es bastante habitual, podría ser utilizada para por ejemplo crear una estructura de dos columnas en la página web. Para aclararnos, llamaremos contenedor a la capa que incluye a las otras capas con el float, que llamaremos capas flotantes.

En las capas flotantes supuestamente colocaremos diversos contenidos, como texto, imágenes o lo que deseemos. Por tanto, las capas flotantes crecerán hacia abajo el espacio suficiente para albergar a todos los contenidos que coloquemos. Lo ideal es que el contenedor acompañase el crecimiento de las capas flotantes, haciéndose tan alto como sea necesario para alojar las dos capas flotantes. Pero realmente no siempre ocurre esto y muchas veces habremos observado cómo el contenedor se queda con un tamaño mínimo, arriba del todo, y no crece lo suficiente para que las capas flotantes quepan en él.

Quizás este problema ya lo hayamos experimentado y entonces podremos entenderlo. En cualquier caso, lo mejor es mirar una imagen para que quede claro el efecto poco deseable que a menudo nos encontraremos:


Esto es lo que ocurriría con un código como este:

<style type="text/css">
#contenedor{
   border: 1px solid #bbb;
   background: #ddd;
   padding: 10px;
}
#flotanteizquierda{
   float: left;
   background: #fc3;
   width: 200px;
   padding: 10px;
}
#flotantederecha{
   float: right;
   background: #3cf;
   width: 200px;
   padding: 10px;
}
</style>

<div id="contenedor">
   <div id="flotanteizquierda">
      Esta capa tiene un float, para alinearse a la izquierda. El problema es que el contenedor de la misma no se entera que esta capa crece mucho hacia abajo y parece como si terminase en seguida.
   </div>
   <div id="flotantederecha">
      Aquí también tenemos float, para alinearse a la derecha. Pero el contenedor donde está colocada no se entera que la capa crece hacia abajo.
   </div>
</div>

Solución con overflow:hidden y definiendo un width

Lo que sería deseable es que el contenedor se haga suficientemente grande para albergar todo el contenido que se ponga dentro, independientemente de que las capas que coloquemos dentro tengan el atributo float. Se puede ver en la siguiente imagen


Esto en realidad se consigue con una combinación de dos atributos que debemos colocar en los estilos CSS de la capa contenedor.

Por un lado tenemos atributo CSS llamado overflow, que ya explicamos en el artículo Overflow en CSS. Simplemente tenemos que asignar el valor hidden al atributo overflow. Esto funciona correctamente en navegadores como Firefox, Opera o Chrome (en general en todos los navegadores menos Explorer, al menos en versiones actuales).

Para conseguir que Explorer también expanda el contenedor hasta la medida suficiente como para albergar el contenido flotante, tenemos que colocar un atributo width, con un valor cualquiera.

Por ejemplo, el contenedor se vería correctamente con este código CSS:

#contenedor{
   overflow: hidden;
   width: 450px;
   border: 1px solid #bbb;
   background: #ddd;
   padding: 10px;
}

El atributo width puede tener cualquier valor, por lo que no tenemos por qué asignarle un valor fijo. Por ejemplo, también funcionaría con un width: 100%;

Para acabar, dejo el enlace a un ejemplo donde se puede ver el problema de maquetación CSS con float y la solución combinando el overflow: hidden y el width. Ver el ejemplo en una página aparte.

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir

Comentarios

Tomás Corral

28/3/2009
Este ejemplo es interesante, pero el mismo ejemplo proporcionando un overflow:auto en lugar de overflow:hidden tiene el mismo resultado y sin los problemas de perder contenido.

Tomás (baireswebdesign.com)

02/4/2009
Estimados,

Es mucho mejor utilizar un cuarto div que se ubique debajo de los 2 flotantes pero antes de cerrar el div contenedor, a este div le damos la propiedad clear: both

ej:

<div id="contenedor">
<div id="flota1">texto</div>
<div id="flota2">texto 2</div>
<div style="clear:both"></div>
</div>
De esta forma contenedor siempre abarcara a los que estaban flotando y podran meter contenido variado dentro de los divs, sin importarl el "alto" final de los mismos

josepzin

03/4/2009
Yo lo solucionaba de otra manera, agregando estos valores al primer contenedor: <div id="contenedor" style="float: left; width: 100%;">

Con tu método no conviertes el contenedor en "float", que tambien es muy util.

minotau

03/4/2009
Yo personalmente lo conseguia metiendo una capa sin contenido al final de las dos capas flotantes pero dentro del contenedor al que le definia el atributo css "clear: both;". Asi obligaba a la capa contenedor a bajar hasta debajo de las capas flotantes. Espero haber dado una alternativa. Aunq me parece tambien muy bien el atributo overflow y width ;)

ToniPHP

09/4/2009
clear: both
Yo también lo hacía metiendo un <div> sin contenido con el estilo clear:both, pero probaré esto de meter el oferflow, porque parece una solución más limpia.
Gracias!

pepi

10/4/2009
otro mas que metia capas vacias
pero no conocia eso de clear:both, asi que miraba cuanto faltaba de alto y ese era el alto que le daba a la capa vacia, claro que tenia el problema de que si se agrandaba el teto tenia que redimensionarlo.

uy

26/4/2009
Buena solución
No siempre el clear sirve, y no sirve meter más capas sirve.

En mi caso, se rompía toda la estructura, y con overflow:hidden se soluciona perfectamente. El único problema que habría es si tuviera una altura determinada #contenedor, pero en ese caso, tampoco tendríamos éste problema. Por lo que la solución es muy buena e interesantemente limpia.

Saludos.

Carlo Rozo

01/5/2009
Solución mas sencilla
Tan sencillo como colocar un salto de línea <br /> al final de las dos capas flotantes.

mauro

05/5/2009
Funciona!
Gracias, me fue de mucha utilidad, sos un groso.
Con el atributo clear no pude solucionar el problema.

Fenomenal!

Asure

05/6/2009
le amo
Dios! si le conociera lo besaria!

muchas gracias, ya m volvia loca @w@

clear no es tan poderoso como pensaba (:

saludos!

Carlos

09/6/2009
Muy bueno!
Gracias por solucionar ese problema, seguro que mas de una vez le sucedió a alguien. Siempre me rompía la cabeza al tratar de solucionar ese problema, a parte que no lo conseguía por ningun lado de la red.

Muy buen aporte!

Fadi Webdesign

17/4/2010
Felicidades por el artículo
Hola que tal, la solución que diste al tedioso problema de las capas(divs) flotantes, es excelente, este problema yo lo tenía desde hace mucho tiempo. Que chido que compartas tus conocimientos ojala todos fueran como tú, porque así de esa manera aprendemos en conjunto, y estoy hablando de compartir cosas que en realidad valgan la pena. Saludos

montolio

13/6/2010
buena !
También me solucionó un montón de problemas.

Aguante este blog.

Pedro

14/7/2010
Se agradece mucho la aportación.
Amigo, se agradece la aportación. No conseguía ampliar la capa que rodeaba a capas flotantes.

Muchas Gracias...

Gustavo

24/7/2010
Gracias
Una solucion limpia y sin parches,
me salvaste la vida!!!!!!

Ya estaba mirando opciones para trabajar sin float U_U

Gracias.

CAlavera

07/9/2010
Felicitación
Casí nunca comento en los blogs :P

Pero de verdad que esta vez me fue de mucha ayuda tu articulo.

GRACIAS!

dess

23/11/2010
poner dos objetos en el mismo nivel
hola quisiera poner en el mismo nivel el logo y el menu en la siguiente pagina:
http://www.desselite.com/elhorno/demo/index.html que estoy haciendo de prueba... tienen idea de como hago eso?

Saludos y gracias,

dess.

juan

02/11/2011
Prueba de solucion de contenedor que crece con divs internos
EXCELENTE POST HERMANO !!! ME SOLUCIONO EL PROBLEMA Y ESTUVE RENEGANDO BASTANTE PROBANDO MUCHAS COSAS Y NADA HASTA TU POST

ttimagina

23/11/2011
Solución!!!!
Muchas gracias, por fin puede encontrar la solución a este problema me estaba volviendo loco jajaja

Web

24/2/2012
Felicitaciones
Gracias! Muy buen artículo!

Mario Campos alaar

18/4/2012
Ayuda con los divs
Excelente artículo,
Pero quisiera ayuda con lo siguiente:
Tengo div contenedor, dentro de él hay 3 div fijo. Cuando modifico el tamaño de la página del navegador, los Divs se empiezan a mover abajo a medida que hago la pantalla mas pequeña. Cómo hago para que los divs estén siempre en sus lugares y se ponga en el navegador la barra de scroll o de movimiento en la parte de abajo?

#contenedor {width:100%px; overflow: hidden;}
#left-sidebar { width:256px; height:500px; float: left; background-color:ff0000; }
#content {width:512px; height:500px; float: left; background-color:f0f0f0; }
#right-sidebar { width:256px; height:500px; float: right; background-color: ABC012; }

Agradecería muchísimo una ayuda en este sentido.

sajero

27/6/2012
Resuelvelo con ...
Puedes resolverlo con un float y un padding

jl

17/7/2012
:)
genial. justo lo que buscaba. gracias!

Pedro S.

18/10/2012
Gracias por la ayuda
Muchas gracias por la solución a un problema que llevaba 2 días intentando resolver. Sobre todo gracias por exponer el problema de forma tan clara (enseguida identifiqué que era exactamente mi problema) y por darle una solución tan simple.
También gracias por la labor divulgativa que realizan, que sigo desde hace ya varios años.

Un saludo.
Pedro

Ruperto

04/2/2013
Gracias!
Excelente artículo, muchas gracias!
Solucioné mi problema!

Andres

12/9/2013
Gracias
Gracias me ayudo mucho la explicación, hacerlo en el css es lo más correcto aunque algunos comentan poner br puede funcionar pero no es correcto, diseño al css.

Gabriel

13/1/2014
Display: table;
En realidad la solución mas sencilla y limpia es asignarle:
display: table;
Con esto se soluciona todo y luego podes darle el atributo overflow para lo que quieras en caso que lo necesites para otra cosa!!!

lbartolessi

21/1/2014
Muchísimas gracias.
La de tiempo que me haces ahorrar. Enhorabuena por tu estilo didactico y claro y por lo bien elegidos que están los temas a tratar. Te estoy superagradecido.

Abel Ovsky

27/1/2014
Solución perfecta
Era justamente lo que buscaba, todo el problema era que me faltaba la propiedad: overflow: hidden;
Declarar dentro en el div principal que contiene todos los div dentro,
MUCHÍSIMAS GRACIAS.

SALUDOS!

Lennin Ruiz

21/3/2014
Excelente
Me has quitado un dolor de cabeza muy sencillo y limpio, me funciono

Edwing

19/9/2014
Gracias
..y hubo una luz al final del camino :P gracias hermano, me sirvió mucho!!

Daniel

07/11/2014
Float
Hola, ¿y cómo podríamos hacer para solucionar este problema en Explorer? Yo lo que hago es darle un ancho y una altura al contenedor, y lo voy ajustando hasta lograr los tamaños deseados.

Félix

16/1/2015
Problema solucionado. Gracias
Estimado, muchas gracias por tu aporte, me funcionó a la perfección, después de intentar un sin número de cosas que se me ocurrían. Muchas gracias, de verdad.
Saludos

Daniel Rivas

13/3/2015
buen aporte.
necesito ayuda con tres cajas aside(izquierda) section(centrado) aside(izquierda) aqui les dejo mi codigo fuente de lo qu quiero hacer////
este es el Html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>prueba de posiciones de aside</title>
<link rel="stylesheet" href="estilo.css">

</head>
<body>
<header><h1>cabecera</h1></header>
<nav>Menu de navegacion
</nav>

<div class="contenido">
<aside class="izquierda">izquierda</aside>
<section>contenido importante</section>
<aside class="derecha">derecha</aside>
<div style="clear:both"></div>

</div>


<footer></footer>
</body>
</html>

este es el estulo://///
*{
margin: 0;
padding: 0;
}

body{

background: #000000;
}

header{
width: 100%;
height: 100px;
background: red;
}
nav{
width: 100%;
height: 100px;
background: purple;
color: #fff;
text-align: center;
}

.contenido{

overflow: hidden;
width: 100%;

background: #ddd;


}

.izquierda{
background: #fefefe;
width: 20%;
height: 500px;
float: left;
text-align: center;
}

section{
margin: auto;
width: 55%;
height: 500px;
background: #ccc;
}



.derecha{

width: 20%;
height: 500px;
text-align: center;
float: right;
background: #3cf;

}

footer{
clear: both;
margin-top: 1em;
width: 100%;
height: 100px;
background: green;
}

gino

29/6/2015
solucion
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>prueba de posiciones de aside</title>
<style type="text/css">

*{
margin: 0;
padding: 0;
}

body{
margin:0;
padding:0;
background: #000000;
}

header{
width: 100%;
height: 100px;
background: red;
}
nav{
width: 100%;
height: 100px;
background: purple;
color: #fff;
text-align: center;
}

.contenido{
width: 100%;
background: blue;


}

.izquierda{
background: #fefefe;
width: 20%;
height: 500px;
float: left;
text-align: center;
}

section{
float:left;
width: 55%;
height: 500px;
background: #ccc;
}



.derecha{

width: 20%;
height: 500px;
text-align: center;
float: right;
background: #3cf;

}

footer{
width: 100%;
height: 100px;
background: green;
}
</style>

</head>
<body>
<header>
<h1>cabecera</h1>
</header>
<nav>
Menu de navegacion
</nav>

<div class="contenido">
<aside class="izquierda">
izquierda
</aside>
<section>
contenido importante
</section>
<aside class="derecha">
derecha
</aside>
<div style="clear:both"></div>

</div>


<footer>
pie de pagina
</footer>

</body>
</html>

TeNaCiOuS

30/4/2016
Se agradece
me tenia ya bien cabreado hace varias horas el problema con los floata jajajaja muchas gracias, me solucionaron el problema una vez mas.

Eric

25/8/2016
Gracias!
Funcionó perfecto... gracias... estaba tratando de solucionar eso... Saludos!

Santiago

19/1/2018
Excelente!!
Gracias hermano, se me presento este problema con los float en una pagina para 3 columnas, probe varias cositas antes de buscar en san Google, pero no di con la solucion. Muchas gracias por tu aporte!!