- CSS Subgrid é um recurso que vai além das limitações do Grid tradicional, permitindo estender a estrutura do grid pai até os elementos DOM filhos
- Antes, apenas os filhos diretos podiam participar do grid, mas com subgrid até estruturas aninhadas como
<ul> e <li> podem usar a mesma disposição em células de grid
- Resolve o desequilíbrio entre elementos irmãos causado por diferenças no comprimento do conteúdo e permite compor layouts em que cada card ou seção reage dinamicamente
- Ainda assim, há pontos de atenção como reserva de linhas, reinicialização da numeração das linhas e incompatibilidade com grids fluidos baseados em auto-fill
- Já há suporte nos principais navegadores e a adoção gradual é possível, o que faz dessa uma técnica capaz de aumentar bastante a flexibilidade no design de UI no futuro
Conceito básico de Subgrid
- No CSS Grid inicial, apenas os elementos filhos diretos podiam participar do layout
- Por exemplo, em uma UI de portfólio, as imagens em
<li> dentro de <ul> normalmente ficam agrupadas em uma única célula
- Com
grid-template-rows: subgrid e grid-template-columns: subgrid, é possível herdar a definição de linhas e colunas do grid pai
- Cada
<li> passa a ser posicionado diretamente nas células do grid pai, mantendo ao mesmo tempo a estrutura HTML semântica e o alinhamento visual
- O mesmo resultado também pode ser obtido com Flexbox e Grid aninhado, mas o subgrid oferece uma abordagem mais enxuta ao compartilhar uma única estrutura de grid
Novas possibilidades de layout
- No exemplo de cards de portfólio, cada
<article> tem um grid de 2 colunas para posicionar imagem e texto
- A unidade
fr é flexível, mas como cada card faz seu cálculo de forma independente, surgem desequilíbrios na largura das colunas
- Ao aplicar
grid-template-columns: subgrid, todos os cards compartilham a proporção de colunas do grid pai
- Conforme o conteúdo muda, como no comprimento do título, todo o grid é reajustado automaticamente
- Dessa forma, é possível criar um layout com reconhecimento mútuo entre elementos irmãos
- Ex.: ao encurtar o título “Infinite Supercomputer”, a proporção entre imagem e texto em todos os cards é ajustada imediatamente
Cuidados ao usar Subgrid (Gotchas)
Reserva de espaço em linhas
- Compartilhar colunas é intuitivo, mas ao compartilhar linhas é necessário fazer uma reserva explícita de linhas
- Ex.: em um card de tabela de preços, para que os itens de cada
<ul> fiquem alinhados na mesma linha, é preciso definir a quantidade de linhas com grid-row: span N
- Por padrão, o subgrid ocupa apenas uma única célula, então, para usar várias linhas, primeiro é preciso expandir a área do grid pai
Numeração em grids aninhados
- O subgrid herda o template de linhas e colunas do pai, mas a numeração das linhas é reiniciada
- Ex.: mesmo herdando as linhas 2 a 5 do grid pai, internamente elas são renumeradas como 1 a 4
- Como cada grid tem seu próprio índice, os números das linhas funcionam como índices relativos, não como IDs únicos
Incompatibilidade com grids fluidos
- Um grid fluido no formato
repeat(auto-fill, minmax()) não pode ser usado junto com subgrid
- O subgrid exige um número definido de colunas, e
auto-fill e auto-fit não são suportados
- O autor afirma explicitamente que não encontrou uma solução para essa combinação
Suporte em navegadores antigos
- Há suporte nos principais navegadores desde 2023, mas a taxa de suporte ainda é inferior a 90%
- Com a condição
@supports not (grid-template-columns: subgrid), é possível oferecer um layout alternativo
- Ex.: propor uma estrutura de fallback com imagem e texto em pilha vertical
Casos reais e conclusão
- O site de desenvolvedores da Stripe (stripe.dev) organiza a página inteira como um grande grid e implementa posicionamentos detalhados por meio de várias camadas de subgrid
- O subgrid é útil não só em layouts grandes, mas também em ajustes menores de UI
- É possível fazer uma adoção gradual sem precisar reestruturar o projeto inteiro
- Como uma forma de garantir nova flexibilidade para layouts em CSS, vale bastante a pena experimentar seu uso
1 comentários
Comentários do Hacker News
O recurso de subgrid é realmente muito legal, mas no primeiro exemplo simples também daria para fazer os filhos participarem do layout em grid com
ul { display: contents }Se o recurso de subgrid não for estritamente necessário, essa abordagem é mais eficiente
display: contentsremove completamente o elemento UL do layoutEntão não dá para aplicar estilos nele nem fazer com que receba eventos de UI
Se você quiser usar a UL como área de destaque ou seção com rolagem, subgrid é muito mais útil
fre deixarfrpara o texto preencher o espaço restanteQuando fiz uma UI de comparação de preços no passado, sofri muito por não haver subgrid
Era impossível colocar duas tabelas lado a lado e alinhar as linhas
Dava para resolver com altura fixa ou cálculos em JS, mas isso era muito ineficiente numa estrutura de componentes em React
Achei que container queries fossem uma solução melhor
Mas, para manter a consistência do grid como um todo, subgrid pode ser mais adequado
Aliás, olhando este exemplo no CodePen, fica mais fácil entender
Além disso, usar container cria um novo stacking context, o que é inconveniente
É uma pena não dar para usar subgrid e container juntos. Se os filhos pudessem referenciar o tamanho do subgrid, seria realmente poderoso
Fica a sensação de “então voltamos ao layout com <table>?”
<table>era um hack para resolver problemas, mas tinha muitas limitações técnicas e de acessibilidadeO sistema de Grid é uma ferramenta para disposição visual, diferente de tabelas que representam estrutura de dados
Agora que grid se consolidou como padrão, eu preferia que ele não fosse mais comparado com tabelas
Mas não havia nenhuma preocupação com responsividade ou acessibilidade. No fim, acabamos reinventando as tabelas
<table>era ser uma estrutura para descrever conteúdo. O grid em si não tem problemaNo fim, o CSS acabou reimplementando essa funcionalidade de forma melhorada
Um dos bugs de grid que já enfrentei foi que, ao definir o tamanho de um elemento
<img>em porcentagem, o tamanho da célula ficava distorcido pelo tamanho original da imagemIsso acontecia tanto no Firefox quanto no Chromium, e o bug relacionado está em Mozilla Bug 1857365
É uma pena que o CSS às vezes exija adicionar informações de estrutura do documento só para fazer layout
Por exemplo, precisar declarar explicitamente o número de linhas
Ou então que um contêiner flex pudesse imitar a distribuição de outro contêiner
Mas isso provavelmente deixaria a DX mais complexa
Fiquei me perguntando por que havia estilos tanto no arquivo HTML quanto no CSS nos exemplos de código
Olhando só o CSS do primeiro exemplo de subgrid, passei um bom tempo tentando descobrir que estilos tinham sido aplicados à UL
Fica a sensação de “então voltamos ao grid de novo?”
Já fazíamos algo parecido na era do HTML antigo
Os posts no blog do Josh são sempre impressionantes
A clareza do texto, o senso de design e até o site interativo, tudo é excelente
Pessoalmente, ainda acho grid meio desconfortável de usar
A sintaxe é estranha e meu senso de layout não encaixa muito bem. Flexbox é bem mais intuitivo e flexível
Flexbox controla tamanhos com foco no conteúdo, enquanto Grid é mais centrado no contêiner
O conteúdo não se ajusta automaticamente em vários eixos, e eu tenho que posicionar tudo manualmente
Talvez eu não tenha entendido bem a essência do grid, ou talvez ele simplesmente não combine com o tipo de trabalho que eu faço