Grade CSS: o layout da tabela está de volta. Esteja lá e será quadrado

Texto longo, leia o resumo

Se você já conhece o Flexbox, a grade vai parecer familiar. Rachel Andrew mantém um ótimo site dedicado ao CSS Grid para ajudar você a começar. A grade já está disponível no Google Chrome.

Flexbox? Grade?

Nos últimos anos, o CSS Flexbox se tornou amplamente usado, e o suporte do navegador está muito bom, a menos que você seja uma das pessoas que precisam oferecer suporte ao IE9 e versões anteriores. O Flexbox facilitou muitas tarefas complexas de layout, como espaçamento equidistante entre elementos, layouts de cima para baixo ou o santo graal da magia do CSS: centralização vertical.

Não há como alinhar elementos em vários contêineres Flexbox.

Mas, infelizmente, as telas geralmente têm uma segunda dimensão com a qual precisamos nos preocupar. Infelizmente, não é possível ter ambos, um ritmo vertical e horizontal, usando apenas o flexbox. É aqui que a grade CSS vem para ajudar.

O CSS Grid está em desenvolvimento, atrás de uma flag na maioria dos navegadores há mais de cinco anos, e um tempo extra foi gasto na interoperabilidade para evitar um lançamento com bugs, como o Flexbox. Portanto, se você usar o Grid para implementar seu layout no Chrome, é provável que tenha o mesmo resultado no Firefox e no Safari. No momento da escrita, a implementação do Edge da Microsoft para Grid está desatualizada (a mesma que já estava presente no IE11) e a atualização está "em consideração".

Apesar das semelhanças no conceito e na sintaxe, não pense em Flexbox e Grid como técnicas de layout concorrentes. A grade é organizada em duas dimensões, enquanto o Flexbox é exibido em uma. Há sinergia ao usar os dois juntos.

Como definir uma grade

Para se familiarizar com as propriedades individuais do Grid, recomendo a página Grid By Example de Rachel Andrew ou a Cheat Sheet do CSS Tricks. Se você conhece o Flexbox, muitas das propriedades e o significado delas devem ser familiares.

Vamos conferir um layout de grade padrão de 12 colunas. O layout clássico de 12 colunas é muito usado, porque o número 12 é divisível por 2, 3, 4 e 6 e, portanto, é útil para muitos designs. Vamos implementar este layout:

Não há como alinhar elementos em vários contêineres Flexbox.

Vamos começar com o código de marcação:

<!DOCTYPE html>
<body>
    <header></header>
    <nav></nav>
    <main></main>
    <footer></footer>
</body>

Na folha de estilos, começamos expandindo o body para que ele cubra toda a janela de visualização e o transformando em um contêiner de grade:

html, body {
    width: 100vw;
    min-height: 100vh;
    margin: 0;
    padding: 0;
}
body {
    display: grid;
}

Agora estamos usando a grade CSS. Oba!

A próxima etapa é implementar as linhas e colunas da grade. Poderíamos implementar as 12 colunas no nosso mockup, mas, como não estamos usando todas as colunas, isso tornaria nosso CSS desnecessariamente confuso. Para simplificar, vamos implementar o layout desta forma:

Exemplo de layout simplificado

A largura do cabeçalho e do rodapé é variável, e o conteúdo é variável em ambas as dimensões. O menu também será variável em ambas as dimensões, mas vamos importar uma largura mínima de 200 px. Por quê? Para mostrar os recursos da grade CSS, é claro.

Na grade CSS, o conjunto de colunas e linhas é chamado de faixas. Vamos começar definindo nosso primeiro conjunto de faixas, as linhas:

body {
    display: grid;
    grid-template-rows: 150px auto 100px;
}

grid-template-rows usa uma sequência de tamanhos que definem as linhas individuais. Nesse caso, damos à primeira linha uma altura de 150 px e à última uma altura de 100 px. A linha do meio é definida como auto, o que significa que ela será ajustada à altura necessária para acomodar os itens da grade (os filhos do contêiner da grade) nessa linha. Como o corpo é esticado em toda a viewport, a faixa que contém o conteúdo (amarelo na imagem acima) vai preencher pelo menos todo o espaço disponível, mas vai crescer (e fazer o documento rolar) se for necessário.

Para as colunas, queremos uma abordagem mais dinâmica: queremos que a navegação e o conteúdo cresçam (e encolham), mas queremos que a navegação nunca encolha abaixo de 200 px e que o conteúdo seja maior que a navegação. No Flexbox, usaríamos flex-grow e flex-reduce, mas na grade é um pouco diferente:

body {
    display: grid;
    grid-template-rows: 150px auto 100px;
    grid-template-columns: minmax(200px, 3fr) 9fr;
}

Estamos definindo duas colunas. A primeira coluna é definida usando a função minmax(), que recebe dois valores: o tamanho mínimo e o tamanho máximo da faixa. É como min-width e max-width em um só. A largura mínima é, como discutimos antes, 200 px. A largura máxima é 3fr. fr é uma unidade específica de grade que permite distribuir o espaço disponível para os elementos da grade. fr provavelmente significa "unidade de fração", mas também pode significar "unidade sem custo financeiro". Nossos valores aqui significam que as duas colunas vão crescer para preencher a tela, mas a coluna de conteúdo sempre será três vezes mais larga que a coluna de navegação, desde que a coluna de navegação permaneça mais larga que 200 px.

Embora o posicionamento dos itens da grade ainda não esteja correto, o tamanho das linhas e colunas se comporta corretamente e gera o comportamento que pretendíamos:

Como colocar os itens

Um dos recursos mais eficientes da grade é a capacidade de posicionar itens sem considerar a ordem do DOM. No entanto, como os leitores de tela navegam pelo DOM, recomendamos que você preste atenção em como reordenar os elementos para que eles sejam acessíveis. Se nenhum posicionamento manual for feito, os elementos serão colocados na grade na ordem do DOM, organizados da esquerda para a direita e de cima para baixo. Cada elemento ocupa uma célula. A ordem em que a grade é preenchida pode ser alterada usando grid-auto-flow.

Então, como colocamos os elementos? A maneira mais fácil de posicionar os itens da grade é definindo quais colunas e linhas eles cobrem. O Grid oferece duas sintaxes para fazer isso: Na primeira sintaxe, você define os pontos inicial e final. Na segunda, você define um ponto de partida e um período:

header {
    grid-column: 1 / 3;
}
nav {
    grid-row: 2 / span 2;
}
Posicionamento manual

Queremos que o cabeçalho comece na primeira coluna e termine antes da terceira. O menu precisa começar na segunda linha e abranger duas linhas no total.

Tecnicamente, já implementamos nosso layout, mas quero mostrar alguns recursos de conveniência que a grade oferece para facilitar o posicionamento. O primeiro recurso é que você pode nomear as bordas da faixa e usar esses nomes para a colocação:

body {
    display: grid;
    grid-template-rows: 150px [nav-start] auto 100px [nav-end];
    grid-template-columns: [header-start] minmax(200px, 3fr) 9fr [header-end];
}
header {
    grid-column: header-start / header-end;
}
nav {
    grid-row: nav-start / nav-end;
}

O código acima vai gerar o mesmo layout do código anterior.

O recurso de nomear regiões inteiras na sua grade é ainda mais eficaz:

body {
    display: grid;
    grid-template-rows: 150px auto 100px;
    grid-template-columns: minmax(200px, 3fr) 9fr;
    grid-template-areas: "header header"
                        "nav    content"
                        "nav    footer";
}
header {
    grid-area: header;
}
nav {
    grid-area: nav;
}

grid-template-areas recebe uma string de nomes separados por espaços, permitindo que o desenvolvedor dê um nome a cada célula. Se duas células adjacentes tiverem o mesmo nome, elas serão agrupadas na mesma área. Assim, você pode fornecer mais semântica ao código de layout e tornar as consultas de mídia mais intuitivas. Novamente, esse código vai gerar o mesmo layout de antes.

Tem mais?

Sim, há muito o que falar em uma única postagem do blog. Rachel Andrew, que também é uma GDE, é uma especialista convidada no grupo de trabalho do CSS e trabalha com eles desde o início para garantir que o Grid simplifique o design da Web. Ela até escreveu um livro sobre o assunto. O site Grid By Example (em inglês) é um recurso valioso para se familiarizar com a grade. Muitas pessoas acham que o Grid é uma etapa revolucionária para o design da Web, e agora ele está ativado por padrão no Chrome para que você possa começar a usá-lo hoje mesmo.