Cómo alinear verticalmente elementos con CSS usando Flexbox... y cómo se hacía antes de que Flexbox existiera, mediante algunos hacks de CSS que nos permitían llegar a soluciones alternativas cuando no existía el alineamiento vertical.
En este artículo vamos a ofrecer varias técnicas para alineación vertical. Lo haremos de manera retrospectiva, porque este tema de la alineación vertical siempre fue un problema en CSS y la mayoría de las situaciones relatadas aquí han sido resueltas gracias a Flexbox.
De todos modos, para mostrar rápidamente a las soluciones más fáciles y actuales vamos a explicar la solución basada en Flexbox, que es la que recomendamos. Más adelante en esta misma página encontrarás otras posibilidades para alinear verticalmente y los motivos por los que antes era un problema, en CSS2 y anteriores especificaciones.
En el artículo veremos varios mecanismos para la Alineación vertical con CSS.
Alinear verticalmente con Flexbox
Hoy alinear verticalmente con CSS no es un problema gracias a Flexbox. Flexbox es una especificación de CSS relativamente nueva y ofrece una forma sencilla pero avanzada para distribuir el espacio entre los elementos de una página web, de manera vertical u horizontal
Una de las ventajas de Flexbox es la capacidad de alinear verticalmente los elementos en la página o en sus contendores, pero en realidad el estándar ofrece muchas facilidades. Te recomendamos aprender en el Manual de Flexbox, porque aquí solo nos vamos a limitar a hablar de la alineación vertical de los elementos.
Para poder tener un elemento con flexbox simplemente le ponemos el atributo display: flex a un elemento.
.elemento {
display: flex;
}
Para alinear verticalmente con Flexbox, primero debemos entender algunos conceptos importantes.
Eje principal en Flexbox
El eje en flexbox puede ser tanto hoizontal (cuando los elementos se colocan en una fila) como vertical (cuando los elementos se colocan en una columna).
flex-direction: row
indica que los elementos se pondrán en una fila, así pues, el eje principal es la horizontal. Esta es la distribución predeterminada de Flexbox.flex-direction: column
indica que los elementos se coloquen en una columna, por tanto el eje principal es la vertical
Es importante saber que las propiedades para alinear verticalmente con Flexbox pueden cambiar dependiendo del eje principal de los elementos.
Propiedades para alineación vertical con Flexbox
Ahora las dos propiedades de flexbox que nos pueden aportar alineación vertical
- align-items: Esta propiedad define cómo se alinean los elementos a lo largo del eje contrario al principal (el eje transversal o perpendicular al eje principal del contenedor flex). En un contenedor con
flex-direction: row;
, esta propiedad afecta la alineación vertical. - justify-content: Esta propiedad define cómo se alinean los elementos en el eje principal del contenedor. En un contenedor con
flex-direction: row;
, esta propiedad afecta la alineación horizontal, pero si lo cambias porflex-direction: column;
,justify-content
afectará la alineación vertical.
Ejemplos de alineación vertical con Flexbox:
Vamos a partir de este código HTML:
<div class="contenedor">
<div class="elemento">Uno</div>
<div class="elemento">Dos</div>
<div class="elemento">Tres</div>
</div>
En este primer ejemplo vamos a centrar verticalmente un todo el contenido del contenedor flex:
.contenedor {
display: flex;
background-color: #ddd;
height: 300px;
align-items: center;
}
.elemento {
padding: 0.5rem;
background-color: #ffc;
margin: 0.5rem;
}
Tienes que establecer un
height
en el contenedor para marcar una altura suficiente para ver el efecto de alineación vertical. Si no hay una altura definida, o no es suficientemente grande, el contenedor se adaptará al contenido, lo que podría hacer que la alineación vertical no sea apreciable.
En este caso hemo usado align-items
para marcar la alineación vertical ya que la distribución de los elementos será la fila (el eje principal es la horizontal).
El efecto de esta alineación vertical sería como vemos en la siguiente imagen:
Ahora veamos un segundo ejemplo de CSS que realizaría la alineación vertical en elementos que se van a colocar en columnas.
.contenedor {
display: flex;
flex-direction: column;
background-color: #ddd;
height: 300px;
justify-content: center;
}
.elemento {
padding: 0.5rem;
background-color: #ffc;
margin: 0.5rem;
}
En este caso se usa justify-content
debido a que el eje principal es la vertical, ya que los elementos se están distribuyendo en la columna.
El efecto resultante sería el que se puede ver en la siguiente imagen:
Hemos visto solamente algo esencial de todo lo que ofrece Flexbox. Tienes muchos otros valores tanto para
justify-content
como paraalign-items
comospace-between
ospace-around
que te pueden aportar mucha más versatilidad a las alineaciones.
Problema de la alineación vertical antes de Flexbox
Al principio de la web la maquetación se realizaba por tablas. Para las celdas de las tablas existe un atributo HTML llamado valign que nos permitía alinear verticalmente.
<table>
<tr>
<td valing="middle" style="border: 1px solid red; height: 60px;">lalala</td>
</tr>
</table>
Cuando teníamos un contenido dentro de una celda de una tabla utilizábamos el atributo valign="middle"
para alinearlo al centro vertical de la celda. Ese atributo daba respuesta a la alineación vertical de los elementos, sin embargo ahora tenemos dos problemas:
- Primero y fundamental: no se deben usar tablas para maquetar
- También muy importante: no se deben especificar atributos HTML para cambiar el estilo de los elementos.
Dada la existencia de ese atributo, resulta extraño que con CSS 2 no se hubiése pensado una manera de alinear verticalmente un contenido en un contenedor que no sea una celda de una tabla.
Entonces, dado que las versiones de CSS 2 y anteriores no se había incorporado una forma de definir la alineación vertical de los elementos, los diseñadores y maquetadores sentían una carencia especial. Ese atributo es necesario, por lo menos en algunas ocasiones, para realizar nuestro trabajo de maquetación si no se usan tablas.
Todo eso nos llevaba a buscar una manera de alinear verticalmente un contenido en una capa, para lo que era necesario utilizar algún truco para conseguirlo.
Alinear verticalmente con line-height
Si los elementos que queremos alinear se componen de una sola línea, el mecanismo más sencillo es usar el atributo line-height
, colocando su valor igual que la altura del contenedor que se pretende alinear.
<div class="contenedor">
texto de una sola línea
</div>
Con este CSS alineamos el texto al centro de la vertical.
.contenedor {
background-color: #ddd;
height: 300px;
line-height: 300px;
}
Sin embargo, este truco no vale si tienes texto que puede ocupar varias líneas.
Alinear verticalmente con display: table
Antes de Flexbox también se usaba el truco de display: table para alinear verticalmente. Gracias a que un contenedor se puede comportar como una celda de una tabla, es posible usar el atributo vertical-align: middle
de CSS.
En este caso conseguimos alinear verticalmente un contenido que puede ocupar varias líneas, solo que el ejemplo se complica bastante y hace falta un HTML más complejo, ya que debemos usar varios display: display: table
, display: table-row
y display: table-cell
.
Actualmente nunca recomendaríamos esta solución. Es una técnica anterior a Flexbox y Grid que se empleaba para simular el comportamiento de las tablas en la maquetación de páginas web.
<div class="table-container">
<div class="table-cell">
<div class="content">
<p>¡Estoy centrado verticalmente!</p>
<p>Puede haber un contenido de varias líneas</p>
</div>
</div>
</div>
Ahora podemos ver el CSS necesario para que se consiga una alineación vertical del contenido del contenedor con class="content"
.
.table-container {
display: table;
width: 100%;
height: 300px; /* Establece la altura para que se pueda ver el efecto de centrado vertical */
border: 1px solid #000; /* Solo para verse el contenedor de tabla */
}
.table-cell {
display: table-cell;
vertical-align: middle; /* Esta propiedad se encarga de centrar verticalmente el contenido */
}
.content {
width: 80%;
padding: 10px;
text-align: center;
background-color: #eee;
}
En el ejemplo tenemos el contenedor .table-container
, que se comporta como una tabla, mientras que .table-cell
hace que se comporte como una celda de la tabla. El uso de vertical-align: middle
en .table-cell
permite que el contenido se centre verticalmente dentro de ese "contenedor table-cell".
Hack basado en la alineación vertical de las imágenes
Ahora presentaré un hack CSS para alineación vertical de elementos en las páginas. Los llamados hack CSS son como trucos para definir estilos que dan problemas en distintos navegadores o no existen maneras de definirlos con las herramientas actuales de CSS. Explicamos y dimos ejemplos de hacks CSS en un artículo anterior.
Vamos a mostrar un truco sencillo para alinear verticalmente con CSS utilizando una imagen. Aprovecharemos que la imagen tiene un atributo vertical-align:middle; que sirve para que el texto que hay después de la imagen esté alineado a su mitad vertical.
Entonces haremos algo como esto.
Definimos los estilos para una imagen:
img.valign {
height: 100%;
vertical-align: middle;
width: 0px;
}
En los estilos de la imagen definimos que tenga height 100% para adaptarse a la altura del contenedor donde la hayamos metido. vertical-align:middle sirve para que el texto que haya antes o después de la imagen. El atributo width: 0px nos sirve simplemente para que la imagen no tenga anchura, puesto que no queremos mostrar ninguna imagen ni que esta tome espacio en la página, sólo queremos alinear verticalmente.
Ahora podremos crear una capa con un contenido alineado en la vertical, de esta manera:
<div style='height:330px; background-color: #ccccff;'>
Contenido alineado verticalmente. <img class="valign" />
</div>
La etiqueta DIV puede tener la altura que deseemos. El color de fondo simplemente lo he colocado para que se vean sus límites.
Podemos ver la imagen que se ha colocado dentro de la capa, que tiene class definida en el css anterior. No tiene src ni nada, pues no necesitamos colocarlo porque no queremos mostrar ningún archivo como imagen.
El ejemplo funciona perfectamente en navegadores muy antiguos como Internet Explorer, con lo que es un hack css perfectamente usable. Aunque como decimos, habiendo lanzado flexbox no es muy recomendable.
Lo malo es que esta alineación vertical sólo funcionará en caso que el contenido de la capa no supere una línea. En el momento que el texto de la capa tenga varias líneas, sólo se alineará verticalmente una de ellas, la primera o la última, dependiendo de donde se haya colocado la imagen, delante o detrás del texto.
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...