hack flex-grow 9999: o hack de Flexbox que você precisa conhecer

Flexbox guarda muitas surpresas. Conheça o hack flex-grow 9999 e pergunte-se como você conseguiu trabalhar com Flexbox por tanto tempo sem saber disso!

Antes de explicar em detalhes sobre o hack flex-grow 9999, faz-se interessante descrever resumidamente o que ele faz: o hack flex-grow 9999 faz um flex item se comportar como se tivesse dois valores de crescimento (flex-grow) flexíveis. Ele impede que um flex item em uma linha cresça, permitindo este crescimento somente se estiver em sua própria linha. Tudo sem o uso de media queries.

A princípio, isso não faz o menor sentido, certo? Continue lendo e veja o exemplo para as coisas ficarem mais claras.

Imagine um flex container (display: flex) com 2 flex items em uma linha (flex-direction: row): Item A à esquerda e Item B à direita. O Item A não pode crescer, então aplica-se um valor 0 para flex-grow (o valor padrão); o Item B precisa ocupar todo o espaço restante no contêiner — que pode ser alcançado com flex-grow: 1.

A intenção é que os flex items fiquem empilhados (stacked) uns sobre os outros quando necessário. O Item B precisa pular para a segunda linha se não houver espaço suficiente para que ele tenha, por exemplo, pelo menos 20em de largura. Adicionar flex-wrap: wrap para o container e flex-base: 20em para o Item B faz chegar no resultado pretendido.

Uma amostra deste resultado:

Hack flex-grow 9999: primeiro passo da implementação

Agora vem a parte complicada. O Item A deve ser estendido para toda a largura do contêiner somente se os itens estiverem envolvidos (wrapped) em várias linhas. Seria possível usar media queries para atualizar o valor de flex-grow, mas, no caso, pode ser difícil definir exatamente o breakpoint.

As razões pelas quais o breakpoint pode ser difícil de definir são:

  1. A largura do Item A é desconhecida — por exemplo, contém palavras que são mais longas e/ou em outro idioma
  2. Não se sabe a largura do elemento-pai dos componentes — pode se for usado em uma sidebar ou qualquer outro lugar

A ideia é conseguir chegar ao resultado pretendido sem usar media queries, atualizando o valor de flex-grow do Item A para 1. O problema agora é que o Item A também crescerá se ambos os itens estiverem próximos um do outro. Para corrigir isso, é possível atribuir um valor de crescimento flexível ridiculamente grande, como 9999 — daí “hack flex-grow 9999” :-) –, ao Item B.

E eis que o resultado pretendido é alcançado:

Hack flex-grow 9999: resultado final da técnica

Mas, afinal, por que e como o hack flex-grow 9999 funciona?! Flex grow define quanto do espaço livre restante um item flexível recebe. Por exemplo, se houver 100px de espaço livre, é possível atribuir ao Item A 1/4 (25px) do espaço restante (flex-grow: 1) e ao Item B 3/4 (75px) do espaço restante (flex-grow: 3).

No caso em questão, o Item A recebe 1/10000 do espaço restante, o que resulta em 0px (1/10000 * 100 = 0,01). Eventualmente, se houver espaço suficiente, o Item A receberá alguns pixels — mas é preciso um espaço disponível muito grande para que isso aconteça.

Conclusão sobre o hack flex-grow 9999

Apesar de Flexbox já estar “no mercado” há algum tempo, ele tem suas peculiaridades e (o que é muito comum) determinados usos e macetes vão sendo descobertos pela comunidade com seu tempo de uso. É o caso do hack flex-grow 9999.

Como flex-grow funciona pode ser bastante confuso no começo, mas depois de entendido e dominado seu conceito, os proveitos que se tiram daí fazem valer a pena.