Grade CSS Nível 2: Aí vem a subgrade

Publicados: 2022-03-10
Resumo rápido ↬ O CSS Grid Level 2 já está em processo de especificação, e a principal característica deste nível da especificação é nos trazer subgrid. Neste artigo, Rachel Andrew explica os novos recursos.

Estamos agora há mais de um ano desde o pouso do CSS Grid Layout na maioria dos nossos navegadores, e o CSS Working Group já está trabalhando no Nível 2 da especificação. Neste artigo, explicarei o que atualmente faz parte do Projeto de Trabalho e do Editor dessa especificação. Observe que tudo aqui está sujeito a alterações e nada disso funciona atualmente em navegadores. Veja isso como uma espiada no processo, tenho certeza que escreverei peças mais práticas à medida que começarmos a ver as implementações tomarem forma.

Níveis de Especificação CSS

Os recursos CSS Grid que podemos usar atualmente em navegadores são aqueles do Nível 1 da especificação CSS Grid. As várias partes do CSS são divididas em módulos; essa modularização aconteceu quando o CSS passou do CSS 2.1, e é por isso que às vezes você ouve as pessoas falando sobre CSS3. Na realidade, não existe CSS3. Em vez disso, havia um conjunto de módulos que incluía todas as coisas que já faziam parte da especificação CSS2.1. Qualquer CSS que existia no CSS2.1 passou a fazer parte de um módulo de Nível 3, portanto, temos Seletores de CSS de Nível 3, pois os seletores existiam no CSS2.1.

Novos recursos CSS que não faziam parte do CSS2.1, como CSS Grid Layout, começam no Nível 1. A especificação CSS Grid Nível 1 é essencialmente a primeira versão do Grid. Depois que um Nível de especificação atinge o status de Recomendação de Candidato, os novos recursos importantes não são adicionados. Isso significa que navegadores e outros agentes de usuário podem implementar a especificação e ela pode se tornar uma recomendação do W3C. Se novos recursos forem projetados, eles acontecerão em um novo Nível da especificação. Estamos neste ponto com CSS Grid Layout. A especificação de Nível 1 está em CR, e uma especificação de Nível 2 foi criada para que novos recursos sejam trabalhados. Eu sugiro dar uma olhada no Editor's Draft se você quiser acompanhar as discussões de especificação, pois ele conterá todas as edições mais recentes.

Mais depois do salto! Continue lendo abaixo ↓

O que o nível 2 da grade CSS conterá?

Por fim, a especificação de nível 2 conterá tudo o que já está no nível 1, além de alguns novos recursos. Se você der uma olhada na especificação no momento da escrita, há uma nota explicando que todo o Nível 1 deve ser copiado assim que o Nível 2 atingir o CR.

Podemos então esperar encontrar alguns novos recursos, e o Nível 2 da Especificação de Grade trata de trabalhar o recurso de subgrade do CSS Grid. Esse recurso foi retirado da especificação do Nível 1 para dar tempo para entender adequadamente os casos de uso da subgrade e dar mais tempo para trabalhar nele sem atrasar o restante do Nível 1. No restante deste artigo, vou estar dando uma olhada no recurso de subgrade como está atualmente detalhado no Rascunho do Editor. Estamos em um estágio muito inicial com o recurso, no entanto, este é o momento perfeito para acompanhar e realmente ajudar a moldar como a especificação é desenvolvida. Meu objetivo ao escrever este artigo é explicar algumas das coisas que estão sendo discutidas, para que você possa entender e trazer sua opinião para as discussões.

O que é uma sub-rede?

Ao usar o CSS Grid Layout, você já pode aninhar as grades. No exemplo abaixo, tenho uma grade pai com faixas de seis colunas e faixas de três linhas. Eu posicionei um item nesta grade da linha de coluna 2 para a linha 6 e da linha de linha 1 para 3. Eu então fiz desse item um contêiner de grade e faixas de coluna definidas.

 .grid { display: grid; grid-template-columns: 1fr 2fr 1fr 2fr 1fr 2fr; grid-template-rows: auto auto auto; } .item { grid-column: 2 / 6; grid-row: 1 / 3; display: grid; grid-template-columns: 2fr 1fr 2fr 1fr; }

As trilhas de nossa grade aninhada não têm relação com as trilhas do pai. Isso significa que, se quisermos alinhar as faixas de nossa grade aninhada com as linhas da grade externa, temos que fazer o trabalho e usar métodos de cálculo de tamanhos de faixas que garantam que todas as faixas permaneçam iguais. No exemplo acima, as faixas ficarão alinhadas, até que um item de tamanho maior seja adicionado a uma célula da grade (fazendo com que ela ocupe mais espaço).

Uma grade com o inspetor de grade do Firefox mostrando as linhas
Um pequeno item significa que as faixas parecem estar alinhadas. (Visualização grande)
Assim como no primeiro exemplo, exceto que a grade aninhada agora não se alinha com a externa.
Com um item grande, podemos ver que as faixas não se alinham. (Visualização grande)

Para colunas, muitas vezes é possível contornar o cenário acima, essencialmente restringindo a flexibilidade da grade. Você pode tornar suas colunas de unidade fr minmax(0,1fr) para que elas ignorem o tamanho do item ao fazer a distribuição de espaço, ou você pode voltar a usar porcentagens. No entanto, isso remove alguns dos benefícios do uso de grade e, quando se trata de alinhar linhas em uma grade aninhada, esses métodos não funcionarão.

Digamos que queremos um layout de cartão no qual os cartões individuais tenham cabeçalho, corpo e rodapé. Também queremos que o cabeçalho e o rodapé se alinhem nos cartões.

 .cards { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 20px; } .card { display: grid; grid-template-rows: auto 1fr auto; }
Três cartões em um recipiente
Um conjunto de cartões (visualização grande)

Isso funciona desde que o conteúdo tenha a mesma altura em cada cabeçalho e rodapé. Se tivermos conteúdo extra, a ilusão será quebrada e os cabeçalhos e rodapés não estarão mais alinhados na linha.

Três cartões em um recipiente, um cabeçalho mais alto que os outros
Não podemos alinhar os cabeçalhos nos cartões. (Visualização grande)

Criando uma subgrade

Agora podemos dar uma olhada em como o recurso de subgrade está atualmente especificado e como ele pode resolver os problemas que mostrei acima.

Nota : No momento da escrita, nenhum dos códigos abaixo funciona em navegadores. O objetivo aqui é explicar a sintaxe e os conceitos. A especificação final também provavelmente mudará a partir desses detalhes. Para referência, escrevi este artigo com base no Editor's Draft disponível em 23 de junho de 2018.

Para criar uma subgrade, teremos um novo valor para grid-template-rows e grid-template-columns . Essas propriedades são normalmente usadas com uma lista de trilhas, que define o número e o tamanho das trilhas de linha e coluna. Ao criar uma subgrade, no entanto, você não deseja especificar essas faixas. Em vez disso, você usa o valor de subgrid para informar à grade que essa grade aninhada deve usar o número de faixas e o dimensionamento de faixas que a área de grade que ela cobre abrange.

No código abaixo, tenho uma grade pai com faixas de 6 colunas e faixas de 3 linhas. A grade aninhada é um item de grade nessa grade pai e se estende da linha de coluna 2 à linha de coluna 6 e da linha de linha 1 à linha de linha 4. Isso é exatamente como nosso exemplo inicial, no entanto, agora podemos dar uma olhada usando subgrade. A grade aninhada tem um valor de subgrid para grid-template-columns e grid-template-rows . Isso significa que a grade aninhada agora tem trilhas de 4 colunas e trilhas de 2 linhas, usando o mesmo dimensionamento das trilhas definidas no pai.

 .grid { display: grid; grid-template-columns: 1fr 2fr 1fr 2fr 1fr 2fr; grid-template-rows: auto auto auto; } .item { grid-column: 2 / 6; grid-row: 1 / 3; display: grid; grid-template-columns: subgrid; grid-template-rows: subgrid; }
Diagrama de uma grade
A grade aninhada está usando as faixas definidas no pai. (Visualização grande)

Isso significaria que qualquer alteração no dimensionamento da faixa no pai seria seguida pela grade aninhada. Uma palavra mais longa tornando uma das faixas na grade pai mais larga resultaria em que a faixa na grade aninhada também se tornasse mais larga, então as coisas continuariam a se alinhar. Isso também funcionaria de outra maneira: as faixas da grade pai poderiam se tornar mais amplas com base no conteúdo da subgrade.

Subgrades Unidimensionais

Você pode ter uma subgrade em uma dimensão e especificar o dimensionamento da trilha em outra. Neste próximo exemplo, a subgrade é especificada apenas em grid-template-columns . A propriedade grid-template-rows tem uma lista de faixas especificada. As trilhas de coluna permanecerão, portanto, como as quatro trilhas que vimos acima, mas as trilhas de linha podem ser definidas separadamente das trilhas do pai.

 .grid { display: grid; grid-template-columns: 1fr 2fr 1fr 2fr 1fr 2fr; grid-template-rows: auto auto auto; } .item { grid-column: 2 / 6; grid-row: 1 / 3; display: grid; grid-template-columns: subgrid; grid-template-rows: 10em 5em 200px 200px; }

Isso significa que as linhas da subgrade serão aninhadas dentro da grade pai, assim como ao criar uma grade aninhada hoje. Como nossa grade aninhada abrange duas linhas do pai, uma ou ambas as linhas precisarão ser expandidas para conter o conteúdo da subgrade para não causar estouros.

Você também pode ter uma subgrade em uma dimensão e a outra dimensão usar faixas implícitas. No exemplo abaixo, não especifiquei nenhuma trilha de linha e dei um valor para grid-auto-rows . As linhas serão criadas na grade implícita no tamanho que especifiquei e, como no exemplo anterior, o pai precisará ter espaço para essas linhas ou expandir para contê-las.

 .grid { display: grid; grid-template-columns: 1fr 2fr 1fr 2fr 1fr 2fr; grid-template-rows: auto auto auto; } .item { grid-column: 2 / 6; grid-row: 1 / 3; display: grid; grid-template-columns: subgrid; grid-auto-rows: minmax(200px, auto); }

Numeração de linha e subgrade

Se dermos uma olhada no nosso primeiro exemplo novamente, o tamanho da trilha de nossa subgrade é ditado pelo pai em ambas as dimensões. Os números de linha, no entanto, agem normalmente na subgrade. A primeira linha de coluna na direção em linha é a linha 1 e a linha na extremidade mais distante da direção em linha é a linha -1. Você não se refere às linhas da subgrade com o número da linha do pai.

 .grid { display: grid; grid-template-columns: 1fr 2fr 1fr 2fr 1fr 2fr; grid-template-rows: auto auto auto; } .item { grid-column: 2 / 6; grid-row: 1 / 3; display: grid; grid-template-columns: subgrid; grid-template-rows: subgrid; } .subitem { grid-column: 2 / 4; grid-row: 2; }
Diagrama de uma grade com outra aninhada dentro
A grade aninhada começa a numerar na linha 1. (Visualização grande)

Lacunas e subgrades

A subgrade herdará qualquer intervalo de coluna ou linha definido na grade pai, no entanto, isso pode ser substituído por intervalos de coluna e linha especificados na subgrade. Se, por exemplo, a grade pai tiver um column-gap definido como 20px, mas a subgrade tiver column-gap definido como 0, as células da grade da subgrade ganharão 10px de cada lado para reduzir o intervalo para 0, com a linha de grade essencialmente correndo no meio da lacuna.

Agora podemos ver como a subgrade nos ajudaria a resolver o segundo caso de uso do início deste artigo, ter cartões com cabeçalhos e rodapés alinhados entre os cartões.

 .grid { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-auto-rows: auto 1fr auto; grid-gap: 20px; } .card { grid-row: auto / span 3; /* use three rows of the parent grid */ display: grid; grid-template-rows: subgrid; grid-gap: 0; /* set the gap to 0 on the subgrid so our cards don't have gaps */ }
Três cartões com cabeçalhos e rodapés alinhados
Os internos do cartão agora se alinham (visualização grande)

Nomes de linha e subgrade

Quaisquer nomes de linha em sua grade pai serão passados ​​para a subgrade. Portanto, se nomearmos as linhas em nossa grade pai, poderíamos posicionar o item de acordo com esses nomes de linha.

 .grid { display: grid; grid-template-columns: [a] 1fr [b] 2fr [c] 1fr [d] 2fr [e] 1fr [f] 2fr [g]; grid-template-rows: auto auto auto; } .item { grid-column: 2 / 6; grid-row: 1 / 3; display: grid; grid-template-columns: subgrid; grid-template-rows: 10em 5em 200px 200px; } .subitem { grid-column: c / e; }
Diagrama mostrando que os nomes de linha se aplicam à grade e à subgrade
Os nomes de linha no pai se aplicam à subgrade. (Visualização grande)

Você também pode adicionar nomes de linha à sua subgrade, as linhas de grade podem ter vários nomes de linha para que esses nomes sejam adicionados às linhas. Para especificar nomes de linha, adicione uma lista desses nomes após o valor de subgrid de grid-template-columns e grid-template-rows . Se pegarmos nosso exemplo acima e também adicionarmos nomes às linhas da subgrade, terminaremos com dois nomes de linha para qualquer linha na subgrade.

 .grid { display: grid; grid-template-columns: [a] 1fr [b] 2fr [c] 1fr [d] 2fr [e] 1fr [f] 2fr [g]; grid-template-rows: auto auto auto; } .item { grid-column: 2 / 6; grid-row: 1 / 3; display: grid; grid-template-columns: subgrid [sub-a] [sub-b] [sub-c] [sub-d] [sub-e]; grid-template-rows: 10em 5em 200px 200px; } .subitem { grid-column: c / e; }
Diagrama mostrando nomes de linha na subgrade são adicionados aos do pai
Os nomes de linha especificados na subgrade são adicionados aos do pai. (Visualização grande)

Faixas implícitas e subgrade

Depois de decidir que uma dimensão de sua grade é uma subgrade, isso remove a capacidade de ter quaisquer faixas implícitas adicionais nessa dimensão. Se você adicionar mais itens que couberem, os itens adicionais serão colocados na última trilha disponível da subgrade da mesma forma que os itens são tratados em grades muito grandes. Uma Área de Grade criada na subgrade que abrange mais trilhas do que as disponíveis, terá sua última linha definida como a última linha da subgrade.

Como explicado acima, no entanto, você pode fazer com que uma dimensão de sua subgrade se comporte exatamente da mesma maneira que uma grade aninhada normal, incluindo faixas implícitas.

Envolvendo-se com o processo

O trabalho do CSS Working Group acontece em público, no GitHub, como qualquer outro projeto de código aberto. Isso torna um pouco mais fácil acompanhar o trabalho que foi o que aconteceu em uma lista de discussão. Você pode dar uma olhada nos problemas levantados no Nível 2 da especificação CSS Grid procurando por problemas marcados como css-grid-2 no repositório GitHub do CSS Working Group. Se você puder contribuir com pensamentos ou um caso de uso para qualquer um desses problemas, será bem-vindo.

Existem outros recursos que as pessoas solicitaram para CSS Grid Layout, e o fato de não terem sido incluídos no Nível 2 não significa que não estejam sendo considerados. Você pode ver os níveis como uma versão de recurso pode estar em um produto, só porque algum recurso não faz parte do sprint atual, não significa que nunca acontecerá. Trabalhar em novos recursos da plataforma web tende a demorar um pouco mais do que o lançamento médio do produto, mas é um processo semelhante.

Quanto tempo isso tudo leva?

O desenvolvimento de especificações e a implementação do navegador é um processo iterativo um tanto circular. Não é o caso que a especificação precisa ser “terminada” antes de vermos algumas implementações do navegador. As implementações iniciais provavelmente estarão por trás dos sinalizadores de recursos - assim como a especificação original da grade. Fique de olho para eles aparecerem, pois uma vez que há código para brincar com ele, fica muito mais fácil pensar sobre esses recursos!

Espero que este passeio do que pode estar por vir tenha sido interessante. Estou animado que o recurso de subgrade está em andamento, pois sempre acreditei que é vital para um sistema de layout de grade completo para a web, assista a este espaço para mais notícias sobre como o recurso está progredindo e sobre as implementações de navegadores emergentes.