flex
? Se le permite configurar los valores de propiedad flex-grow
, flex-shrink
y flex-basis
. Noté que esta propiedad se usa con mayor frecuencia en una vista flex: 1
, lo que permite que un elemento flexible se estire para ocupar el espacio disponible.
En este artículo, quiero hablar sobre una propiedad abreviada y las propiedades que se establecen al usarla. Voy a hablar sobre cuándo y por qué se pueden utilizar estas propiedades, daré ejemplos prácticos.
flex
Propiedad de crecimiento flexible
La propiedad CSS se
flex-grow
usa para ajustar lo que se llama factor de crecimiento flexible, que permite que esos elementos se estiren para llenar el espacio disponible. Solo se pueden usar números enteros como valores para esta propiedad. Veamos un ejemplo.
Aquí está el marcado HTML:
<div class="wrapper">
<div class="item item-1"></div>
<div class="item item-2"></div>
<div class="item item-3"></div>
</div>
Estos son los estilos:
.wrapper {
display: flex;
flex-wrap: wrap;
}
.item {
flex-grow: 1;
}
Una propiedad
flex-grow
puede afectar el ancho o alto de un elemento, dependiendo del valor de la propiedad flex-direction
. Al considerar los siguientes ejemplos, tenga en cuenta que la propiedad que utilizan se flex-direction
establece en el valor predeterminado ( row
). Si este no es el caso, te lo contaré.
Tenga en cuenta que sin ser utilizados
flex-grow
, los elementos flexibles se establecerán en su ancho predeterminado, que es igual a su ancho original. Y si se usa flex-grow: 1
, el espacio libre disponible se distribuye entre los elementos.
Arriba, la propiedad de crecimiento flexible no se aplica. A continuación se muestra flex-grow: 1 Es
posible que se pregunte cómo se asigna exactamente el espacio libre entre elementos flexibles. Esta es una buena pregunta. La responderé pronto.
La siguiente ilustración muestra cómo se ven los elementos sin usar la propiedad
flex-grow
. En otras palabras, los artículos se muestran aquí en su tamaño normal.
La propiedad flex-grow no se usa
Para comprender cómo se calcula el ancho de los elementos flexibles, eche un vistazo a las fórmulas a continuación. Encontré estas fórmulas en el material de Samantha Ming (¡por lo que le agradezco!).
Calculemos el ancho del primer elemento, el que contiene el texto
CSS
.
Encontrar el ancho de un elemento
Entonces, aquí se usa la siguiente fórmula:
= ((flex-grow / flex-grow) * ) +
Analicemos esta fórmula:
flex-grow
Es el factor de crecimiento especificado para el artículo.flex-grow
Es la suma de los valores de los factores de crecimiento de todos los elementos.flex-grow
.flex-grow
.
La sustitución de valores reales en esta fórmula da como resultado lo siguiente:
= ( (1 / 3) * 498) + 77 = 241
Diferentes valores de crecimiento flexible para diferentes artículos
En el ejemplo anterior, se utilizó el mismo valor para todos los elementos flexibles
flex-grow
. Ahora intentemos asignar una propiedad al primer elemento flex-grow: 2
. ¿Cómo se calculará ahora el ancho de los elementos? Al considerar la siguiente fórmula, tenga en cuenta que el ancho del espacio libre en nuestro ejemplo es 498px
.
Encontrar el ancho de un elemento en una situación en la que diferentes elementos tienen diferentes crecimientos flexibles
Como puede ver, esto utiliza el mismo mecanismo para calcular el ancho de los elementos que se discutió anteriormente. La principal diferencia es que el valor
flex-grow
del primer elemento se establece como2
, lo que se refleja en la fórmula para calcular el ancho de los elementos.
¿Se puede usar 0 como valor de crecimiento flexible?
¡Por supuesto que puede! Dado que la propiedad
flex-grow
acepta valores enteros y se puede escribir en ella 0
. Esto significa que no queremos que el elemento flexible cambie de tamaño para ocupar parte del espacio libre del contenedor.
Consecuencias de establecer la propiedad Flex-Grow en 0
Como puede ver, el elemento al que se asigna la propiedad
flex-grow: 0
no cambia de ancho. Esta técnica puede resultar útil cuando desee que un elemento flexible mantenga su ancho original.
Flex-grow no hace que los artículos sean iguales
Existe la idea errónea de que el uso
flex-grow
permite que los elementos coincidentes tengan el mismo ancho. Esto es un error. El punto de uso flex-grow
es distribuir el espacio disponible entre elementos. Como puede ver al analizar las fórmulas anteriores, el ancho final de los elementos flexibles se calcula en función de su ancho original (es decir, lo que tenían antes de que se aplicaran flex-grow
).
Si necesita hacer que todos los elementos de un conjunto tengan el mismo ancho, sepa que puede hacerlo usando la propiedad
flex-basis
. Hablaremos de esto a continuación.
Propiedad de contracción flexible
La propiedad le
flex-shrink
permite establecer el llamado factor de contracción flexible. Si todos los elementos flexibles son más grandes que el tamaño de su contenedor, los elementos se reducirán según sus valores de propiedad asignados flex-shrink
.
La propiedad flex-shrink se asigna al elemento central: 1
Estos son los estilos para este ejemplo:
.item-2 {
width: 300px;
flex-shrink: 1;
}
El navegador
item-2
igualará el ancho del elemento 300px
cuando se cumplan las siguientes condiciones:
- El ancho total de todos los elementos es menor que el ancho del contenedor.
- El ancho de la ventana gráfica de la página es igual o mayor que el ancho del elemento.
Así es como se comportan los elementos del ejemplo anterior cuando se muestran en ventanas gráficas de diferentes anchos.
El ancho del elemento con el texto Is no
se encoge mientras haya suficiente espacio en la pantalla para mostrarlo. Como puede ver, el elemento no encoge, manteniendo su ancho
300px
mientras haya suficiente espacio para él.
Propiedad de base flexible
La propiedad
flex-basis
establece el tamaño base del elemento flexible antes de que se asigne el espacio libre de acuerdo con los factores de flexibilidad establecidos por las propiedades flex-grow
y flex-shrink
. De forma predeterminada, para todos los valores excepto auto
y content
, el valor flex-basis
es igual al ancho del elemento y, cuando se usa la propiedad flex-direction: column
, su alto.
La propiedad
flex-basis
toma los mismos valores que pueden tomar las propiedades width
y height
. El valor predeterminado es auto
uno que se establece en función del valor content
. El valor content
se establece automáticamente en función del tamaño del contenido del elemento flexible.
Apliquemos los
item-1
siguientes estilos al elemento de nuestro ejemplo:
.item-1 {
flex-grow: 0;
flex-shrink: 0;
flex-basis: 50%;
}
Uso de la propiedad de base flexible: 50%
Aquí se asigna una propiedad al primer elemento
flex-basis: 50%
. En este caso, es importante restablecerlo a una0
propiedadflex-grow
, lo que le permitirá asegurarse de que el tamaño del elemento no exceda50%
.
¿Qué sucede si escribe un
flex-basis
valoren la propiedad en su lugar100%
? Esto hará que el elemento ocupe el 100% del ancho del elemento principal y que otros elementos se ajusten a una nueva línea.
Estos son los estilos relevantes:
.item-1 {
flex-grow: 0;
flex-shrink: 0;
flex-basis: 100%;
}
El resultado de usar la propiedad de base flexible es 100%;
La propiedad flex de taquigrafía
La propiedad
flex
permite, en formato de taquigrafía, a los valores de conjuntos de propiedades flex-grow
, flex-shrink
y flex-basis
. El valor predeterminado que toma esta propiedad es auto
. Coincide flex: 0 1 auto
. Esto significa que permite que los elementos flexibles aumenten de tamaño en función del tamaño de su contenido.
En este contexto, me gustaría llamar su atención sobre un detalle importante. Estamos hablando de artículos flexibles con tamaños absolutos y relativos. Y, por cierto, esto no tiene nada que ver con el posicionamiento CSS . Esto se aplica al modelo flexbox.
Artículos flexibles con tamaños relativos
Aquí está el CSS:
.item {
/* , , flex: 1 1 auto */
flex: auto;
}
Aquí, el tamaño de los elementos flexibles se basa en su contenido. Como resultado, los elementos con más contenido aparecerán más grandes.
Un elemento con más contenido tendrá más
Artículos flexibles con dimensiones absolutas
Si, a diferencia del ejemplo anterior, la propiedad
flex-basis
se establece en un valor 0
, esto hará que todos los elementos flexibles crezcan al mismo tamaño.
Este es el estilo:
.item {
/* flex: 1 1 0% */
flex: 1;
}
Los artículos son del mismo tamaño
Funciones de propiedad flexible que me encantan
El mismo nombre de la propiedad
flex
sugiere que puede funcionar de manera flexible con los valores que se le pasan. Esto le da algunas características que encuentro atractivas. Veamos algunos ejemplos.
▍Un valor sin unidades
Aquí está el CSS:
.item {
flex: 1;
}
Aquí,
flex
se escribe un valor único sin unidades en la propiedad . Este valor será interpretado por el sistema como el valor de la propiedad flex-grow
. Su equivalente se verá así flex: 1 1 0
.
▍Dos valores sin unidades
Echemos un vistazo al siguiente estilo:
.item {
flex: 1 1;
}
Aquí establecemos explícitamente los valores
flex-grow
y respectivamente flex-shrink
. Esto flex-basis
se restablecerá a los valores predeterminados.
▍ Valor único que representa un cierto tamaño
Hablemos de cómo se "decodificará" el siguiente estilo:
.item {
flex: 100px;
/* flex: 1 1 100px */
}
El valor
100px
será tratado por el sistema como un valor flex-basis
. Y en flex-grow
y flex-shrink
, por defecto, se escribirá 1
.
▍Usando 0 sin especificar unidades
Suponga que desea establecer
flex-basis
un valor 0
mediante la propiedad flex
. Para solucionar este problema, decidiremos hacer esto:
.item {
flex: 0;
}
No se recomienda hacerlo, ya que puede confundir tanto a quienes leerán dicho código como al navegador. Cómo entender, ¿a qué se refiere exactamente este
0
? A la propiedad flex-grow
, flex-shrink
o flex-basis
? En general, resulta la confusión. Esto es lo que dice la especificación CSS al respecto : un
cero sin una unidad de medida, sin dos valores de esbeltez antes, debe interpretarse como un valor de esbeltez. Para evitar interpretaciones erróneas o declaraciones de propiedad engañosas, los autores deben usar unidades al especificar la base flexible en cero, o preceder este valor con dos valores de base flexible.
Es decir, para evitar ambigüedades, el código anterior debe reescribirse de la siguiente manera:
.item {
flex: 0%;
/* flex: 1 1 0% */
}
Aquí se usa una construcción
0%
, pero puede, por ejemplo, usar una construcción 0px
.
Usa la propiedad flex abreviada
Cuando tenga que establecer las propiedades
flex-grow
, flex-shrink
y flex-basis
, lo mejor es utilizar una propiedad abreviada para eso flex
.
Echando un vistazo a la especificación de CSS :
se recomienda a los autores que administren elementos flexibles utilizando la propiedad de taquigrafía flex en lugar de usar nombres de propiedad totalmente calificados directamente, ya que la aplicación de la propiedad taquigráfica restablecerá correctamente los valores no especificados al estado correspondiente a los usos comunes.
Casos de uso y ejemplos prácticos
▍ Avatares de usuario
Un avatar configurado con la propiedad flex
El modelo flexbox se usa a menudo para diseñar componentes de página relevantes para el usuario. Por ejemplo, se trata del avatar del usuario y la firma correspondiente, que debe estar en la misma línea.
Aquí está el marcado:
<div class="user">
<img class="user__avatar" src="shadeed.jpg" alt="" />
<div>
<h3>Ahmad Shadeed</h3>
<p>Author of Debugging CSS</p>
</div>
</div>
Este es el estilo:
.user {
display: flex;
flex-wrap: wrap;
align-items: center;
}
.user__avatar {
flex: 0 0 70px;
width: 70px;
height: 70px;
}
Observe que cuando configuré el elemento
user__avatar
, apliqué la propiedad flex: 0 0 70px
. Esto es importante porque sin esta configuración, es posible que la imagen no se muestre correctamente en algunos navegadores obsoletos. Además, la prioridad de la propiedad es flex
mayor que la prioridad de la propiedad width
(cuando se trata de la situación en la que se aplica flex-direction: row
) y la propiedad height
(en la situación en la que se aplica flex-direction: column
).
Si cambia el tamaño del avatar, afectando solo la propiedad
flex
, el navegador ignorará lo que está configurado en la propiedad width
. Aquí está el estilo relevante:
.user__avatar {
/* 100px, 70px */
flex: 0 0 100px;
width: 70px;
height: 70px;
}
▍Título del elemento
Título del elemento
Supongamos que necesitamos diseñar el título de un elemento. Este encabezado debería ocupar todo el espacio disponible. Puede resolver este problema utilizando la propiedad
flex: 1
:
.page-header {
display: flex;
flex-wrap: wrap;
}
.page-header__title {
flex: 1;
}
▍Campo de entrada para preparar el mensaje
Cuadro de entrada Los campos como este se encuentran a menudo en aplicaciones de mensajería como las que se encuentran en Facebook y Twitter. Dicho campo debería ocupar todo el espacio disponible. En este caso, el botón para enviar un mensaje debe tener un ancho fijo. Así es como se ve en CSS:
form {
display: flex;
flex-wrap: wrap;
}
input {
flex: 1;
/* */
}
Este ejemplo es una buena demostración del uso de una propiedad
flex-grow
.
Cabe señalar que algunos métodos de uso de la propiedad
flex
no reciben suficiente atención en las publicaciones dedicadas a esta propiedad. Arreglemos esto.
▍Alinee los elementos inferiores que están en diferentes tarjetas
El objetivo es alinear ambas fechas con la línea roja.
Digamos que tenemos un diseño CSS Grid con dos columnas. El problema aquí es que las fechas que se muestran al final del contenido de texto de las tarjetas no están alineadas. Y necesitamos que estén en la misma línea que se muestra en la figura anterior.
El modelo flexbox se puede utilizar para resolver este problema.
Aquí está el marcado:
<div class="card">
<img src="thumb.jpg" alt="">
<h3 class="card__title">Title short</h3>
<time class="card__date"></time>
</div>
Puede lograr nuestro objetivo utilizando la propiedad
flex-direction: column
. Se puede diseñar un elemento card__title
, un encabezado, aplicando una propiedad flex-grow
y haciendo que ocupe todo el espacio disponible. Como resultado, resulta que la línea de fecha aparecerá en la parte inferior de la tarjeta. Esto sucederá incluso si el título en sí es lo suficientemente corto.
Estos son los estilos:
.card {
display: flex;
flex-direction: column;
}
/* */
.card__title {
flex-grow: 1;
}
Este problema se puede solucionar sin recurrir a la propiedad
flex-grow
. Es decir, estamos hablando de usar un modelo flexbox y un mecanismo para establecer márgenes automáticamente usando una palabra clave auto
. Por cierto, escribí un artículo detallado sobre esto .
/* */
.card__date {
margin-top: auto;
}
Usando diferentes valores para factores de esbeltez
En esta sección, quiero hablar sobre el uso de propiedades
flex-grow
y a las flex-shrink
que se les asignan valores distintos de 1
. Ahora daré algunos ejemplos prácticos del uso de un esquema similar para establecer estas propiedades.
▍Paneles de control
Un conjunto de controles
Para este ejemplo, me inspiré en el diseño de Facebook (también tomé íconos de allí). El panel de control (elemento
actions
del siguiente código) tiene cuatro elementos. El último (elementoactions__item.user
) tiene un ancho que es menor que el ancho de los otros elementos. Puede crear un panel de control como este:
.actions {
display: flex;
flex-wrap: wrap;
}
.actions__item {
flex: 2;
}
.actions__item.user {
flex: 1;
}
▍Animación en la que se estira el elemento
El elemento se estira cuando se desplaza sobre él.
Los elementos flexibles pueden animarse cuando se desplaza sobre ellos. Esta técnica puede resultar de gran utilidad. Aquí está el CSS relevante:
.palette {
display: flex;
flex-wrap: wrap;
}
.palette__item {
flex: 1;
transition: flex 0.3s ease-out;
}
.palette__item:hover {
flex: 4;
}
Aquí puede encontrar un video que lo demuestra todo en acción.
▍Aumentar el tamaño de la tarjeta activa
Me gusta mucho este proyecto en CodePen, que implementa un mecanismo para aumentar el tamaño de la tarjeta con una descripción del plan de tarifas, en el que el usuario hizo clic. Se cambia el tamaño de la tarjeta estableciendo su propiedad
flex-grow
en un valor 4
.
Aumentar el tamaño de la tarjeta activa
▍ ¿Qué pasa si el contenido del contenedor es más grande que el contenedor mismo?
Los artículos no caben en el contenedor
Hace algún tiempo recibí un correo electrónico de uno de mis lectores que me informó sobre un problema que tenía y me pidió ayuda para resolverlo. La esencia de este problema se presenta en la figura anterior. Aquí hay un par de imágenes que deberían estar dentro del elemento contenedor, pero estas imágenes son más grandes que el contenedor.
Probemos este estilo:
.wrapper {
display: flex;
}
.wrapper img {
flex: 1;
}
Pero incluso cuando se utilizan las propiedades, las
flex: 1
imágenes no se colocan en el contenedor. En referencia a la especificación CSS : los
elementos flexibles, de forma predeterminada, no se reducen a menos del tamaño de su contenido (la longitud de la palabra más larga o el elemento de tamaño fijo). Para cambiar esto, debe usar las propiedades min-width o min-height.
En nuestro caso, el problema es que las imágenes son demasiado grandes para que el modelo flexbox cambie de tamaño para que quepan en el contenedor. Puedes arreglarlo así:
.wrapper img {
flex: 1;
min-width: 0;
}
Vea este artículo mío para más detalles.
Salir
Aquí les hablé de la propiedad
flex
y cómo usarla. Espero que hayas aprendido algo nuevo y útil de este material.
¿Está utilizando la propiedad Flex CSS en sus proyectos?