En la
primera parte de este tutorial vimos los conceptos básicos de la propiedad
float, ejemplos de cómo se comportan los elementos flotantes y cómo afectan a su entorno en el documento. Vamos a continuar viendo, también a través de ejemplos, cómo podemos modificar ese comportamiento.
Clear: Para no estar al lado de un float
Como ya hemos visto, un elemento flotante modifica el comportamiento de otros elementos de bloque, que suben para ocupar su sitio y su contenido se desplaza para dejarle hueco . Este comportamiento se puede evitar con la propiedad
clear, que puede tomas los valores:
left, right, both, none o inherit.
Clear se aplica a elementos de bloque no flotantes o a cualquier elemento flotante, forzándolos a desplazarse debajo de un
float anterior. Los valores indican a que lado del elemento no permitimos que haya un
float: a la derecha, a la izquierda o a ambos.
Clear se aplica a elementos de bloque no flotantes o a cualquier elemento flotante, forzándolos a mostrarse debajo de un float
Vamos a retomar algunos ejemplos y aplicar
clear para ver cómo afecta al resultado.
En la siguiente imagen tenemos 3 bloques con dimensiones diferentes y con
float:left:
|
Los tres bloques con float:left |
Si no queremos que el bloque azul se quede donde está, podemos ponerle
clear:left. Con esto estamos indicando que este bloque no puede tener ningún
float a su izquierda. Si hubiera alguno debe bajar hasta colocarse debajo. Y esto es lo que hace:
div#azul {
clear: left;
}
|
Bloque azul clear:left
|
Si en vez de eso aplicamos clear:left sólo al naranja:
div#naranja {
clear: left;
}
|
Bloque naranja clear:left |
El naranja baja, porque no puede tener a su izquierda ningún bloque flotante y el azul se coloca a su lado. Si al bloque naranja le ponemos
clear:both significa que no puede tener ningún elemento flotante a su izquierda ni a su derecha, pero si lo aplicamos veremos que no ocurre nada. Este ejemplo nos sirve para resaltar que la propiedad
clear obliga a un elemento a colocarse debajo de un
float anterior. Como el bloque azul está declarado despues en el HTML, no cambia nada.
Para desplazar el bloque azul podemos añadirle también clear:left:
div#naranja {
clear: left;
div#azul {
clear: left;
}
|
Bloque naranja y bloque azul con clear:left |
Cuando tratamos con elementos no flotantes, la propiedad se aplica sólo a bloques, los elementos de línea no se ven afectados. En este ejemplo tenemos tres imágenes, el pez azul es flotante a la izquierda:
|
Pez azul float:left |
Podriamos pensar que si le ponemos a la mariquita
clear:left bajará a la siguiente línea, pero no es así, al ponerlo no cambia nada porque es un elemento de línea y no es flotante. Sin embargo, si tenemos imágenes dentro de bloques, sí podemos utilizarlo. En el siguiente ejemplo teníamos el pez azul con
float:left y las otras dos imágenes en un
div con borde rojo. El
div ha subido al ser flotante la imagen del pez azul y las dos imágenes se han desplazado para dejarle sitio.
|
Pez azul con float:left. Las otras dos imágenes en un bloque |
Si ahora le ponemos al
div con borde rojo
clear:left:
|
pez float:left, div con imágenes clear:left |
El bloque no puede tener un
float a su izquierda por lo que se desplaza abajo.
La propiedad
clear es muy útil también para controlar como se coloca el texto alrededor de una imagen. En el siguiente ejemplo tenemos una imagen flotante a la izquierda y dos parrafos que hemos marcado con borde rojo:
|
imagen con float:left |
Si no queremos que el segundo párrafo empiece a la derecha de la imagen le ponemos
clear:left:
|
Imagen float:left, segundo párrafo con clear:left |
Todo el bloque del párrafo baja para colocarse debajo del elemento flotante.
Si tenemos varias imágenes podemos utilizar
clear para controlar cómo se colocan. En el siguiente ejemplo tenemos tres imágenes y a continuación 2 párrafos con el borde marcado en rojo. Ninguno es flotante:
Como queremos que el texto quede alrededor de las imágenes, vamos a hacerlas flotantes a la derecha, las tres (
float:right ). El resultado es:
|
Ejemplo con las imágenes flotantes a la derecha |
Si queremos que el corazón quede debajo del caballo, le ponemos
clear: right:
|
Las tres imágenes float:right, Corazón clear:right |
Como el corazón no puede tener ningún elemento flotante a su derecha, bajará para colocarse por debajo. El periódico, que es flotante a la derecha, como los otras imágenes, quedará al lado del corazón, y no del caballo porque los elementos flotantes se desplazan a derecha o izquierda
en su línea. El corazón a bajado y, para el periódico, declarado en el HTML después del corazón, esta es ahora su linea.
Es muy importante tener en cuenta que para lograr la disposición que queramos tenemos que jugar con
float/clear y con
el orden en que declaramos los elementos en el HTML. Si queremos que el periódico quede al lado del caballo y el corazón debajo, tenemos que cambiar el orden de las imágenes en el HTML. Ponemos primero el caballo, después el periódico y después el corazón. Las tres imágenes con
float:right y el corazón, ademas con
clear:right. Nos quedaría:
|
Las tres imágenes float:right. Corazón clear:right |
Igualmente, si queremos que el primer párrafo quede por encima de las imágenes, tendría que estar declarado antes.
Es muy importante tener en cuenta que para lograr la disposición que queramos tenemos que jugar con float/clear y con el orden en que declaramos los elementos en el HTML
Para que las tres imágenes queden en vertical tendríamos que poner
clear:right a la segunda y la tercera:
|
Las tres imágenes con float:right. Periódico y corazón con clear:right |
Y este es un buen punto para retomar la explicación de los elementos contenedores que se encogen sin tener en cuenta los
floats…
El contenedor menguante
La razón por la que el bloque contenedor se va encogiendo es sencilla: para los elementos de bloque (como el
div contenedor) los elementos con
float no ocupan espacio en la página, por lo tanto no los tiene en cuenta. En alguno de los ejemplos que hemos visto, con todos los elementos flotantes, el bloque no contiene nada. La única razón por la que no desaparece completamente es que tiene un
padding declarado de 10px.
Este comportamiento a veces no es lo que queremos (ya veremos como se evita) y puede parecer un
bug, un error de diseño, pero no lo es. Es una decisión consciente de los desarrolladores del estándar CSS y tiene una razón de ser: el texto que fluye alrededor de las imágenes flotadas.
Para entenderlo nos sirve un ejemplo similar al del apartado anterior. El siguiente documento tiene dos párrafos, y el primero de ellos contiene también una imagen:
|
Imagen y texto, ninguno flotante |
Si hacemos la imagen flotante a la izquierda, todo queda como debe, el texto se coloca alrededor de la imagen como en los medios impresos tradicionales:
|
Imagen con float:left |
Cada párrafo es un elemento de bloque que ha subido para recolocarse como si el
float no estuviera ahí. El contenido de los bloques, al ser elementos de línea que quedan al lado de un
float, acortan su longitud para dejarle sitio.
El pez azul está dentro del párrafo 1, pero éste no le tiene en cuenta y se ha encogido hasta encerrar sólo al texto. Si el contenedor no ignorara al elemento flotante el resultado sería este:
Soluciones al problema del contenedor
Vamos a partir de un ejemplo con una imagen y un bloque de texto, los dos dentro de un
div contenedor (
#wrapper) que hemos marcado con borde negro.
Ponemos la imagen flotante a la izquierda y el bloque de texto flotante a la derecha. El texto está dentro de un
div al que hemos puesto borde rojo y al que hemos fijado una anchura de 365 pixels para que quepa al lado de la imagen. Estos serían los estilos aplicados a cada elemento:
div#wrapper {
padding: 10px;
width: 500px;
border: 1px solid black;
}
img {
float:left;
}
div#texto {
float:right;
border: 1px dotted red;
width: 365px;
}
El resultado visual es:
|
imagen float:left, bloque de texto float:right |
Como el texto y la imagen son flotantes, el contenedor no los tiene en cuenta y queda vacío. No desaparece por completo porque tiene un
padding de 10px. Hay varias formas de solucionar esto, vamos a ir viéndolas una por una.
1.-Hacer el contenedor flotante
Si el contenedor es también flotante sí abarcará a los elementos flotantes dentro de él. Si le ponemos, por ejemplo,
float:right :
|
Contenedor con float:right |
Naturalmente esta solución no siempre puede aplicarse, porque muchas veces necesitamos que el contenedor no sea flotante. Si lo tenemos centrado en la página, por ejemplo, al ponerlo flotante se nos desplazará estropeándonos el diseño. Afortunadamente hay más soluciones.
2.- Poner un elemento con clear después de los flotantes
Esta solución es muy utilizada porque no tiene ‘efectos secundarios’. Si tenemos un elemento de bloque después de los flotantes es perfecto, le ponemos
clear:both y el contenedor, al tener que contener a este elemento, incluirá también a los que están por encima (los flotantes). Recuerda que
clear se aplica a elementos de bloque.
Cuando no tenemos ningún elemento más, como en nuestro ejemplo, tenemos que incluir uno vacío, normalmente un
div, sólo para ponerle el
clear y arreglar el contenedor. Debajo del bloque que contiene el texto, añadiríamos el siguiente:
<div class="clear"></div>
Definimos
clear como una clase porque podemos utilizarla sobre otros elementos si los tenemos disponibles:
.clear {
clear: both;
}
Este
div sería invisible, en la imagen de abajo le hemos puesto unos pixels de
padding y borde verde para que se vea:
|
Div vacío con clear:both |
El bloque contenedor se ha tenido que extender incluyendo a los
float. El único problema de esta solución es que a veces tenemos que incluir elementos vacíos, que no tienen un significado real (semántico) en la página.
Para evitar esto actualmente se utiliza un
pseudo elemento:
.clearfix:after {
content: "";
visibility: hidden;
display: block;
clear: both;
height: 0;
}
Esta clase se podría aplicar sobre el último elemento real, en este caso el párrafo, de forma que se aplica el
clear sobre el pseudo elemento 'after' posterior.
3.- Utilizar la propiedad CSS overflow
Si ponemos
overflow:hidden o
overflow:auto en el elemento padre (el contenedor en este caso) se expandirá siempre para abarcar a los elementos flotantes. Esta solución también es muy utilizada, sólo hay que tener en cuenta que esta propiedad implica también algo más, para saber si podemos aceptarlo:
overflow: hidden – Significa que el contenido que exceda de las dimensiones del
div (si las tiene) se oculta, no habrá barra de desplazamiento ni se verán por fuera del
div.
overflow: auto – Significa que si el contenido excede las dimensiones del
div, aparecerán unas barras de desplazamiento para hacer
scroll.
Algunos navegadores (IE6 por ejemplo) necesitan que el contenedor tenga fijada una anchura o altura para que la solución funcione bien.