¿Cuáles son las diferencias entre base flexible y ancho?

224

Ha habido preguntas y artículos sobre esto, pero nada concluyente por lo que puedo decir. El mejor resumen que pude encontrar es

flex-base le permite especificar el tamaño inicial / inicial del elemento, antes de calcular cualquier otra cosa. Puede ser un porcentaje o un valor absoluto.

... que en sí mismo no dice mucho sobre el comportamiento de los elementos con un conjunto de bases flexibles . Con mi conocimiento actual de flexbox, no veo por qué eso no podría describir el ancho también.

Me gustaría saber cómo exactamente la base flexible es diferente del ancho en la práctica:

  • Si reemplazo el ancho con base flexible (y viceversa), ¿qué cambiará visualmente?
  • ¿Qué sucede si configuro ambos a un valor diferente? ¿Qué pasa si tienen el mismo valor?
  • ¿Hay algunos casos especiales en los que el uso de ancho o flex-base tendría una diferencia significativa con el uso del otro?
  • ¿Cómo difieren el ancho y la base flexible cuando se usan junto con otros estilos de flexbox, como flex-wrap , flex-grow y flex-shrink ?
  • ¿Alguna otra diferencia significativa?

Edición / aclaración : esta pregunta se ha formulado en un formato diferente en ¿Qué conjuntos de propiedades de base flexible son exactamente? pero sentí que sería agradable una comparación o resumen más directo de las diferencias de base flexible y ancho (o altura ).

jpeltoniemi
fuente
El mejor artículo que explica la base de la flexión, el crecimiento y la
reducción de la

Respuestas:

339

Considerar flex-direction

Lo primero que viene a la mente al leer su pregunta es que flex-basisno siempre se aplica width.

Cuando flex-directiones row, flex-basiscontrola el ancho.

Pero cuando flex-directiones column, flex-basiscontrola la altura.


Diferencias clave

Aquí hay algunas diferencias importantes entre flex-basisy width/ height:

  • flex-basisse aplica solo a artículos flexibles. Los contenedores flexibles (que no son también artículos flexibles) se ignorarán flex-basispero pueden usar widthy height.

  • flex-basisfunciona solo en el eje principal. Por ejemplo, si está dentro flex-direction: column, la widthpropiedad sería necesaria para dimensionar elementos flexibles horizontalmente.

  • flex-basisno tiene ningún efecto en artículos flexibles posicionados absolutamente. widthy las heightpropiedades serían necesarias. Los elementos flexibles ubicados de manera absoluta no participan en el diseño flexible .

  • Mediante el uso de la flexpropiedad, tres propiedades - flex-grow, flex-shrinky flex-basis- puede ser perfectamente combinadas en una sola declaración. Usando width, la misma regla requeriría múltiples líneas de código.


Comportamiento del navegador

En términos de cómo se representan, no debería haber diferencia entre flex-basisy width, a menos que flex-basissea autoo content.

De la especificación:

7.2.3 La flex-basispropiedad

Para todos los valores que no sean autoy content, flex-basisse resuelve de la misma manera que widthen los modos de escritura horizontal.

Pero el impacto de autoo contentpuede ser mínimo o nada en absoluto. Más de la especificación:

auto

Cuando se especifica en un elemento flexible, la autopalabra clave recupera el valor de la propiedad de tamaño principal como se usa flex-basis. Si ese valor es él mismo auto, entonces el valor utilizado es content.

content

Indica el tamaño automático, en función del contenido del elemento flexible.

Nota: Este valor no estaba presente en la versión inicial de Diseño de caja flexible y, por lo tanto, algunas implementaciones anteriores no lo admitirán. El efecto equivalente se puede lograr mediante el uso autojunto con un tamaño principal ( widtho height) de auto.

Por lo tanto, de acuerdo con las especificaciones, flex-basisy widthresolver de forma idéntica, a menos que flex-basissea autoo content. En tales casos, flex-basispuede usar el ancho del contenido (que, presumiblemente, la widthpropiedad también usaría).


El flex-shrinkfactor

Es importante recordar la configuración inicial de un contenedor flexible. Algunas de estas configuraciones incluyen:

  • flex-direction: row - los elementos flexibles se alinearán horizontalmente
  • justify-content: flex-start - los elementos flexibles se apilarán al comienzo de la línea en el eje principal
  • align-items: stretch - los artículos flexibles se expandirán para cubrir el tamaño transversal del contenedor
  • flex-wrap: nowrap - los artículos flexibles se ven obligados a permanecer en una sola línea
  • flex-shrink: 1 - un elemento flexible puede encogerse

Tenga en cuenta la última configuración.

Debido a que los elementos flexibles pueden reducirse de forma predeterminada (lo que evita que desborden el contenedor), el flex-basis/ width/ especificado heightpuede anularse.

Por ejemplo, flex-basis: 100pxo width: 100px, junto con flex-shrink: 1, no necesariamente será de 100 px.

Para representar el ancho especificado, y mantenerlo fijo , deberá desactivar la reducción:

div {
   width: 100px;
   flex-shrink: 0;
}  

O

div {
  flex-basis: 100px;
  flex-shrink: 0;
}

O, según lo recomendado por la especificación:

flex: 0 0 100px;    /* don't grow, don't shrink, stay fixed at 100px */

7.2. Componentes de flexibilidad

Se alienta a los autores a controlar la flexibilidad utilizando la flextaquigrafía en lugar de sus propiedades de la mano directamente, ya que la taquigrafía restablece correctamente cualquier componente no especificado para acomodar usos comunes .


Errores del navegador

Algunos navegadores tienen problemas para dimensionar elementos flexibles en contenedores flexibles anidados.

flex-basisignorado en un contenedor flexible anidado. widthtrabajos.

Cuando se usa flex-basis, el contenedor ignora el tamaño de sus elementos secundarios, y los elementos secundarios desbordan el contenedor. Pero con la widthpropiedad, el contenedor respeta el tamaño de sus hijos y se expande en consecuencia.

Referencias

Ejemplos:


Uso de artículos flexibles flex-basisy contenedor de white-space: nowrapdesbordamiento inline-flex. widthtrabajos.

Parece que un contenedor flexible configurado para inline-flexno reconoce flex-basisa un niño cuando representa a un hermano white-space: nowrap(aunque podría ser un elemento con un ancho indefinido). El contenedor no se expande para acomodar los artículos.

Pero cuando widthse utiliza la propiedad en lugar de flex-basis, el contenedor respeta el tamaño de sus elementos secundarios y se expande en consecuencia. Esto no es un problema en IE11 y Edge.

Referencias

Ejemplo:


flex-basis(y flex-grow) no funciona en el elemento de tabla

Referencias


flex-basisfalla en Chrome y Firefox cuando el contenedor de los abuelos es un elemento que se contrae para adaptarse. La configuración funciona bien en Edge.

Al igual que en el ejemplo presentado en el enlace anterior, position: absoluteel uso de floaty inline-blocktambién generará la misma salida defectuosa ( demo jsfiddle ).


Errores que afectan a IE 10 y 11:

Michael Benjamin
fuente
2
¿Qué tal min-width:100px;? ¿Puede ser una opción para desactivar la reducción?
Mori
1
@Mori, sí, se flex-shrinkdetiene a las min-width. La regla flexible equivalente sería flex: 1 0 100px.
Michael Benjamin
flex: 1 0 100pxconduce al mismo resultado, pero no estoy seguro de lo que quiere decir con "equivalente".
Mori
Quiero decir, ¿por qué no deberíamos considerarlo igual a flex: 0 0 100px, por ejemplo?
Mori
2
@Mori, porque entonces es igual al ancho . Necesita el componente flex-grow: 1 para permitir que el elemento crezca desde el ancho mínimo, establecido por la base flex .
Michael Benjamin
33

Además del excelente resumen de Michael_B, vale la pena repetir esto:

flex-base le permite especificar el tamaño inicial / inicial del elemento, antes de calcular cualquier otra cosa. Puede ser un porcentaje o un valor absoluto.

La parte importante aquí es inicial .

Por sí solo, esto se resuelve en ancho / alto hasta que las otras propiedades de crecimiento / contracción de flexión entran en juego.

Entonces. un niño con

.child {
 flex-basis:25%;
 flex-grow:1;
}

inicialmente tendrá un ancho del 25%, pero luego se expandirá de inmediato lo más que pueda hasta que se tengan en cuenta los otros elementos. Si no hay ninguno ... será 100% ancho / alto.

Una demostración rápida:

Experimentar con flex-grow, flex-shrinky flex-basis (o la taquigrafía flex :fg fs fb) ... puede dar algunos resultados interesantes.

Paulie_D
fuente
He encontrado que, en general en el contexto de la flexión que ambos flex-basisy width / heightestablecer el tamaño inicial / partir de un elemento. Por ejemplo, flex-basis: 200pxbásicamente funciona igual que flex-basis: auto; width: 200px;. Parece que cuando flex-basisno está configurado en auto, simplemente anula el width / heightvalor. La única diferencia que veo es la forma en que se maneja el desbordamiento de contenido.
Karolis
5

Posiblemente el punto más importante para agregar:

¿Qué pasa si el navegador no es compatible flex? En tal caso, width/heighttome el control y se aplicarán sus valores.

Es una muy buena idea, casi esencial, definir width/heightelementos, incluso si tiene un valor completamente diferente flex-basis. Recuerde probar deshabilitando display:flexy viendo lo que obtiene.

Niet the Dark Absol
fuente
2
Entre los principales navegadores, los únicos que no admiten propiedades flexibles son IE <10. caniuse.com/#search=flex
Michael Benjamin
1
@Michael_B Claro, y tal vez solo soy yo, pero también tengo que admitir navegadores móviles, incluido el navegador Nintendo 3DS, que definitivamente no es compatible flex.
Niet the Dark Absol