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

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

flex-basis 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 dos elementos com o conjunto de base flexível . Com o meu conhecimento atual do flexbox, não vejo por que isso não poderia descrever a largura também.

Eu gostaria de saber exatamente como a flex-base é diferente da largura na prática:

  • Se eu replace a largura por flex-base (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 flexibilidade teria uma diferença significativa no 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?

Editar / esclarecimento : Esta pergunta foi feita em um formato diferente em O que exatamente a propriedade de base flexível define? mas eu senti uma comparação mais direta ou resumo das diferenças de flex-base e largura (ou altura ) seria bom.

Considere flex-direction

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

Quando o flex-direction é row , o flex-basis controla a largura.

Mas quando o flex-direction é column , o flex-basis controla a altura.


Diferenças Chaves

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

  • flex-basis aplica flex-basis se apenas aos itens flexíveis. Os contêineres flex (que também não são flexíveis) ignoram a flex-basis mas podem usar width e height .

  • flex-basis funciona apenas no eixo principal. Por exemplo, se você estiver em flex-direction: column , a propriedade width será necessária para dimensionar os itens flex horizontalmente.

  • flex-basis não tem efeito em itens flexíveis posicionados de forma absoluta. width propriedades de width e height seriam necessárias. Itens flexíveis posicionados de forma absoluta não participam do layout flex .

  • Usando a propriedade flex , três propriedades – flex-grow , flex-shrink e flex-basis – podem ser combinadas em uma única declaração. Usando width , a mesma regra exigiria várias linhas de código.


Comportamento do Navegador

Em termos de como são renderizados, não deve haver diferença entre flex-basis e a width , a menos que flex-basis seja auto ou de content .

Da especificação:

7.2.3. A propriedade de flex-basis

Para todos os valores diferentes de auto e content , flex-basis é resolvida da mesma maneira que a width nos modos de gravação horizontal.

Mas o impacto do auto ou do content pode ser mínimo ou absolutamente nada. Mais da especificação:

auto

Quando especificado em um item flexível, a palavra auto chave auto recupera o valor da propriedade de tamanho principal como a flex-basis usada. Se esse valor for auto , o valor usado será o 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 checkbox flexível e, portanto, algumas implementações mais antigas não suportam isso. O efeito equivalente pode ser alcançado usando auto conjunto com um tamanho principal ( width ou height ) de auto .

Assim, de acordo com a especificação, flex-basis e a width resolvidas de forma idêntica, a menos que flex-basis seja auto ou de content . Nesses casos, a flex-basis pode usar a largura do conteúdo (que, presumivelmente, a propriedade width também usaria).


O fator flex-shrink

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

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

Anote a última configuração.

Como os itens flexíveis têm permissão para reduzir por padrão (o que impede o transbordamento do contêiner), a flex-basis / width / height especificada pode ser substituída.

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

Para renderizar a largura especificada e mantê-la fixa, você precisará desativar a redução:

 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 encorajados a controlar a flexibilidade usando a abreviação flex e não diretamente com suas propriedades de longhand, já que a abreviação redefine corretamente quaisquer componentes não especificados para acomodar usos comuns .


Erros do Navegador

Bug que afeta todos os principais navegadores, exceto o IE 11 e o Edge:

flex-basis ignorada em um contêiner flexível nested. trabalhos de width .

Foi encontrado um problema ao dimensionar itens flexíveis em um contêiner flexível nested.

Ao usar flex-basis , o contêiner ignora o dimensionamento de seus filhos e os filhos transbordam o contêiner. Mas com a propriedade width , o contêiner respeita o dimensionamento de seus filhos e se expande de acordo. Isso não é um problema no IE11 e no Edge.

Referências:

  • O Chrome não expande o pai flexível de acordo com o conteúdo das crianças
  • Diferença entre largura e base flexível
  • A base flexível está sendo ignorada ao dimensionar contêineres flexíveis nesteds.
  • flex-basis: 100px faz algo diferente da largura: 100px + flex-base: auto

Exemplos:

flexionar itens usando flex-basis e white-space: nowrap contêiner white-space: nowrap overflow inline-flex . trabalhos de width .

Parece que um conjunto de contêineres flex para inline-flex não reconhece flex-basis em um filho ao renderizar um irmão com 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 propriedade width é usada em vez de flex-basis , o contêiner respeita o dimensionamento de seus filhos e se expande de acordo. Isso não é um problema no IE11 e no Edge.

Referências:

  • largura do contêiner flex em linha não está crescendo
  • O contêiner flexível Inline (display: inline-flex) está expandindo a largura total do contêiner pai

Exemplo:


Erros que afetam o IE 10 e 11:

  • declarações flex atalho com valores de flex-basis sem unidade são ignoradas
  • flex-basis não leva em consideração o box-sizing: border-box
  • flex-basis não suporta calc()
  • A importância é ignorada na flex-basis flex quando se usa taquigrafia flex

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

flex-basis 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 a largura / altura até que as outras propriedades de aumento / redução de flexão entrem em ação.

Assim. uma criança com

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

terá 25% de largura inicialmente, mas imediatamente se expandirá o máximo que puder até que os outros elementos sejam fatorados. Se não houver nenhum, ele terá 100% de largura / altura.

Uma demonstração rápida:

 .flex { width: 80%; margin: 1em auto; height: 25px; display: flex; background: rebeccapurple; } .child { flex-basis: auto; /* default */ background: plum; } .value { flex-basis: 25%; } .grow { flex-grow: 1; } 
 
Some Content
Some Content
Some Content

Possivelmente, o ponto mais importante para adicionar:

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

É uma ideia muito boa – quase essencial – definir a width/height dos elementos, mesmo que você tenha um valor completamente diferente para a flex-basis . Lembre-se de testar desativando a display:flex e ver o que você obtém.