Quais são as diferenças entre base flexível e largura?

224

Houve perguntas e artigos sobre isso, mas nada conclusivo, até onde posso dizer. O melhor resumo que pude encontrar é

O flex-base permite que você especifique o tamanho inicial / inicial do elemento, antes que qualquer outra coisa seja computada. Pode ser uma porcentagem ou um valor absoluto.

... o que por si só não diz muito sobre o comportamento de elementos com conjunto de bases flexíveis . Com meu conhecimento atual do flexbox, não vejo por que isso também não poderia descrever a largura .

Gostaria de saber como exatamente a base flexível é diferente da largura na prática:

  • Se eu substituir a largura pela base flexível (e vice-versa), o que mudará visualmente?
  • O que acontece se eu definir ambos para um valor diferente? O que acontece se eles tiverem o mesmo valor?
  • Existem alguns casos especiais em que o uso de largura ou base flexível teria uma diferença significativa em relação ao uso do outro?
  • Como a largura e a base flexível diferem quando usadas em conjunto com outros estilos de flexbox, como flex-wrap , flex-grow e flex-shrink ?
  • Alguma outra diferença significativa?

Edição / esclarecimento : Esta pergunta foi feita em um formato diferente em O que exatamente conjuntos de propriedades de base flexível? mas senti que seria agradável uma comparação ou resumo mais direto das diferenças de base flexível e largura (ou altura ).

jpeltoniemi
fonte
Melhor artigo explicando a base do flex, flex crescer e encolher por completo
ZenVentzi

Respostas:

339

Considerar flex-direction

A primeira coisa que vem à mente ao ler sua pergunta é que flex-basisnem sempre se aplica width.

Quando flex-directioné row, flex-basiscontrola a largura.

Mas quando flex-directioné column, flex-basiscontrola a altura.


Principais diferenças

Aqui estão algumas diferenças importantes entre flex-basise width/ height:

  • flex-basisaplica-se apenas a itens flexíveis. Os contêineres flexíveis (que também não são itens flexíveis) ignoram, flex-basismas podem usar widthe height.

  • flex-basisfunciona apenas no eixo principal. Por exemplo, se você estiver dentro flex-direction: column, a widthpropriedade seria necessária para dimensionar itens flexíveis horizontalmente.

  • flex-basisnão tem efeito em itens flexíveis absolutamente posicionados. widthe heightpropriedades seriam necessárias. Itens flexíveis absolutamente posicionados não participam do layout flexível .

  • Ao utilizar a flexpropriedade, três propriedades - flex-grow, flex-shrinke flex-basis- pode ser perfeitamente combinadas em uma declaração. Usando width, a mesma regra exigiria várias linhas de código.


Comportamento do navegador

Em termos de como eles são renderizados, não deve haver diferença entre flex-basise width, a menos que flex-basisseja autoou content.

Das especificações:

7.2.3 A flex-basispropriedade

Para todos os valores diferentes de autoe content, flex-basisé resolvido da mesma maneira que widthnos modos de gravação horizontal.

Mas o impacto autoou contentpode ser mínimo ou nada. Mais das especificações:

auto

Quando especificada em um item flexível, a autopalavra - chave recupera o valor da propriedade de tamanho principal como a usada flex-basis. Se esse valor for ele próprio auto, o valor usado será content.

content

Indica o dimensionamento automático, com base no conteúdo do item flexível.

Nota: Esse valor não estava presente na versão inicial do Layout de caixa flexível e, portanto, algumas implementações mais antigas não o suportam. O efeito equivalente pode ser alcançado usando-se autojunto com um tamanho principal ( widthou height) de auto.

Portanto, de acordo com as especificações, flex-basise widthresolva de forma idêntica, a menos que flex-basisseja autoou content. Nesses casos, flex-basispode usar a largura do conteúdo (que, presumivelmente, a widthpropriedade também usaria).


O flex-shrinkfator

É importante lembrar as configurações iniciais de um contêiner flexível. Algumas dessas configurações incluem:

  • flex-direction: row - os itens flexíveis se alinham horizontalmente
  • justify-content: flex-start - os itens flexíveis serão empilhados no início da linha no eixo principal
  • align-items: stretch - os itens flexíveis serão expandidos para cobrir o tamanho cruzado do contêiner
  • flex-wrap: nowrap - os itens flexíveis são forçados a permanecer em uma única linha
  • flex-shrink: 1 - um item flexível pode encolher

Observe a última configuração.

Como os itens flexíveis podem encolher por padrão (o que impede que eles excedam o contêiner), o flex-basis/ width/ especificado heightpode ser substituído.

Por exemplo, flex-basis: 100pxou width: 100px, juntamente com flex-shrink: 1, não será necessariamente 100px.

Para renderizar a largura especificada - e mantê-la fixa - você precisará desativar o encolhimento:

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

OU

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

OU, conforme recomendado pela especificação:

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

7.2 Componentes de flexibilidade

Os autores são incentivados a controlar a flexibilidade usando a flexabreviação, em vez de diretamente com suas propriedades, pois a redefinição redefine corretamente qualquer componente não especificado para acomodar usos comuns .


Erros do navegador

Alguns navegadores têm problemas para dimensionar itens flexíveis em contêineres flexíveis aninhados.

flex-basisignorado em um contêiner flex aninhado. widthtrabalho.

Ao usar flex-basis, o contêiner ignora o dimensionamento de seus filhos e os filhos transbordam. Mas com a widthpropriedade, o contêiner respeita o tamanho de seus filhos e se expande de acordo.

Referências:

Exemplos:


flex itens usando flex-basise white-space: nowraptransbordando inline-flexcontêiner. widthtrabalho.

Parece que um contêiner flexível definido como inline-flexnão é reconhecido flex-basisem uma criança ao renderizar um irmão white-space: nowrap(embora possa ser apenas um item com largura indefinida). O contêiner não se expande para acomodar os itens.

Mas quando a widthpropriedade é usada em vez de flex-basis, o contêiner respeita o tamanho de seus filhos e se expande de acordo. Isso não é um problema no IE11 e no Edge.

Referências:

Exemplo:


flex-basis(e flex-grow) não está funcionando no elemento da tabela

Referências:


flex-basisfalha no Chrome e no Firefox quando o contêiner dos avós é um elemento que se reduz ao tamanho adequado. A configuração funciona bem no Edge.

Como no exemplo apresentado no link acima, envolver position: absoluteo uso de floate inline-blocktambém renderizará a mesma saída defeituosa ( demonstração do jsfiddle ).


Erros que afetam o IE 10 e 11:

Michael Benjamin
fonte
2
Que tal min-width:100px;? Pode ser uma opção para desativar o encolhimento?
Mori
1
@Ori, sim, flex-shrinkpára em min-width. A regra flexível equivalente seria flex: 1 0 100px.
Michael Benjamin
flex: 1 0 100pxleva ao mesmo resultado, mas não sei ao certo o que você quer dizer com "equivalente".
Mori
Quero dizer, por que não devemos considerá-lo igual flex: 0 0 100px, por exemplo?
Mori
2
@Ori, porque então é apenas igual à largura . Ele precisa do componente flex-grow: 1 para permitir que o elemento cresça a partir da largura mínima, definida pela base flexível .
Michael Benjamin
33

Além do excelente resumo de Michael_B, vale a pena repetir isso:

O flex-base permite que você especifique o tamanho inicial / inicial do elemento, antes que qualquer outra coisa seja computada. Pode ser uma porcentagem ou um valor absoluto.

A parte importante aqui é inicial .

Por si só, isso resolve largura / altura até que outras propriedades flexíveis de crescimento / contração entrem em jogo.

Assim. uma criança com

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

terá 25% de largura inicialmente, mas depois expandirá imediatamente o máximo possível até que os outros elementos sejam levados em consideração. Se não houver nenhum ... será 100% de largura / altura.

Uma demonstração rápida:

Experimentar o flex-grow, flex-shrinke flex-basis (ou a taquigrafia flex :fg fs fb) ... pode levar a alguns resultados interessantes.

Paulie_D
fonte
Descobri que, geralmente, no contexto flexível, ambos flex-basise width / heightdefinem o tamanho inicial / inicial de um elemento. Por exemplo, flex-basis: 200pxbasicamente funciona da mesma forma que flex-basis: auto; width: 200px;. Parece que quando flex-basisnão está definido auto, substitui o width / heightvalor. A única diferença que vejo é a maneira como o excesso de conteúdo é tratado.
Karolis
5

Possivelmente o ponto mais importante a ser adicionado:

E se o navegador não suportar flex? Nesse caso, width/heightassuma o controle e seus valores se aplicam.

É uma idéia muito boa - quase essencial - definir width/heightelementos, mesmo se você tiver um valor completamente diferente para flex-basis. Lembre-se de testar desativando display:flexe vendo o que você recebe.

Niet, o Escuro Absol
fonte
2
Entre os principais navegadores, os únicos que não suportam propriedades de flex são IE <10. caniuse.com/#search=flex
Michael Benjamin
1
@Michael_B Claro, e talvez seja só eu, mas também tenho que suportar navegadores móveis, incluindo o navegador Nintendo 3DS, que decididamente não suporta flex.
Niet the Dark Absol