Flexbox: ¿Qué tan grande es esa caja flexible?

Publicado: 2022-03-10
Resumen rápido ↬ En los últimos dos artículos, hemos visto lo que sucede cuando creamos un contenedor flexible y también la alineación. Esta vez exploramos el tema, a menudo confuso, del tamaño en Flexbox. ¿Cómo decide Flexbox qué tan grandes deben ser las cosas?

Esta es la tercera parte de mi serie sobre Flexbox. En los últimos dos artículos, analizamos lo que sucede cuando crea un contenedor flexible y exploramos la alineación como funciona en Flexbox. En esta ocasión vamos a echar un vistazo a las tallas. ¿Cómo controlamos el tamaño de nuestros elementos flexibles y qué opciones toma el navegador cuando controla el tamaño?

Visualización inicial de elementos flexibles

Si tengo un conjunto de elementos, que tienen longitudes variables de contenido en su interior, y configuro su principal para display: flex , los elementos se mostrarán como una fila y se alinearán al comienzo de ese eje. En el siguiente ejemplo, mis tres elementos tienen una pequeña cantidad de contenido y pueden mostrar el contenido de cada elemento como una línea continua. Hay espacio al final del contenedor flexible en el que los elementos no crecen porque el valor inicial de flex-grow es 0 , no crece .

Tres artículos con espacio al final
Los elementos flexibles tienen espacio para que cada uno se muestre en una línea (vista previa grande)

Si agrego más texto a estos elementos, eventualmente llenan el contenedor y el texto comienza a ajustarse. A los cuadros se les asigna una parte del espacio en el contenedor que corresponde a la cantidad de texto que hay en cada cuadro; a un elemento con una cadena de texto más larga se le asigna más espacio. Esto significa que no terminamos con una columna alta y delgada con mucho texto cuando el elemento de al lado solo contiene una sola palabra.

Tres elementos, el elemento final tiene un texto más largo y el texto se ajusta
El espacio se distribuye para dar más espacio a un elemento más largo (Vista previa grande)

Es probable que este comportamiento le resulte familiar si alguna vez ha usado Flexbox, pero tal vez se haya preguntado cómo funciona el navegador en ese tamaño, ya que si observa varios navegadores modernos, verá que todos hacen lo mismo. Esto se debe al hecho de que detalles como este se resuelven en la especificación, asegurándose de que cualquier persona que implemente Flexbox en un nuevo navegador u otro agente de usuario sepa cómo se supone que funciona este cálculo. Podemos usar la especificación para encontrar esta información por nosotros mismos.

¡Más después del salto! Continúe leyendo a continuación ↓

La especificación de tamaño intrínseco y extrínseco de CSS

Con bastante rapidez, al mirar algo sobre el tamaño en la especificación Flexbox, descubre que gran parte de la información que necesita está en otra especificación: CSS Intrisnic and Extrinsic Sizing. Esto se debe a que los conceptos de tamaño que usamos no son exclusivos de Flexbox, de la misma manera que las propiedades de alineación no son exclusivas de Flexbox. Sin embargo, para saber cómo se utilizan estas construcciones de tamaño en Flexbox, debe consultar las especificaciones de Flexbox. Puede sentirse un poco como si estuviera saltando de un lado a otro, así que redondearé algunas definiciones clave aquí, que usaré en el resto del artículo.

Tamaño preferido

El tamaño preferido de un cuadro es el tamaño definido por un width o un height , o los alias lógicos para estas propiedades de inline-size block-size . Mediante el uso:

 .box { width: 500px; }

O el alias lógico inline-size :

 .box { inline-size: 500px; }

Está indicando que desea que su cuadro tenga 500 píxeles de ancho o 500 píxeles en la dirección en línea.

tamaño de contenido mínimo

El tamaño mínimo de contenido es el tamaño más pequeño que puede tener una caja sin causar un desbordamiento. Si su cuadro contiene texto, se aprovecharán todas las oportunidades posibles de envoltorio suave.

tamaño máximo de contenido

El tamaño máximo de contenido es el tamaño más grande que puede tener la caja para contener el contenido. Si el cuadro contiene texto sin formato para dividirlo, se mostrará como una cadena larga e ininterrumpida.

Tamaño principal del artículo flexible

El tamaño principal de un artículo flexible es el tamaño que tiene en la dimensión principal. Si está trabajando en una fila, en inglés, entonces el tamaño principal es el ancho. En una columna en inglés, el tamaño principal es la altura.

Los elementos también tienen un tamaño principal mínimo y máximo según lo definido por su min-width min-height en la dimensión principal.

Calcular el tamaño de un artículo flexible

Ahora que tenemos algunos términos definidos, podemos ver cómo se dimensionan nuestros elementos flexibles. El valor inicial de las propiedades de flex es el siguiente:

  • flex-grow: 0
  • flex-shrink: 1
  • flex-basis: auto

La flex-basis la cual se calcula el tamaño. Si establecemos flex-basis en 0 y flex-grow en 1, todas nuestras cajas no tienen un ancho inicial, por lo que el espacio en el contenedor flexible se reparte de manera uniforme, asignando la misma cantidad de espacio a cada elemento.

Ver Pen Smashing Flexbox Series 3: flex: 1 1 0; por Rachel Andrew (@rachelandrew) en CodePen.

Ver Pen Smashing Flexbox Series 3: flex: 1 1 0; por Rachel Andrew (@rachelandrew) en CodePen.

Mientras que si flex-basis es auto y flex-grow: 1 , solo se distribuye el espacio libre, teniendo en cuenta el tamaño del contenido.

Vea Pen Smashing Flexbox Series 3: flex: 1 1 texto breve automático de Rachel Andrew (@rachelandrew) en CodePen.

Vea Pen Smashing Flexbox Series 3: flex: 1 1 texto breve automático de Rachel Andrew (@rachelandrew) en CodePen.

En situaciones en las que no hay espacio libre, por ejemplo, cuando tenemos más contenido del que cabe en una sola línea, entonces no hay espacio para distribuir.

Vea Pen Smashing Flexbox Series 3: flex: 1 1 texto largo automático de Rachel Andrew (@rachelandrew) en CodePen.

Vea Pen Smashing Flexbox Series 3: flex: 1 1 texto largo automático de Rachel Andrew (@rachelandrew) en CodePen.

Esto nos muestra que averiguar qué significa auto es bastante importante si queremos saber cómo Flexbox calcula el tamaño de nuestras cajas. El valor del auto será nuestro punto de partida.

Definición automática

Cuando auto se define como un valor para algo en CSS, tendrá un significado muy específico en ese contexto, uno que vale la pena echarle un vistazo. El grupo de trabajo de CSS dedica mucho tiempo a averiguar qué significa automático en cualquier contexto, como explica esta charla para el editor de especificaciones Fantasai.

Podemos encontrar la información sobre lo que significa auto cuando se usa como flex-basis en la especificación. Los términos definidos anteriormente deberían ayudarnos a diseccionar esta afirmación.

“Cuando se especifica en un elemento flexible, la palabra clave auto recupera el valor de la propiedad de tamaño principal como la `base flexible` utilizada. Si ese valor es en sí mismo automático, entonces el valor usado es `contenido`”.

Entonces, si nuestra flex-basis es auto , Flexbox echa un vistazo a la propiedad de tamaño principal definida. Tendríamos un tamaño principal si le hubiéramos dado un width a cualquiera de nuestros elementos flexibles. En el siguiente ejemplo, todos los elementos tienen un ancho de 110 px, por lo que se utiliza como el tamaño principal, ya que el valor inicial de la base flexible es automático.

Vea Pen Smashing Flexbox Series 3: elementos flexibles con un ancho de Rachel Andrew (@rachelandrew) en CodePen.

Vea Pen Smashing Flexbox Series 3: elementos flexibles con un ancho de Rachel Andrew (@rachelandrew) en CodePen.

Sin embargo, nuestro ejemplo inicial tiene elementos que no tienen ancho, lo que significa que su tamaño principal es auto , por lo que debemos pasar a la siguiente oración: "Si ese valor es automático, entonces el valor usado es content ".

Ahora debemos ver lo que dice la especificación sobre la palabra clave de content . Este es otro valor que puede usar (en navegadores compatibles) para su flex-basis , por ejemplo:

 .item { flex: 1 1 content; }

La especificación define el content de la siguiente manera:

“Indica un tamaño automático basado en el contenido del artículo flexible. (Por lo general, es equivalente al tamaño máximo de contenido, pero con ajustes para manejar las relaciones de aspecto, las restricciones de tamaño intrínsecas y los flujos ortogonales)

En nuestro ejemplo, con elementos flexibles que contienen texto, podemos ignorar algunos de los ajustes más complicados y tratar el content como si tuviera el tamaño máximo de contenido.

Esto explica por qué, cuando tenemos una pequeña cantidad de texto en cada elemento, el texto no se ajusta. Los elementos flexibles tienen un tamaño automático, por lo que Flexbox está analizando su tamaño de contenido máximo, los elementos caben en su contenedor con ese tamaño, ¡y el trabajo está hecho!

La historia no termina aquí, ya que cuando agregamos más contenido, las cajas no se quedan en el tamaño de contenido máximo. Si lo hicieran, se saldrían del contenedor flexible y causarían un desbordamiento. Una vez que llenan el contenedor, el contenido comienza a envolverse y los artículos se vuelven de diferentes tamaños según el contenido que contienen.

Resolución de longitudes flexibles

Es en este punto donde la especificación se vuelve razonablemente compleja, sin embargo, los pasos que deben seguirse son los siguientes:

Primero, sume el tamaño principal de todos los artículos y vea si es más grande o más pequeño que el espacio disponible en el contenedor.

Si el tamaño del contenedor es más grande que el total, nos preocuparemos por el factor flex-grow , ya que tenemos espacio para crecer.

elementos flexibles con espacio libre al final
En el primer caso, nuestros artículos tienen espacio disponible para crecer. (Vista previa grande)

Si el tamaño del contenedor es más pequeño que el total, entonces nos preocuparemos por el factor flex-shrink ya que necesitamos encoger.

elementos flexibles que desbordan el contenedor
En el segundo caso, nuestros artículos son demasiado grandes y deben encogerse para caber en el contenedor. (Vista previa grande)

Congele cualquier artículo inflexible, lo que significa que ya podemos decidir el tamaño de ciertos artículos. Si usamos flex-grow , esto incluiría cualquier elemento que tenga flex-grow: 0 . Este es el escenario que tenemos cuando a nuestros artículos flexibles les queda espacio en el contenedor. El valor inicial de flex-grow es 0, por lo que se vuelven tan grandes como su ancho máximo y luego no crecen más desde su tamaño principal.

Si usamos flex-shrink , esto incluiría cualquier elemento con flex-shrink: 0 . Podemos ver lo que sucede en este paso si le damos a nuestro conjunto de elementos flex-shrink de 0. Los elementos se congelan en su estado max-content y, por lo tanto, no se flexionan y se acomodan para caber en el contenedor.

Vea Pen Smashing Flexbox Series 3: flex: 0 0 auto de Rachel Andrew (@rachelandrew) en CodePen.

Vea Pen Smashing Flexbox Series 3: flex: 0 0 auto de Rachel Andrew (@rachelandrew) en CodePen.

En nuestro caso, con los valores iniciales de los artículos flexibles, nuestros artículos pueden encogerse. Entonces, los pasos continúan y el algoritmo entra en un ciclo en el que calcula cuánto espacio asignar o quitar. En nuestro caso, usamos flex-shrink ya que el tamaño total de nuestros artículos es más grande que el contenedor, por lo que necesitamos quitar espacio.

El factor flex-shrink se multiplica por el tamaño base interno de los elementos, en nuestro caso, ese es el tamaño max-content . Esto da un valor con el que reducir el espacio. Si los elementos eliminaran el espacio solo de acuerdo con el factor flex-shrink los elementos pequeños podrían desaparecer esencialmente, habiendo eliminado todo su espacio, mientras que el elemento más grande todavía tiene espacio para reducir.

Hay un paso adicional en este ciclo para verificar elementos que se volverían más pequeños o más grandes que su tamaño principal de destino, en cuyo caso el elemento deja de crecer o reducirse. Nuevamente, esto es para evitar que ciertos elementos se vuelvan pequeños o masivos en comparación con el resto de los elementos.

Todo eso se simplificó en términos de las especificaciones, ya que no he mirado algunos de los escenarios más extremos y, en general, puede simplemente pensar más en su mente, asumiendo que está feliz de dejar que Flexbox haga lo suyo y no busca píxeles. perfección. Recordar los siguientes dos hechos funcionará en la mayoría de los casos.

Si está creciendo desde auto , la flex-basis se tratará como cualquier ancho o alto en el elemento o el tamaño max-content . A continuación, se asignará el espacio de acuerdo con el factor flex-grow utilizando ese tamaño como punto de partida.

Si está reduciendo desde auto , la flex-basis se tratará como cualquier ancho o alto en el elemento o el tamaño max-content . Luego, el espacio se eliminará de acuerdo con el tamaño flex-basis multiplicado por el factor flex-shrink , por lo tanto, se eliminará en proporción al tamaño de contenido máximo de los elementos.

Controlando el crecimiento y la reducción

He pasado la mayor parte de este artículo describiendo lo que hace Flexbox cuando se deja en sus propios dispositivos. Por supuesto, puede ejercer un mayor control sobre sus elementos flexibles utilizando las propiedades flex . Es de esperar que parezcan más predecibles con una comprensión de lo que sucede detrás de escena.

Al establecer su propia flex-basis , o al darle al elemento en sí un tamaño que luego se usa como flex-basis recupera el control del algoritmo y le dice a Flexbox que desea crecer o reducirse a partir de este tamaño en particular. Puede desactivar el crecimiento o la reducción por completo configurando flex-grow o flex-shrink en 0. Sin embargo, en este punto, vale la pena usar el deseo de controlar los elementos flexibles como un momento para verificar si está utilizando el método de diseño correcto. Si se encuentra tratando de alinear elementos flexibles en dos dimensiones, entonces podría ser mejor que elija Diseño de cuadrícula.

Problemas relacionados con el tamaño de depuración

Si sus elementos flexibles terminan con un tamaño inesperado, esto generalmente se debe a que su base flexible es automática y hay algo que le da un ancho a ese elemento, que luego se usa como base flexible. Inspeccionar el elemento en DevTools puede ayudar a identificar de dónde proviene el tamaño. También puede intentar establecer una flex-basis de 0 , lo que obligará a Flexbox a tratar el elemento como si tuviera un ancho cero. Incluso si este no es el resultado que desea, ayudará a identificar el valor flex-basis en uso como el culpable de sus problemas de tamaño.

Espacios flexibles

Una característica muy solicitada de Flexbox es la capacidad de especificar espacios o medianeras entre elementos flexibles de la misma manera que podemos especificar espacios en el diseño de cuadrícula y el diseño de varias columnas. Esta función se especifica para Flexbox como parte de Box Alignment, y la primera implementación del navegador está en camino. Firefox espera enviar las propiedades de brecha para Flexbox en Firefox 63. El siguiente ejemplo se puede ver en Firefox Nightly.

Vea Pen Smashing Flexbox Series 3: flex-gaps de Rachel Andrew (@rachelandrew) en CodePen.

Vea Pen Smashing Flexbox Series 3: flex-gaps de Rachel Andrew (@rachelandrew) en CodePen.
Tres filas de elementos con espacio de medianil entre ellos
La imagen como se ve en Firefox 63 (vista previa grande)

Al igual que con el diseño de cuadrícula, la longitud del espacio se tiene en cuenta antes de distribuir el espacio a los elementos flexibles.

Terminando

En este artículo, he tratado de explicar algunos de los puntos más finos de cómo Flexbox calcula el tamaño de los elementos flexibles. Puede parecer un poco académico, sin embargo, tomarse un tiempo para comprender cómo funciona esto puede ahorrarle una gran cantidad de tiempo al usar Flexbox en sus diseños. Me resulta muy útil volver al hecho de que, de forma predeterminada, Flexbox está tratando de brindarle el diseño más sensato de un montón de elementos con diferentes tamaños. Si un elemento tiene más contenido, se le da más espacio. Si usted y su diseño no están de acuerdo con lo que Flexbox cree que es mejor, puede recuperar el control configurando su propia flex-basis .