Inicio Posicionamiento en CSS
Artículo
Cancelar

Posicionamiento en CSS

Introducción

CSS utiliza el flotado y el posicionamiento para tener el máximo control sobre el lugar que ocupa cada elemento en una página web, sus condiciones de visibilidad y “flotabilidad”, así como controlar el manejo de capas.

En los siguientes apartados veremos algunas propiedades de CSS que se utilizan para controlar el posicionamiento de los elementos. Estas son:

  • display
  • float
  • clear
  • position
  • visibility
  • z-index
  • overflow
  • clip-path

Un término que aparecerá a menudo es “flujo normal”. Cuando hablamos de que los objetos de una página siguen el flujo normal del documento, queremos indicar que la forma en la que se disponen en la ventana del navegador coincide con el lugar que ocupan en el documento escrito (en el código HTML), donde el orden de lectura es de arriba a abajo y de izquierda a derecha.

Flotando y posicionando con CSS conseguimos que los elementos abandonen su flujo normal. De esta forma un elemento que este en el documento escrito más abajo que otro en el documento puede verse en el navegador por encima de él.

display

La propiedad display permite al documento interpretar de otra forma los elementos de tipo bloque y los elementos de tipo línea. Para ello basta con que asignes a esta propiedad el valor block si quieres que un elemento “en línea” se comporte como un elemento de tipo bloque y none, si quieres que un elemento de bloque no genere caja, no muestre su contenido y no ocupe espacio en la página.

Lee el artículo La propiedad display

¿Qué diferencia hay entre inline e inline-block?

flex

Leer Guía de Introducción a Flex

grid

Leer Guía de Introducción a Grid

float

La propiedad float sirve para mover una caja a la izquierda o a la derecha hasta que su borde exterior toque el borde de la caja que lo contiene o toque otra caja flotante.

Para que un elemento pueda flotar debe tener definido implícita o explícitamente su tamaño.

Las cajas flotantes no se encuentran en el “flujo normal” del documento por lo que las cajas que sí siguen el flujo normal se comportan como si las flotantes no estuviesen ahí. Es decir, no dejan el hueco de donde debería estar la caja flotante en un flujo normal, pero si se adaptan cuando se encuentran un elemento flotante.

La propiedad float puede tener los siguientes valores:

  • none hará que el objeto no sea flotante.
  • left hace que el elemento flote izquierda.
  • right hace que el elemento flote a la derecha.
  • inherit hará que el elemento tome el valor de esta propiedad de su elemento padre.

Primer ejemplo con float

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <ul>
    <li>Primer elemento</li>
    <li class="float">Segundo elemento</li>
    <li class="float">Tercer elemento</li>
    <li class="float">Cuarto elemento</li>
    <li>Quinto elemento</li>
    <li>Sexto elemento</li>
    <li>Séptimo elemento</li>
  </ul>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ul {
  background-color: grey;
  padding: 0;
}

li{
  list-style-type: none;
    background: blue;
    width: 100px;
    padding: 8px;
    margin: 8px;
    color: white;
}

.float{
  float: right;
}

alt text Resultado con float:right

Y si cambiamos float:right por float:left:

alt text Resultado con float:left

Segundo ejemplo con float

Flotar contenedores

Para comprender la técnica de flotar cajas vamos a hacer este ejemplo. Se trata de tres contenedores (div) de distintos colores y tamaños, los tres están metidos en el interior de otro contenedor llamado “contenido” que lo que hace es conseguir que el conjunto se encuentre centrado en el navegador.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
        <link rel="stylesheet" type="text/css" href="estilos.css" />
        <title>Flotar</title>
    </head>
    <body>
        <div id="contenido">
            <div id="caja1"> Caja 1 </div>
            <div id="caja2"> Caja 2 </div>
            <div id="caja3"> Caja 3 </div>
        </div>
    </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
body { font-weight: bold; color: white; }

#contenido {
    /* Ancho de 700px y centrado en el navegador */
    width: 700px; margin: auto;
    /* Borde sólido y fondo gris claro */
    border: solid 1px black; background-color: #CCCCCC; }

#caja1 {
    width: 100px; height: 100px; background-color:#FF0000;
    border: solid 1px black; margin: 10px; }

#caja2 {
    width: 130px; height: 130px; background-color:#00FF00;
    border: solid 1px black; margin: 10px; }

#caja3 {
    width: 160px; height: 160px; background-color:#0000FF;
    border: solid 1px black; margin: 10px; }

La página sin aplicarle los estilos CSS:

alt text

La página con los estilos CSS:

alt text

Como se trata de tres elementos de bloque cada uno de ellos comienza debajo del anterior.

Ahora flotamos la Caja1 a la derecha, así que tenemos que modificar el selector #caja1 del archivo estilos.css. El resto lo dejamos igual:

1
2
3
4
5
6
7
8
#caja1 {
    width: 100px; height: 100px;
    background-color:#FF0000;
    border: solid 1px black;
    margin: 10px;
    /*Flotar a la derecha */
    float: right;
}

Como se muestra en la siguiente imagen, cuando se flota la Caja1 a la derecha, se saca del flujo normal del documento y se mueve a la derecha hasta que su borde toca el borde derecho del bloque que lo contiene.

alt text

Recordar que la Caja 1 no llega a “pegar de todo” en el borde del contenedor pues en el estilo aplicado se configura, para las tres cajas, un margen de 10px en todos los lados.

Flotar una caja a la izquierda

Ahora vamos a flotar la Caja 1 a la izquierda, por lo que se saca otra vez del flujo del documento y se mueve a la izquierda hasta que el borde izquierdo del bloque toca el borde izquierdo del bloque que lo contiene.

Tenemos que modificar el selector #caja1 del archivo estilos.css. El resto lo dejamos igual:

1
2
3
4
5
6
7
8
#caja1 {
    width: 100px; height: 100px;
    background-color:#FF0000;
    border: solid 1px black;
    margin: 10px;
    /*Flotar a la izquierda */
    float: left;
}

La Caja 1 flotada a la izquierda quedaría así:

alt text

Puesto que la Caja ya no se encuentra en el flujo del documento, no ocupa espacio y se sitúa sobre la Caja 2, ocultando así parte de ella.

Flotar la Caja 1 y la Caja 2 a la izquierda

Ahora vamos a hacer que flote también la Caja 2. Para conseguir esto, tenemos que configurar el selector #caja2 del archivo estilos.css tal y como se hizo en el apartado anterior para la Caja 1.

1
2
3
4
5
6
7
8
#caja2 {
    width: 130px; height: 130px;
    background-color: #00FF00;
    border: solid 1px black;
    margin: 10px;
    /*Flotar a la izquierda*/
    float: left;
}

Flotando las Cajas 1 y 2 a la izquierda la web quedaría así:

alt text

Al flotar ahora también la Caja 2, ésta se mueve hasta que toca su borde izquierdo con el borde derecho de la Caja 1. Esto es así porque la Caja 1 también está flotada y ambas fueron sacadas del flujo normal del documento.

La Caja 3, junto con el Contenedor, es la única que queda en el flujo normal del documento.

Debemos fijarnos que el tamaño del Contenedor se adapta al de los elementos que siguen en el flujo normal.

Flotar todas las cajas a la izquierda

Al flotar las tres cajas a la izquierda:

  • La Caja 1 se mueve a la izquierda hasta que toca el borde izquierdo del contenedor que lo contiene.
  • La Caja 2 se mueve también a la izquierda hasta que toca la Caja 1.
  • La Caja 3 también se mueve a la izquierda hasta que toca con la Caja 2.

Esto es así porque todas las Cajas salen del flujo normal del documento y se ven entre sí.

Para conseguir esto, tenemos que modificar los selectores #caja1, #caja2 y #caja3 del archivo estilos.css tal y como se hizo en los apartados anteriores.

1
2
3
4
5
6
7
8
#caja3 {
    width: 160px; height: 160px;
    background-color:#0000FF;
    border: solid 1px black;
    margin: 10px; 
    /*Flotar a la izquierda*/
    float: left;
}

alt text

Tal y como se ve la imagen, el div “Contenido” tiene ahora una altura de 0px, ya que todo lo que tiene en su interior está fuera del flujo del documento. Es decir, como no tiene nada “dentro” no necesita tener una altura determinada.

Los divs de las cajas de colores siguen estando “en el interior” del div “contenido” y eso se nota en que no salen del ancho marcado por éste y que su alineamiento es con respecto a él.

Para que se vuelva a ver el “Contenido” tenemos varias opciones:

  • Se le puede aplicar una altura configurando en el selector #contenido la propiedad height con una altura mayor que el alto de la caja más grande.
  • Se puede flotar a la izquierda la caja con id contenido. De esta forma volvería a aparecer pero flotada a la izquierda de su contendedor (body).
  • Añadir, dentro del div “contenido” y a continuación de las tres cajas flotadas, un div totalmente vacío. Este div lo configuramos estableciendo la propiedad clear con el valor both (aunque en este caso también serviría left, pues todas las cajas flotadas anteriormente lo están a la izquierda). Esta es la solución más utilizada y la que emplearemos.

Veamos cómo quedan los códigos de los archivos HTML y CSS después de realizar la última operación explicada en la diapositiva anterior de modo que todas las cajas flotan a la izquierda y se ve igualmente el “contenido”.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <link rel="stylesheet" type="text/css" href="estilos.css" />
    <title>Flotar</title>
</head>

<body>
    <div id="contenido">
        <div id="caja1"> Caja 1 </div>
        <div id="caja2"> Caja 2 </div>
        <div id="caja3"> Caja 3 </div>
        <!-- Caja vacía para limpiar flotados -->
        <div class="clearboth"></div>
    </div>
</body>

</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
body { font-weight: bold; color: white; }

#contenido {
    /* Ancho de 700px y centrado en el navegador */
    width: 700px; margin: auto;
    /* Borde sólido y fondo gris claro */
    border: solid 1px black; background-color: #CCCCCC;}

#caja1 {
    width: 100px; height: 100px; background-color:#FF0000;
    border: solid 1px black; margin: 10px;
    /*Flotar a la izquierda */
    float: left; }
	
#caja2 {
    width: 130px; height: 130px; background-color:#00FF00;
    border: solid 1px black; margin: 10px; 
    /*Flotar a la izquierda */	
    float:left; }
	
#caja3 {
    width: 160px; height: 160px; background-color:#0000FF;
    border: solid 1px black; margin: 10px; 
    /*Flotar a la izquierda */
    float: left; }
    
    /*Limpiar flotados a izquierda y derecha*/
    .clearboth {clear: both; }

La web con todas las cajas flotadas a la izquierda, y con un nuevo div que sirve para resetear los elementos flotados hasta este punto (donde se añade el div), quedaría del siguiente modo:

alt text

Bloque contenedor demasiado estrecho

El caso a tratar es cuando nuestro div “contenido” es demasiado estrecho como para que los elementos flotados quepan horizontalmente. Si es así, el que no quepa se desplazará hacia abajo.

Podemos forzar esta situación configurando el ancho del div “contenido” con un valor de 350px (recordar que la suma de los anchos de las tres cajas, más sus márgenes, es mayor de 350px).

1
2
3
4
5
6
7
body { font-weight: bold; color: white; }

#contenido {
    /* Ancho de 350px y centrado en el navegador */
    width: 350px; margin: auto;
    /* Borde sólido y fondo gris claro */
    border: solid 1px black; background-color: #CCCCCC;}

La web con un bloque contenedor con un ancho de 350px, todas las cajas flotadas a la izquierda, y con el div que resetea los flotados hasta el punto donde se añade éste, se vería del siguiente modo:

alt text

El orden de las cajas en el documento HTML es Caja 1 – Caja 2 – Caja 3 pero, ¿cómo quedaría la web si cambiamos el orden de las cajas a Caja 3 – Caja 2 – Caja 1?

La web con el bloque contenedor de 350px, todas las cajas flotadas a la izquierda, y con el div que resetea los flotados hasta el punto donde se añade éste, pero con las cajas en el orden Caja 3 – Caja 2 – Caja 1, se vería del siguiente modo:

alt text

Podemos ver que el resultado cambia mucho. El motivo por el que no se pega la Caja 1 al borde del div “contenido” es por que la Caja1 sigue tropezando con la Caja 3 al intentar ser flotada a la izquierda.

clear

La propiedad clear se encarga de impedir elementos flotantes en la zona indicada, a la izquierda del elemento (left), a la derecha (right) o en ambos lados (both).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <ul>
    <li>Primer elemento</li>
    <li class="float">Segundo elemento</li>
    <li class="float">Tercer elemento</li>
    <li class="float fix">Cuarto elemento</li>
    <li class="float">Quinto elemento</li>
    <li class="float">Sexto elemento</li>
    <li>Séptimo elemento</li>
  </ul>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ul {
  background-color: grey;
  padding: 0;
}

li{
  list-style-type: none;
    background: blue;
    width: 100px;
    padding: 8px;
    margin: 8px;
    color: white;
}

.float{
  float: left;
}

.fix {
  clear: both;
}

alt text Resultado con clear

La propiedad clear puede tener los siguientes valores:

  • left indica que el elemento comienza por debajo de cualquier otro elemento del bloque al que pertenece que estuviese flotando a la izquierda.
  • right funciona como el left pero en este caso el elemento deberá estar flotando a la derecha.
  • both mueve hacia abajo el elemento hasta que esté limpio de elementos flotantes a ambos lados.
  • none permite elementos flotantes a ambos lados. Es el valor por defecto.
  • inherit indica, al igual que en float, que heredará el valor de la propiedad clear de su elemento padre.

position

Aunque la mayoría de problemas pueden y deben ser solucionados con un modo u otro de la propiedad display, existen mecanismos alternativos y complementarios de posicionamiento que se utilizan para realizar acciones y casos muy concretos. Mediante la propiedad position podemos modificar la posición en donde aparecen los diferentes elementos y su contenido, al margen de utilizar sistemas como flex o grid.

La propiedad position se puede utilizar para modificar la posición donde aparecerá un elemento. Esta propiedad admite cinco valores:

  1. static
  2. relative
  3. absolute
  4. fixed
  5. sticky

Si utilizamos un modo de posicionamiento diferente al estático (absolute, fixed, sticky o relative), podemos utilizar una serie de propiedades para modificar la posición de un elemento. Es importante tener en cuenta que dichas propiedades solo tendrán efecto si NO tenemos la propiedad position establecida a static.

Estas propiedades son las siguientes:

  • top: Empuja el elemento una distancia desde la parte superior hacia el inferior.
  • bottom: Empuja el elemento una distancia desde la parte inferior hacia la superior.
  • left: Empuja el elemento una distancia desde la parte izquierda hacia la derecha.
  • right: Empuja el elemento una distancia desde la parte derecha hacia la izquierda.
  • inset: Propiedad de atajo para utilizar todas las anteriores.

Estas propiedades, lo único que hacen es colocar o fijar el elemento en el punto concreto indicado, de modo que si indicas left: 0 significa que quieres que el elemento esté colocado 0 píxeles desde la izquierda. Puede contener valores negativos, invirtiendo la dirección.

(Voluntario) Lee el artículo La propiedad position.

static

static permite colocar los elementos según el flujo normal. Es el valor que asumirá por defecto en todos los elementos HTML.

relative

relative permite dejar el elemento exactamente donde está. Un elemento posicionado de esta forma se puede cambiar desde su punto de partida estableciendo para ello una distancia vertical y/o horizontal. En el siguiente ejemplo se desplaza la “caja2” 50px del extremo izquierdo y 50 px del extremo superior de su posición relativa.

1
2
3
4
5
6
7
#caja2 {width: 130px; height: 130px;
        background-color:#00FF00;
        border: solid 1px black;
        margin: 10px;
        /* Posicionamento relativo */
        position: relative;
        left: 50px; top: 50px; }

(Voluntario) Lee el artículo Posicionamiento relativo

¿Hacia donde se mueve el elemento con ID caja2 del código anterior?

absolute

absolute permite abandonar el flujo normal del haciendo que el elemento no ocupe ningún espacio de forma que el resto de elementos del flujo normal actuarán como si el elemento no estuviese allí. El modo de determinar el origen de coordenadas de nuestro elemento será el siguiente:

  • Si el elemento posicionado de modo absoluto no está contenido dentro de ningún otro, su origen de coordenadas se mide respecto a la esquina superior izquierda del body (contenedor principal).
  • Si el elemento posicionado de modo absoluto está contenido dentro de otro elemento, el origen de coordenadas del elemento se calculan con respecto a la posición de la esquina superior izquierda del elemento que lo contiene.

Lee la sección “La propiedad position: absolute” del artículo Posicionamiento absoluto.

fixed

fixed funciona de forma parecida al posicionamiento absoluto pero posiciona con respecto a la ventana del navegador apareciendo en la misma posición aunque el usuario se desplace por la página con las barras de desplazamiento.

(Voluntario) Lee el artículo Posicionamiento fijo.

sticky

(Voluntario) Lee el artículo Posicionamiento sticky.

¿Qué diferencias hay entre las posiciones static, relative, fixed, absolute, sticky?

visibility

Esta propiedad controla si el elemento será visualizado según le asignes el valor visible o hidden. Debes tener en cuenta que, aunque un elemento no sea visible, éste continúa ocupando su espacio en el flujo normal del documento al contrario de lo que ocurría con la propiedad display cuando se le asignaba el valor none.

¿Qué diferencia hay entre visibility:hidden y display:none?

z-index

Permite controlar el orden en el que se presentan los elementos que quedan solapados por efecto de otras propiedades. Si cuando definimos algún elemento con posición absoluta, éste tiene que visualizarse en el mismo lugar ocupado por otro elemento, se producirá una superposición de elementos visualizándose, en la parte coincidente, sólo el que está ocupando la “posición superior”. La propiedad z-index permite especificar el orden en el eje z de los elementos, esto es, el orden de apilamiento en capas del documento.

Por defecto, los elementos se apilan en el orden en que aparecen: el elemento situado más abajo en el flujo normal del documento quedará encima. Si quieres que esta posición no sea tenida en cuenta, debes saber que los elementos con un valor mayor de la propiedad z-index son colocados encima de los que tienen un valor menor z-index, quedando estos últimos tapados por los primeros.

alt text

También debes saber que esta propiedad sólo se aplica a elementos que tengan la propiedad position en absolute o en relative.

¿Qué es el z-index?

¿Qué ocurre si pongo un z-index: 99999 a un elemento cualquiera?

¿Se puede un z-index negativo?

overflow

La propiedad overflow define cómo se maneja el contenido que excede el tamaño del contenedor.

La propiedad overflow (desbordamiento en español) establece el comportamiento de desbordamiento. Es similar al menú de Google Sheets que se ve en la siguiente Figura.

Overflow o desbordamiento en Google Sheet Overflow o desbordamiento en Google Sheet

Se puede definir tanto el overflow tanto en el eje X como en el eje Y con las propiedades overflow-x y overflow-y respectivamente.

¿Se puede definir un overflow horizontal y vertical por separado?

(Voluntario) Lee el artículo Desbordamiento (Overflow).

clip-path

Hace algún tiempo, existió una propiedad CSS llamada clip, cuya intención era permitir recortes con ciertas formas como rectángulos. Sin embargo, hoy en día ha sido marcada como obsoleta, en favor de una nueva propiedad llamada clip-path.

(Voluntario) Lee el artículo La propiedad clip-path.

Pero... ¿cómo se centra un div?

Bibliografía

Este artículo está licenciado bajo CC BY 4.0 por el autor.

Tarea obligatoria: Introducción a CSS

Selectores en CSS