Cómo alinear cosas en CSS
Publicado: 2022-03-10Tenemos toda una selección de formas de alinear las cosas en CSS hoy en día, y no siempre es una decisión obvia cuál usar. Sin embargo, saber lo que está disponible significa que siempre puedes probar algunas tácticas si te encuentras con un problema de alineación en particular.
En este artículo, echaré un vistazo a los diferentes métodos de alineación. En lugar de proporcionar una guía completa para cada uno, explicaré algunos de los puntos conflictivos que tienen las personas y señalaré referencias más completas para las propiedades y los valores. Al igual que con gran parte de CSS, puede recorrer un largo camino al comprender las cosas fundamentales sobre cómo se comportan los métodos y luego necesita un lugar para buscar los detalles más finos en términos de cómo lograr el diseño preciso que desea.
Alineación de texto y elementos en línea
Cuando tenemos texto y otros elementos en línea en una página, cada línea de contenido se trata como un cuadro de línea. La propiedad text-align
alineará ese contenido en la página, por ejemplo, si desea que su texto esté centrado o justificado. A veces, sin embargo, es posible que desee alinear las cosas dentro de ese cuadro de línea con otras cosas, por ejemplo, si tiene un icono que se muestra junto al texto o texto de diferentes tamaños.
En el siguiente ejemplo, tengo un texto con una imagen en línea más grande. Estoy usando vertical-align: middle
en la imagen para alinear el texto con el centro de la imagen.
La propiedad line-height
y la alineación
Recuerde que la propiedad line-height
cambiará el tamaño del cuadro de línea y, por lo tanto, puede cambiar su alineación. El siguiente ejemplo usa un valor de altura de línea grande de 150 px, y he alineado la imagen en la top
. La imagen se alinea con la parte superior del cuadro de línea y no con la parte superior del texto, elimine esa altura de línea o hágala menor que el tamaño de la imagen y la imagen y el texto se alinearán en la parte superior del texto.
Resulta que line-height
y, de hecho, el tamaño del texto es bastante complicado, y no voy a entrar en esa madriguera de conejo en este artículo. Si está tratando de alinear con precisión los elementos en línea y desea comprender realmente lo que está sucediendo, le recomiendo leer "Deep Dive CSS: Font Metrics, line-height
And vertical-align
".
¿Cuándo puedo usar la propiedad vertical-align
?
La propiedad vertical-align
es útil si está alineando cualquier elemento en línea. Esto incluye elementos con display: inline-block
. El contenido de las celdas de la tabla también se puede alinear con la propiedad vertical-align
.
La propiedad vertical-align
no tiene efecto en los elementos de cuadrícula o flex y, por lo tanto, si se usa como parte de una estrategia alternativa, dejará de aplicarse en el momento en que el elemento principal se convierta en un contenedor de cuadrícula o flex. Por ejemplo, en el siguiente bolígrafo, tengo un conjunto de elementos dispuestos con display: inline-block
y esto significa que puedo alinear los elementos incluso si el navegador no tiene Flexbox:
En el próximo bolígrafo, he tratado el inline-block
como una alternativa para el diseño Flex. Las propiedades de alineación ya no se aplican y puedo agregar align-items
de alineación para alinear los elementos en Flexbox. Puede notar que el método Flexbox está en juego porque la brecha entre los elementos que obtendrá al usar display: inline-block
se ha ido.
El hecho de que vertical-align
funcione en las celdas de la tabla es la razón por la que funciona el truco para centrar verticalmente un elemento usando display: table-cell
.
Ahora que tenemos mejores formas de alinear cuadros en CSS (como veremos en la siguiente sección), no necesitamos emplear las propiedades de alineación vertical-align
text-align
en lugares que no sean los elementos en línea y de texto para que fueron diseñados. Sin embargo, siguen siendo completamente válidos para usar en esos formatos de texto y en línea, así que recuerda que si estás tratando de alinear algo en línea, son estas propiedades y no las de Alineación de cuadro las que debes alcanzar.
Alineación de caja
La especificación de alineación de cajas se ocupa de cómo alineamos todo lo demás. La especificación detalla las siguientes propiedades de alineación:
-
justify-content
-
align-content
-
justify-self
-
align-self
-
justify-items
-
align-items
Es posible que ya piense en estas propiedades como parte de la especificación Flexbox, o quizás de Grid. La historia de las propiedades es que se originaron como parte de Flexbox y aún existen en la especificación de Nivel 1; sin embargo, se trasladaron a su propia especificación cuando se hizo evidente que eran más útiles en general. Ahora también los usamos en el Diseño de cuadrícula, y también se especifican para otros métodos de diseño, aunque la compatibilidad actual del navegador significa que no podrá usarlos todavía.
Por lo tanto, la próxima vez que alguien en Internet le diga que la alineación vertical es la parte más difícil de CSS, puede decirle esto (que incluso cabe en un tweet):
.container { display: flex; align-items: center; justify-content: center; }
En el futuro, es posible que incluso podamos prescindir de display: flex
, una vez que se implementen las propiedades de Alineación de cuadro para Diseño de bloque. Por el momento, sin embargo, hacer que el padre de lo que deseas centre un contenedor flexible es la forma de obtener la alineación horizontal y vertical.
Los dos tipos de alineación
Al alinear elementos flexibles y de rejilla, tiene dos cosas posibles para alinear:
- Tienes el espacio libre en la cuadrícula o contenedor flexible (una vez que se han dispuesto los elementos o las pistas).
- También tiene el elemento dentro del área de la cuadrícula en la que lo colocó, o en el eje transversal dentro del contenedor flexible.
Le mostré un conjunto de propiedades arriba, y las propiedades de alineación se pueden considerar como dos grupos. Los que se ocupan de la distribución del espacio libre y los que alinean el artículo en sí.
Tratar con espacio libre: align-content
y justify-content
Las propiedades que terminan en -content
tienen que ver con la distribución del espacio, por lo que cuando elige usar align-content
o justify-content
, está distribuyendo el espacio disponible entre las pistas de la cuadrícula o los elementos flexibles. No cambian el tamaño de los elementos flexibles o de cuadrícula en sí mismos; los mueven porque cambian el lugar donde va el espacio libre.
A continuación, tengo un ejemplo de flexión y un ejemplo de cuadrícula. Ambos tienen un contenedor que es más grande de lo necesario para mostrar los elementos flexibles o las pistas de la cuadrícula, por lo que puedo usar align-content
y justify-content
para distribuir ese espacio.
Mover elementos alrededor: justify-self
, align-self
, justify-items
y align-items
Luego tenemos align-self
y justify-self
aplicados a elementos flexibles o de cuadrícula individuales; también puede usar align-items
justify-items
en el contenedor para establecer todas las propiedades a la vez. Estas propiedades se ocupan del elemento de cuadrícula o flex real, es decir, mover el contenido dentro del área de cuadrícula o línea flexible.
- Diseño de cuadrícula
Obtiene ambas propiedades, ya que puede cambiar el elemento en el bloque y el eje en línea, ya que tenemos un área de cuadrícula definida en la que se encuentra. - Diseño flexible
Solo puede alinear en el eje transversal ya que el eje principal está controlado solo por la distribución del espacio. Entonces, si sus artículos están en una fila, puede usaralign-self
para moverlos hacia arriba y hacia abajo dentro de la línea flexible, alineándolos entre sí.
En mi ejemplo a continuación, tengo un contenedor flexible y de cuadrícula, y estoy usando align-items
y align-self
en Flexbox para mover los elementos hacia arriba y hacia abajo uno contra el otro en el eje transversal. Si usa Firefox e inspecciona el elemento con Firefox Flexbox Inspector, puede ver el tamaño del contenedor flexible y cómo los elementos se mueven verticalmente dentro de él.
En la cuadrícula, puedo usar las cuatro propiedades para mover los elementos dentro de su área de cuadrícula. Una vez más, el Grid Inspector de Firefox DevTools será útil cuando juegues con la alineación. Con las líneas de cuadrícula superpuestas, puede ver el área dentro de la cual se mueve el contenido:
Experimente con los valores en la demostración de CodePen para ver cómo puede cambiar el contenido en cada método de diseño:
Confundido por align
y justify
Uno de los problemas citados con las personas que recuerdan las propiedades de alineación en Grid y Flexbox es que nadie puede recordar si alinear o justificar. ¿Qué dirección es cuál?
Para el diseño de cuadrícula, necesita saber si está alineando en la dirección de bloque o en línea. La dirección del Bloque es la dirección de los bloques dispuestos en su página (en su modo de escritura), es decir, para el inglés que es vertical. La dirección Inline es la dirección en la que se ejecutan las oraciones (por lo tanto, para el inglés, es de izquierda a derecha horizontalmente).
Para alinear cosas en la dirección del bloque, utilizará las propiedades que comienzan con align-
. Utiliza align-content
para distribuir el espacio entre las pistas de la cuadrícula, si hay espacio libre en el contenedor de la cuadrícula, y align-items
o align-self
para mover un elemento dentro del área de la cuadrícula en la que se ha colocado.
El siguiente ejemplo tiene dos diseños de cuadrícula. Uno tiene writing-mode: horizontal-tb
(que es el predeterminado para inglés) y el otro writing-mode: vertical-rl
. Esta es la única diferencia entre ellos. Puede ver que las propiedades de alineación que he aplicado funcionan exactamente de la misma manera en el eje del bloque en ambos modos.
Para alinear las cosas en la dirección en línea, use las propiedades que comienzan con justify-
. Utilice justify-content
para distribuir el espacio entre las pistas de la cuadrícula y justify-items
justify-self
para alinear los elementos dentro de su área de la cuadrícula en la dirección en línea.
Una vez más, tengo dos ejemplos de diseño de cuadrícula para que pueda ver que en línea siempre está en línea, sin importar qué modo de escritura esté usando.
Flexbox es un poco más complicado debido al hecho de que tenemos un eje principal que se puede cambiar a row
o column
. Entonces, primero pensemos en ese eje principal. Se establece con la propiedad flex-direction
. El valor inicial (o predeterminado) de esta propiedad es row
, que colocará los elementos flexibles como una fila en el modo de escritura actualmente en uso; por eso, cuando trabajamos en inglés, terminamos con elementos dispuestos horizontalmente cuando creamos un contenedor flexible. Luego puede cambiar el eje principal a flex-direction: column
y los elementos se distribuirán como una columna, lo que significa que se distribuirán en la dirección del bloque para ese modo de escritura.
Como podemos hacer este cambio de eje, el factor más importante en Flexbox es preguntar: "¿Qué eje es mi eje principal?" Una vez que sepa eso, entonces para la alineación (cuando esté en su eje principal) simplemente use justify-content
. No importa si su eje principal es fila o columna. Usted controla el espacio entre los elementos flexibles con justify-content
.
En el eje transversal, puede usar align-items
que alinearán los elementos dentro del contenedor flexible o la línea flexible en un contenedor flexible de varias líneas. Si tiene un contenedor de varias líneas que usa flex-wrap: wrap
y tiene espacio en ese contenedor, puede usar align-content
para distribuir el espacio en el eje transversal.
En el siguiente ejemplo, estamos haciendo ambas cosas con un contenedor flexible que se muestra como una fila y una columna:
Cuando justify-content
o align-content
no funciona
Las propiedades de justify-content
y align-content
en Grid y Flexbox tienen que ver con la distribución de espacio adicional . Entonces, lo que debe verificar es que tenga espacio adicional.
Aquí hay un ejemplo de Flex: configuré flex-direction: row
y tengo tres elementos. No ocupan todo el espacio en el contenedor flexible, por lo que tengo espacio libre en el eje principal, el valor inicial para justify-content
es flex-start
por lo que todos mis artículos se alinean al principio y el espacio adicional está al final. Estoy usando Firefox Flex Inspector para resaltar el espacio.
Si cambio flex-direction a space-between
, ese espacio adicional ahora se distribuye entre los elementos:
Si ahora agrego más contenido a mis elementos para que se vuelvan más grandes y ya no haya espacio adicional, justify-content
no hace nada, simplemente porque no hay espacio para distribuir.
Una pregunta común que me hacen es por qué justify-content
no funciona cuando flex-direction
es column
. Esto generalmente se debe a que no hay espacio para distribuir. Si toma el ejemplo anterior y lo convierte en flex-direction: column
, los elementos se mostrarán como una columna, pero no habrá espacio adicional debajo de los elementos como lo hay cuando hace flex-direction: row
. Esto se debe a que cuando crea un contenedor flexible con display: flex
, tiene un contenedor flexible a nivel de bloque; esto ocupará todo el espacio posible en la dirección en línea. En CSS, las cosas no se estiran en la dirección del bloque, por lo que no hay espacio adicional.
Agregue una altura al contenedor y, siempre que sea más de lo necesario para mostrar los elementos, tendrá espacio adicional y, por lo tanto justify-content
funcionará en su columna.
¿Por qué no hay justify-self
en Flexbox?
Grid Layout implementa todas las propiedades para ambos ejes porque siempre tenemos dos ejes con los que lidiar en Grid Layout. Creamos pistas (que pueden dejar espacio adicional en el contenedor de cuadrícula en cualquiera de las dimensiones) y podemos distribuir ese espacio con align-content
o justify-content
. También tenemos Áreas de Cuadrícula, y es posible que el elemento en esa área no ocupe todo el espacio del área, por lo que podemos usar align-self
o justify-self
para mover el contenido alrededor del área (o align-items
justify-items
para cambiar la alineación de todos los elementos).
Flexbox no tiene pistas en la forma en que lo hace el diseño de cuadrícula. En el eje principal, lo único que tenemos que jugar es la distribución del espacio entre los elementos. No existe el concepto de una pista en la que se coloca un elemento flexible. Por lo tanto, no se crea un área en la que mover el elemento. Es por eso que no hay una propiedad justify-self
en los ejes principales de Flexbox.
A veces, sin embargo, desea poder alinear un elemento o parte del grupo de elementos de una manera diferente. Un patrón común sería una barra de navegación dividida con un elemento separado del grupo. En esa situación, la especificación aconseja el uso de márgenes automáticos.
Un margen automático ocupará todo el espacio en la dirección en que se aplica, por lo que podemos centrar un bloque (como el diseño de nuestra página principal) usando un margen izquierdo y derecho de automático. Con un margen automático en ambos lados, cada margen intenta ocupar todo el espacio y así empuja el bloque hacia el centro. Con nuestra fila de elementos flexibles, podemos agregar margin-left: auto
al elemento en el que queremos que ocurra la división, y siempre que haya espacio disponible en el contenedor flexible, obtendrá una división. Esto funciona bien con Flexbox porque tan pronto como no hay espacio disponible, los elementos se comportan como lo hacen los elementos flexibles regulares.
Flexbox y microcomponentes
Una de las cosas que creo que a menudo se pasa por alto es lo útil que es Flexbox para hacer pequeños trabajos de diseño, donde podría pensar que usar vertical-align
es el camino a seguir. A menudo uso Flexbox para obtener una alineación ordenada de patrones pequeños; por ejemplo, alinear un ícono al lado del texto, alinear dos cosas con diferentes tamaños de fuente en la línea de base, o hacer que los campos y botones del formulario se alineen correctamente. Si tiene dificultades para que algo se alinee bien con vertical-align
, quizás intente hacer el trabajo con Flexbox. Recuerda que también puedes crear un contenedor flexible en línea si lo deseas con display: inline-flex
.
No hay razón para no usar Flexbox, o incluso Grid para pequeños trabajos de diseño. No son solo para grandes porciones de diseño. Pruebe las diferentes cosas disponibles para usted y vea qué funciona mejor.
Las personas a menudo están muy interesadas en saber cuál es la forma correcta o incorrecta de hacer las cosas. En realidad, a menudo no hay bien o mal; una pequeña diferencia en su patrón podría significar la diferencia entre que Flexbox funcione mejor, donde de lo contrario usaría vertical-align
.
Terminando
Para concluir, tengo un breve resumen de los conceptos básicos de la alineación. Si recuerda estas pocas reglas, debería poder alinear la mayoría de las cosas con CSS:
- ¿Estás alineando texto o un elemento en línea? Si es así, debe usar
text-align
,vertical-align
yline-height
. - ¿Tiene un elemento o elementos que desea alinear en el centro de la página o contenedor? Si es así, haga que el contenedor sea un contenedor flexible y luego configure
align-items: center
yjustify-content: center
. - Para diseños de cuadrícula, las propiedades que comienzan con
align-
funcionan en la dirección del bloque; aquellos que comienzan conjustify-
funcionan en la dirección en línea. - Para Flex Layouts, las propiedades que comienzan con
align-
funcionan en Cross Axis; las que empiezan porjustify-
trabajan sobre el eje principal. - Las propiedades
justify-content
yalign-content
distribuyen espacio extra. Si no tiene espacio adicional en su contenedor flexible o de rejilla, no harán nada. - Si cree que necesita
justify-self
en Flexbox, entonces usar un margen automático probablemente le dará el patrón que está buscando. - Puede usar Grid y Flexbox junto con las propiedades de alineación para pequeños trabajos de diseño, así como componentes principales: ¡experimente!
Para obtener más información sobre la alineación, consulte estos recursos:
- Alineación de cuadro CSS (documentos web de MDN)
- Todo lo que necesita saber sobre la alineación en Flexbox
- Hoja de referencia de alineación de cajas