Padrões de design editorial com grade CSS e colunas nomeadas
Publicados: 2022-03-10Muitos sites, em particular aqueles que exibem conteúdo de formato longo, têm um padrão de repetição bastante simples de componentes: uma área de largura total para imagens, uma área de conteúdo central e talvez uma exibição dividida de dois blocos de meia largura. Esses componentes se repetem para exibir um artigo, imagens e outros conteúdos relacionados — com os editores de conteúdo selecionando o componente certo à medida que criam artigos para publicação.
Neste artigo, vou demonstrar uma abordagem para esse tipo de design editorial, que se baseia em algumas técnicas, algumas das quais são discutidas nos seguintes artigos:
- “Quebrando com o layout de grade CSS”
- “Quebrando com a grade CSS explicada”
- “Nomeando coisas no layout de grade CSS”
Além de ser uma boa maneira de nomear seções de seu layout, essa técnica expõe um monte de coisas interessantes sobre Grid Layout que você pode achar útil na criação de seus próprios padrões de layout. Ele também demonstra mais da promessa do subgrid (uma parte do próximo Nível 2 da especificação do grid e sendo implementado no Firefox).
Nomeando coisas no layout de grade CSS
Ao usar CSS Grid Layout, você pode nomear linhas e áreas. Ambas as coisas podem tornar o trabalho com Grid — especialmente grades complexas — mais simples. Definir convenções de nomenclatura para coisas em seu layout pode ser útil ao trabalhar com sua equipe; é muito mais fácil entender onde qualquer coisa colocada com grid-area: content
vai acabar do que ter algo colocado de column-line: 3 / 9
.
Ao usar a abordagem grid-template-areas
, você atribui um nome aos itens que deseja colocar na grade usando a propriedade grid-area
e, em seguida, colocando-os ao redor da grade. No exemplo a seguir, o item com grid-area: content
vai para a área de grid definida pela propriedade grid-template-areas
:
Isso funciona bem para componentes em que você tem um item para entrar em uma área; no entanto, se você quiser colocar várias coisas na área de conteúdo (uma abaixo da outra), usar grid-area
é a abordagem errada. Em vez disso, você pode definir nomes para as linhas de coluna e colocar o item do início ao fim da linha.
Isso não é tão legal, no entanto, ao usar a abordagem de área de grade, temos que conhecer a linha inicial e final ao colocar um item usando grid-column
grid-row
- ou não é?
Dê uma olhada neste próximo exemplo do CodePen. Meus itens são colocados usando um único nome ou ident usando a propriedade grid-column
, mesmo que algumas das áreas de grade segmentadas cruzem várias colunas:
Meu objetivo aqui é abstrair a complexidade da configuração da grade ao realmente usar a grade. Posso trabalhar muito para criar a grade inicial, mas depois coloco as coisas sem pensar muito sobre isso enquanto preencho minhas páginas. Também quero ter certeza de que podemos repetir os componentes com a frequência necessária à medida que construímos o artigo. O que tenho em mente é um criador de conteúdo usando um CMS e criando blocos de conteúdo usando os diferentes padrões, sabendo que eles serão colocados corretamente um abaixo do outro na grade geral.
Para entender como cheguei a esse ponto, é necessário entender algumas coisas sobre CSS Grid Layout, bem como linhas e áreas nomeadas.
Podemos nomear linhas
Como você já viu no meu segundo exemplo acima, podemos nomear linhas na grade que podem ser praticamente qualquer coisa que quisermos — além da palavra span
. O nome é um ident em vez de uma string e é por isso que não é citado.
No entanto, você verá muitos exemplos em que as convenções de nomenclatura name-start
e name-end
são usadas, acrescentando -start
ao nome da linha inicial e -end
ao nome da linha final. Isso não é puramente convenção e, para a técnica, vou mostrar por que precisamos nomear nossas linhas dessa maneira. Portanto, você deve escolher um nome para a área que está descrevendo e adicionar os sufixos -start
e -end
- que precisam corresponder, é claro!
Nomeamos nossas linhas entre colchetes. As linhas podem (e geralmente precisam) ter vários nomes. Neste caso, o espaço separa os nomes. Ao colocar os itens usando o posicionamento baseado em linha, você pode escolher qualquer nome para a linha para fazer o posicionamento.
Com nossas linhas nomeadas no lugar, poderíamos colocar nossos itens usando grid-column
especificando o nome da linha inicial e final. Este padrão é o mesmo que usar números de linha, então o nome antes da barra é a linha inicial e o nome depois é a linha final.
Isso coloca os itens, mas não é o nome único por item que usei no exemplo. No entanto, agora temos tudo no lugar devido à maneira especial que Grid lida com áreas e linhas nomeadas.
Os nomes de linha nos fornecem uma área nomeada
Supondo que você tenha nomeado suas linhas com -start
e -end
como eu fiz, Grid fornecerá uma área nomeada do nome principal que você usou. Portanto, no meu caso, tenho áreas chamadas content
, start-half
, end-half
, full
e center
. Cada uma dessas áreas é uma única linha (já que não tenho linhas nomeadas), no entanto, ela abrangerá as faixas de coluna da linha -start
à -end
.
Áreas nomeadas nos fornecem uma linha nomeada do nome principal usado
Se quisermos colocar nossos itens como se tivéssemos um nome de coluna, também precisamos aproveitar o fato de que quando criamos uma área de grade, obtemos um nome de linha do nome principal usado; ou seja, o nome principal sendo o nome com -start
e -end
removidos. Esse nome de linha resolve para o início ou fim da área, dependendo se estamos segmentando grid-column-start
ou grid-column-end
.
Então, temos uma área chamada content
, porque temos linhas de coluna chamadas content-start
e content-end
. A área chamada content
também nos dá a capacidade de usar grid-column-start: content
que irá resolver para a linha inicial dessa área de conteúdo, enquanto grid-column-end: content
irá resolver para a linha final da área de conteúdo.
Isso, portanto, significa que podemos colocar um item na área de conteúdo usando o seguinte:
.content { grid-column: content / content; }
Em seguida, agora podemos arrumar essa técnica ainda mais devido ao fato de que, se você usar uma linha nomeada para grid-column-start
e omitir a linha final (em vez de abranger uma faixa como seria o caso se você usasse números de linha), grid copia o nome para a linha final. Portanto, grid-column: content
é exatamente o mesmo que grid-column: content / content;
Isso é tudo o que precisamos para poder colocar itens usando grid-column
com um nome simples e único. Esse comportamento é exatamente como especificado e não é algum tipo de “hack”. Ele demonstra a profundidade do pensamento que entrou na criação da especificação Grid Layout, e a quantidade de trabalho cuidadoso que foi feito para tornar tão simples a disposição dos itens em nossos projetos.
Dando superpoderes a essa técnica com o Subgrid
Eu acho que essa técnica é legal que permite uma maneira muito direta de declarar onde os elementos devem ser colocados na grade. No entanto, se adicionarmos suporte a subgrade ao mix, ele se tornará realmente muito poderoso.
Atualmente, a subgrade está sendo implementada no Firefox e, portanto, esses próximos exemplos exigem que o Firefox Nightly seja executado. Você pode baixar o Nightly aqui.
O valor de subgrid
de grid-template-columns
e grid-template-rows
significa que o dimensionamento criado em uma grade pai pode ser aceito por um item que é filho da grade (supondo que também esteja usando layout de grade) display: grid
aplicada.
Nota : Você pode ler mais sobre os recursos do subgrid em meus artigos aqui na Smashing Magazine “CSS Grid Level 2: Here Comes Subgrid” e “Indo na propriedade de exibição: Grids All The Way Down”.
Nomes de linha do pai são passados para subgrades
Além das informações de dimensionamento das trilhas serem passadas para a grade filha, quaisquer nomes de linha definidos no pai serão passados. Isso significa que podemos usar nossos “nomes de coluna” dentro de componentes subgrade, tornando esta solução muito útil em um mundo onde existe uma sub-rede. Um item colocado no content
- mesmo se aninhado dentro de subgrades - será alinhado com um colocado como filho direto da grade principal.
Neste próximo exemplo, aninhei dois elementos diretamente dentro do div com uma classe de full-2
. Eu também coloquei um ul
dentro .content
. Se olharmos para os itens dentro full-2
, para colocá-los na grade pai, precisamos fazer do seletor full-2
uma grade com display: grid
então use a propriedade grid-template-columns
com um valor de subgrid
.
Isso faz com que a grade em .full-2
use as trilhas definidas na grade pai e tenha acesso às linhas nomeadas definidas lá. Como este é um item de largura total, ele realmente se comportará como a grade pai em termos de colocação de nossos itens. Podemos então usar qualquer um dos nomes que definimos para as diferentes colunas para colocar os itens. Nesse caso, defini os dois elementos filho como grid-column: center
e eles são exibidos um após o outro nessa área central.
.full-2 { grid-row: 4; grid-column: full; display: grid; row-gap: 10px; grid-template-columns: subgrid; } .full-2 > div { background-color: rgb(124,222,220); grid-column: center; }
Se dermos uma olhada em nossa ul
aninhada dentro de .content
, precisaremos criar uma subgrade no seletor .content
exatamente como no último exemplo; quando fazemos isso, o ul
cai na primeira trilha da subgrade. Se quisermos dispor os itens de escuta na subgrade, precisamos fazer duas coisas: fazer com que o ul ocupe a mesma área que seu pai, colocando-o com grid-column: content
e, em seguida, tornando-o um grid que é uma sub-rede.
Feito isso, os itens da lista serão dispostos usando posicionamento automático nas faixas de coluna da subgrade:
.content { grid-row: 1; grid-column: content; display: grid; grid-template-columns: subgrid; } .content ul { grid-column: content; display: grid; row-gap: 10px; grid-template-columns: subgrid; }
Depois de ter sua grade, você pode usar os nomes do pai exatamente da mesma maneira que antes.
.content li:nth-child(1) { grid-column: center; } .content li:nth-child(2) { grid-column: start-half; } .content li:nth-child(3) { grid-column: end-half; } .content li:nth-child(4) { grid-column: content; }
Se você tem o Firefox Nightly, pode ver a demonstração completa neste exemplo do CodePen:
Você pode manter as subgrades “aninhadas” em sua estrutura de marcação assim, e cada vez que os nomes das linhas serão passados. Este é um recurso que eu acho que será particularmente útil.
Quando você cria uma subgrade, os números de linha correspondem às linhas da subgrade e não à grade pai. Portanto, se você quiser garantir que os elementos na subgrade se alinhem com a grade pai, usar nomes de linha ou áreas nomeadas (como mostrado neste exemplo) tornará isso simples e lógico.
Empacotando
Agora você sabe como usar essa técnica para sua grade principal, e esperamos que não demore muito para começarmos a ver suporte para subgrade em todos os navegadores. Ele habilitará técnicas como esta e a tornará incrivelmente poderosa para nós usarmos.