Curso de CSS / Flexbox: alineación, saltos de línea y tamaños flexibles

Flexbox combina alineación, ajuste y dimensionamiento flexible para acomodar elementos en el espacio disponible. justify-content funciona a lo largo del eje principal, align-items alinea los elementos en el eje transversal y align-content distribuye el grupo de líneas en contenedores que admiten saltos cuando queda espacio transversal.

Empareja las propiedades de alineación con sus ejes

Propiedad Aplicable a Condiciones a verificar
justify-content Distribución de los elementos a lo largo del eje principal del contenedor Espacio restante después de establecer el tamaño del elemento
align-items Alineación a lo largo del eje transversal de cada elemento Tamaño del eje transversal del elemento y tamaño de la línea flex
align-self Alineación a lo largo del eje transversal de elementos específicos Cambiar individualmente la alineación por defecto del contenedor
align-content Alineación del grupo de líneas Contenedores con flex-wrap: wrap o wrap-reverse y espacio restante en el eje transversal
gap Espaciado entre elementos/líneas adyacentes Espacio y división añadidos por la alineación

Con escritura horizontal de izquierda a derecha y flex-direction: row, justify-content controla principalmente lo horizontal, y align-items controla principalmente lo vertical. Si cambias flex-direction a column, el eje principal se vuelve vertical y la dirección física de las dos propiedades también cambia. En particular, debe quedar espacio en la altura del contenedor para comparar el justify-content con column. Si la altura se ajusta perfectamente al contenido, casi no hay espacio para moverse incluso si cambias a center o space-between. La dirección del eje y la configuración de inicio del contenedor Flex se pueden consultar en fundamentos de Flexbox: contenedores, elementos y ejes.

justify-content: center coloca un grupo de elementos en el centro, y space-between coloca el primer y el último elemento en ambos extremos y divide el espacio entre ellos. gap es el espacio especificado, y space-between distribuye el espacio restante. Cuando se usan juntos, el espacio real puede ser mayor que el gap. Si el flex-grow de un elemento usa todo el espacio restante o el margen automático en la dirección del eje principal ocupa espacio, el cambio en justify-content puede no ser visible.

align-items: center alinea los elementos de diferentes alturas al centro dentro de una línea. align-content: center centra todas las líneas en el eje transversal. No debes pensar que ambos son la misma función. align-content no tiene efecto en contenedores de una sola línea que son nowrap, e incluso en contenedores wrap, si el tamaño ocupado por las líneas y la altura del contenedor son iguales, no hay espacio para la comparación. Puedes consultar las condiciones de aplicación en la guía de alineación de Flexbox de MDN.

Compara la alineación de elementos y la alineación de líneas

Guarda el siguiente código como flex-align.html y ábrelo. La primera sección tiene tres elementos de diferentes alturas, la segunda tiene cuatro elementos que forman dos filas si dispone de al menos 320px de anchura exterior. Con menos espacio pueden formar cuatro filas. La altura de 280px deja espacio para desplazar el grupo cuando su contenido cabe.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>flex-align.html</title>
  <style>
* { box-sizing: border-box; }
body { margin: 16px; font: 16px/1.6 sans-serif; color: #243447; }
h1 { font-size: 24px; } h2 { font-size: 20px; margin-top: 32px; }
a { color: #145f8f; } a:focus-visible { outline: 3px solid #b4470b; outline-offset: 3px; }
.toolbar { display: flex; gap: 12px; justify-content: space-between; align-items: center;
 width: 100%; max-width: 640px; min-height: 120px; border: 2px solid #789; padding: 12px; }
 .toolbar > div { padding: 8px; background: #dceefa; }
 .lines { display: flex; flex-wrap: wrap; gap: 12px; width: min(100%, 360px); height: 280px;
 align-items: center; align-content: flex-start; border: 2px solid #789; padding: 12px; }
 .lines > div { flex: 0 0 140px; padding: 8px; background: #e8f5de; }
 .tall { min-height: 60px; }
  </style>
</head>
<body>
<h1>Alignment on one line and multiple lines</h1>
<h2>Toolbar</h2><div class="toolbar"><div>Short item</div><div>Two-line item<br>Second line</div><div>Button position</div></div>
<h2>Line group</h2><div class="lines"><div>1</div><div class="tall">2<br>Second line</div><div>3</div><div class="tall">4<br>Second line</div></div>
</body>
</html>
  1. Cambia justify-content de .toolbar a center para ver si los tres elementos se juntan en el centro. Compara también con flex-start y vuelve a space-between. Deja el tamaño de los elementos y el espacio tal como están.
  2. Cambia align-items en .toolbar a flex-start para asegurarte de que se alinee en la parte superior. Si lo cambias a stretch, los elementos con tamaño automático en el eje transversal aumentarán. Después de la comparación, restaura center.
  3. Cambia solo el align-content de .lines a center. Con dos filas y espacio transversal sobrante, el grupo baja mientras mantiene las relaciones de los elementos de cada línea. Si vuelves a flex-start y solo cambias align-items a flex-start, la posición de los elementos cortos en cada línea cambiará.
  4. Si solo cambias el flex-wrap en .lines a nowrap, todo tratará de mantenerse en una línea, y los elementos de este ejemplo tienen flex-shrink: 0, causando que se desborde horizontalmente. En este estado, no puedes alinear múltiples líneas con align-content. Después de la confirmación, restáuralo a wrap.

Comprende grow, shrink y basis

flex: 1 1 192px especifica flex-grow, flex-shrink y flex-basis, en ese orden. La base es el tamaño estándar desde el cual se empieza la distribución espacial del eje principal y no es un valor que garantice el ancho final. flex-grow es el factor de ampliación para el espacio restante, y flex-shrink es el factor de reducción cuando el espacio es insuficiente. Dado que existe una regla de valor omitido para números individuales o auto en la notación abreviada, se especifican tres valores y se comparan en el ejemplo de aprendizaje.

declaración Cuando queda espacio Cuando se acaba el espacio
flex: 0 1 192px Mantener tamaño estándar Participar en la reducción
flex: 1 1 192px El espacio restante se distribuye Participar en la reducción
flex: 0 0 192px Mantener tamaño estándar Sin reducción. Si es nowrap, puede desbordarse.

Por ejemplo, si un contenedor con un ancho de contenido de 640px contiene tres elementos con tamaño base de 100px y dos espacios (cada uno de 20px), el espacio restante es 640 − 300 − 40 = 300px. Si la proporción de crecimiento es 1:2:1, el espacio añadido será de 75px, 150px y 75px, y el ancho final será de 175px, 250px y 175px. Este es un cálculo de condiciones que no involucran el tamaño mínimo del contenido ni restricciones min/max.

La cantidad de contracción no se distribuye de manera uniforme basándose únicamente en el número de contracción. Considera tanto la proporción de reducción como el tamaño de referencia. Si necesitamos reducir 60px de dos elementos con tamaños estándar de 200px y 100px y ambos con contracción de 1, entonces, en condiciones simples sin restricciones, reduciríamos 40px y 20px. Los resultados pueden variar si hay relleno, bordes, tamaño mínimo de contenido, etc., por lo que realmente deberías verificar los valores aplicados. La descripción de flex de MDN explica la notación abreviada y las condiciones de tamaño.

Distribuye espacio y permite saltos entre tarjetas

Guarda el siguiente código como flex-size.html. El área de cálculo corresponde al cálculo anterior creando un ancho máximo de 640px sin ningún relleno o borde adicional. La lista de tarjetas utiliza un ancho de 192px como estándar para los saltos de línea, pero llena el espacio restante. Si una lista con list-style: none está fuera de nav, es posible que no se reconozca como una lista en el árbol de accesibilidad de Safari. En el ejemplo, ul especifica role="list" para especificar el rol de la lista. Las condiciones de accesibilidad al eliminar viñetas y espaciado también se describen en estilos de párrafos y listas con CSS.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>flex-size.html</title>
  <style>
* { box-sizing: border-box; }
body { margin: 16px; font: 16px/1.6 sans-serif; color: #243447; }
h1 { font-size: 24px; } h2 { font-size: 20px; margin-top: 32px; }
a { color: #145f8f; } a:focus-visible { outline: 3px solid #b4470b; outline-offset: 3px; }
.calc { display: flex; gap: 20px; width: min(100%, 640px); background: #eef2f6; }
 .calc > div { flex: 1 1 100px; min-width: 0; height: 80px; background: #dceefa; }
 .calc > div:nth-child(2) { flex-grow: 2; }
 .cards { display: flex; flex-wrap: wrap; gap: 16px; list-style: none; padding: 0; }
 .cards > li { flex: 1 1 192px; min-width: 0; padding: 16px; background: #e8f5de; overflow-wrap: anywhere; }
  </style>
</head>
<body>
<h1>Flex values ​​and space distribution</h1><div class="calc"><div>grow 1</div><div>grow 2</div><div>grow 1</div></div>
<h2>Wrapping card</h2><ul class="cards" role="list"><li>First card</li><li>Second card</li><li>Third card</li><li>Fourth card</li></ul>
</body>
</html>
  1. Expande tu navegador para que el .calc tenga un ancho de 640px y usa las herramientas de desarrollo para verificar los anchos de los tres elementos. Será 175px·250px·175px. Si solo cambias el grow del segundo elemento a 1, los tres elementos se volverán de 200px cada uno. Después de la comparación, restáuralo a 2.
  2. Solo cambia el grow en .cards > li a 0 para asegurarte de que la última fila de tarjetas no llene el ancho extra. Si lo restauras a 1, la última línea también recibirá espacio.
  3. Reduce el ancho de la pantalla para ver si caben menos tarjetas en una fila. wrap determina en qué líneas colocar los elementos, y cada línea distribuye el espacio restante por separado. Los anchos de las tarjetas de la última fila y la fila anterior no necesariamente coinciden.
  4. Para ver un desbordamiento de una sola línea en lugar de un salto de línea, cambia flex-wrap a nowrap y la declaración flex de los elementos a flex: 0 0 192px. Después de comprobar las dos condiciones, restaura el wrap original y 1 1 192px.

Comprueba el tamaño mínimo automático y texto largo

El ancho mínimo automático de los elementos Flex puede evitar que las áreas que contienen direcciones largas o identificadores se reduzcan. min-width: 0 permite que el elemento reduzca su anchura por debajo de ese mínimo automático, y overflow-wrap: anywhere permite que la cadena en sí se ajuste. Reducir un cuadro no trunca automáticamente el texto dentro de él, por lo que conviene distinguir ambos problemas. Consulta también overflow, saltos de texto y puntos suspensivos con CSS.

Guarda el código siguiente como flex-long-text.html. El ejemplo contiene un identificador largo sin espacios, no una dirección real. Incluso si la pantalla se estrecha, el texto junto al área de guía se lee dividido en varias líneas. Puedes revisar las reglas de ajuste de línea en la descripción de overflow-wrap de MDN.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>flex-long-text.html</title>
  <style>
* { box-sizing: border-box; }
body { margin: 16px; font: 16px/1.6 sans-serif; color: #243447; }
h1 { font-size: 24px; } h2 { font-size: 20px; margin-top: 32px; }
a { color: #145f8f; } a:focus-visible { outline: 3px solid #b4470b; outline-offset: 3px; }
.notice { display: flex; gap: 12px; max-width: 600px; border: 2px solid #789; padding: 12px; }
 .icon { flex: 0 0 48px; background: #ffe4b5; }
 .text { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; background: #dceefa; }
 .text p { margin: 0; }
  </style>
</head>
<body>
<h1>Long strings and minimum sizes</h1><div class="notice"><div class="icon">Notice</div><div class="text"><p>ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</p></div></div>
</body>
</html>
  1. En .text, solo cambia overflow-wrap a normal. Incluso si se reduce el ancho del ítem, la cadena puede desbordarse fuera de los límites. Restaura el valor anywhere.
  2. Para ver el impacto de min-width por separado, elimina min-width: 0 manteniendo overflow-wrap: normal. Después de determinar cómo afecta el tamaño mínimo de cadenas largas a la colocación de los ítems, restaura ambas declaraciones a sus valores originales.

Si la alineación no es posible, primero comprueba el eje del padre y el espacio restante. Si el tamaño no disminuye, comprueba el tamaño mínimo del elemento y la cadena interna. Si aplicas overflow: hidden en todo el padre para ocultar el problema, puedes perder contenido o la indicación de foco. Es más fácil juzgar los resultados si el tamaño del diseño y la visualización del contenido se resuelven por separado.