Tudo sobre Tecnologia da Informação

Dicas de Grid Layout Parte 1

O Grid Layout é um sistema para criação de layout baseado em uma grade bidimensional e otimizado para design de interfaces de usuário. Nesse modelo de grade, os elementos filhos do container que define a grade podem ser posicionados livremente em espaços criados na estrutura, quer ela tenha sido definida com suas dimensões flexíveis ou fixas.

Basicamente, vamos dividir um site em linhas e colunas, como uma grade, para organizar o mesmo, de forma semelhante a uma matriz. O site, no entanto, pode se adaptar a uma tela menor, como a de um celular.

Em versões mais antigas do HTML, era comum usarmos tabelas pra montar a estrutura de um site. As tabelas existem até hoje no HTML5, mas não é prático usar elas pra estruturar um site, o Grid Layout faz isso de forma muito mais fluída e responsiva.

Vamos supor um grid 6 × 6 (6 linhas e 6 colunas), a linha é chamada em inglês de row e a coluna de column (atenção que existe o line também mas ele é usado em algo diferente, no caso, das barras que dividem os itens). Um container é o grid em si (a parte de fora) e cada um elemento dentro dele é chamado de item. Uma linha ou coluna de forma generalizada, é chamada de track, mais especificamente row track e column track. Um grid 6 × 6 tem sete lines contadas a partir do 1, a partir da esquerda e de cima, e temos também a numeração inversa, com números negativos, contados a partir da direita e de baixo. Veja essa imagem abaixo:

Grid

Na imagem acima, temos uma área que vai da line 2 até a -2 (penúltima, que no caso é 6). Uma área pode ter uma quantidade ilimitada de linhas e colunas, e elas podem ter um respiro entre elas, que é o que chamamos de gap, e pode ter tamanho variável, que não interferem no tamanho dos itens.

O container do Grid Layout tem algumas propriedades específicas, que são display, grid-template-columns, grid-template-rows e gap. Existem outras, mas primeiramente vamos focar nessas.

Vamos exemplificar num grid 3 × 3, que tem 3 tracks e cada track tem 4 lines. A linha da parte de fora é o grid container, que no caso do Grid, é bidimensional (no FlexBox é unidimensional). Para especificar que é um grid, nós colocamos display: grid.

Vamos supor esse HTML:


<div class="container">
    <div class="item">A</div>
    <div class="item">B</div>
    <div class="item">C</div>
    <div class="item">D</div>
    <div class="item">E</div>
    <div class="item">F</div>
    <div class="item">G</div>
</div>

Com esse CSS:


div.container {
    display: grid;
    grid-template-columns: auto auto auto;
    grid-template-rows: 100px 100px 100px;
    gap: 20px;
}

div.item {
    background-color: lightgray;
}

Ao colocar apenas display: grid ele não faz nada praticamente, pois automaticamente ele é um grid de uma coluna e várias linhas. Para isso devemos colocar as outras opções para os configurar. Ao colocar grid-template-columns: auto auto ele criará um grid com duas colunas (se tiver auto auto auto terá três, e assim por diante). A mesma coisa se aplica ao grid-template-rows: 100px 100px 100px para linhas, que no caso, definimos um tamanho padrão. O gap: 20px cria um espacinho definido entre os itens, e podemos ter configurações específicas pra colunas e linhas também.

Para começar, no index.html coloque esse código:


<div class="container">
    <div class="item">A</div>
    <div class="item">B</div>
    <div class="item">C</div>
    <div class="item">D</div>
    <div class="item">E</div>
    <div class="item">F</div>
    <div class="item">G</div>
</div>

Com esse estilo:


div.container {
    border: 3px solid blue;
    height: 250px;
    display: grid;
}

div.item {
    border: 3px solid red;
    padding: 5px;
}

Lembrando que, à primeira vista, o container pode não mudar nada, mas ele se torna sim um Grid, mas teremos que colocar outras configurações pra ele funcionar.

Deixe o CSS do container assim:


div.container {
    border: 3px solid blue;
    height: 250px;
    display: grid;
    grid-template-columns: auto auto auto;
    grid-template-rows: auto auto auto;
    gap: 5px;
}

No caso acima, ele terá um Grid com três linhas e três colunas, de tamanho auto.

Ao abrir o Inspecionar Elemento do navegador, em Inspetor e Layout (pode variar de navegador pra navegador), podemos clicar no elemento HTML, que estará marcado com grid, e ele mostrará os elementos do Grid, onde poderemos ver inclusive a numeração do container. Podemos brincar um pouco com os elementos ali, como, por exemplo, o tamanho do gap.

Temos várias outras propriedades para usarmos pelo Grid Layout, o align-items, o justify-items, o align-content e o justify-content, onde os align são para alinhamento vertical e o justify são pra alinhamento horizontal.

Usando o mesmo HTML do exemplo anterior, vamos colocar esse CSS:


div.container {
    border: 3px solid blue;
    display: grid;
    grid-template-columns: auto auto auto;
    grid-template-rows: 100px 100px 100px;
}

div.item {
    border: 3px solid red;
    padding: 5px;
}

No container, vamos deixar o CSS assim:


div.container {
    border: 3px solid blue;
    display: grid;
    grid-template-columns: auto auto auto;
    grid-template-rows: 100px 100px 100px;
    align-items: stretch;
    justify-items: stretch;
}

div.item {
    border: 3px solid red;
    padding: 5px;
}

O stretch é o padrão pra align-items, caso não coloquemos nada, ele estica verticalmente. Podemos colocar também os valores start, center e end. Brinque com essas opções, mas vamos trabalhar com o stretch. O mesmo vale pro justify-items, que ajusta horizontalmente.

Agora colocaremos o align-content e o justify-content, ele alinhará todo o conteúdo da grade, sendo o primeiro verticalmente e o segundo horizontalmente. O padrão de ambos é o stretch, mas podemos colocar os valores start, center, end, space-between, space-evenly e space-around, de forma semelhante ao que acontecia no FlexBox. Deixe o CSS assim e depois brinque um pouco com essas opções:


div.container {
    border: 3px solid blue;
    height: 500px; /* Aumentando o container para vermos o espaçamento */
    display: grid;
    grid-template-columns: auto auto auto;
    grid-template-rows: 100px 100px 100px;
    align-items: stretch;
    justify-items: stretch;
    align-content: start;
    justify-content: start;
}

Após terminar de brincar, deixe as opções dos content como stretch.

Com o mesmo HTML dos itens de A a G, deixe o CSS assim:


div.container {
    border: 3px solid blue;
    height: 500px;
    display: grid;
    grid-template-columns: auto auto auto;
    grid-template-rows: auto auto auto;
    gap: 10px;
}

div.item {
    border: 3px solid red;
    padding: 5px;
}

Deixe o CSS do container assim:


div.container {
    border: 3px solid blue;
    height: 500px;
    display: grid;
    grid-template-columns: auto auto auto;
    grid-template-rows: auto auto auto;
    gap: 10px;
    align-items: normal;
    justify-items: normal;
    align-content: normal;
    justify-content: normal;
}

Como visto, o normal é o stretch (esticar).

Tente em cada um dos itens, além do stretch, o start, center e end.

Tente em cada um dos content, além do stretch, start, center, end, space-between, space-evenly e space-around.

Ainda temos mais propriedades de container para o Grid Layout, como o grid-auto-rows, grid-auto-columns, place-items, place-content e grid-template, sendo que os três últimos são simplificações de propriedades vistas anteriormente. Vamos continuar com o HTML de A a G, e coloque o H e o I também, com esse CSS:


div.container {
    border: 3px solid blue;
    display: grid;
    grid-template-columns: auto auto auto;
    grid-template-rows: 100px 100px 100px;
}

div.item {
    border: 3px solid red;
    padding: 5px;
}

No caso acima, o container terá só 9 itens, se colocarmos um 10º item, ele não ficará encaixado, porque nosso Grid explícito tem três colunas e três linhas (o Grid definido é chamado de Grid explícito), que comporta 9 itens, e o J não seguirá a mesma configuração e ficará espremido. Poderíamos colocar mais um 100px, mas caso o J saia, ficará um espaço de 100px vazio. Ao colocar grid-auto-rows: 100px, podemos ter um Grid de 9 colunas sem problemas ao adicionar mais itens que isso implicitamente (os itens fora do Grid são do Grid implícito), deixando o CSS do container assim:


div.container {
    border: 3px solid blue;
    display: grid;
    grid-template-columns: auto auto auto;
    grid-template-rows: 100px 100px 100px;
    grid-auto-rows: 100px;
}

Da mesma forma, usamos o grid-auto-columns para as colunas, mas esse costuma ser menos usado.

Deixe as divs de A a I, e deixe o CSS do container assim:


div.container {
    border: 3px solid blue;
    display: grid;
    grid-template-columns: auto auto auto;
    grid-template-rows: 100px 100px 100px;
    align-items: stretch;
    justify-items: center;
    align-content: start;
    justify-content: end;
}

O align-items e o justify-items podemos simplificar com o place-items, que configura ambos numa propriedade só. O mesmo vale pro place-content, que simplifica o align-content e justify-content. A configuração de ambos os place configura primeiro o align (vertical) e depois o justify (horizontal). Veja como fica o CSS acima simplificado:


div.container {
    border: 3px solid blue;
    display: grid;
    grid-template-columns: auto auto auto;
    grid-template-rows: 100px 100px 100px;
    place-items: stretch center;
    place-content: start end;
}

Da mesma forma, podemos simplificar o grid-template-rows e o grid-template-columns por simplesmente grid-template que configura os dois juntos, primeiro a linha e depois a coluna. O CSS ficaria assim:


div.container {
    border: 3px solid blue;
    display: grid;
    grid-template: 100px 100px 100px / auto auto auto; /* a barra divide a linha da coluna */
    place-items: stretch center;
    place-content: start end;
}

Podemos ainda simplificar mais coisas, vamos voltar com os itens de A a G, com esse CSS:


div.container {
    border: 3px solid blue;
    display: grid;
    grid-template-columns: auto auto auto;
    grid-template-rows: 100px 100px 100px;
}

Podemos usar a função repeat() para repetir valores iguais numa propriedade, dessa forma:


div.container {
    border: 3px solid blue;
    display: grid;
    grid-template-columns: repeat(3, auto);
    grid-template-rows: repeat(3, 100px);
}

Simplificando:


div.container {
    border: 3px solid blue;
    display: grid;
    grid-template: repeat(3, 100px) / repeat(3, auto);
}

Temos também a fr (fraction, ou fração). Para usar as frações, vamos supor um container bem grande, que tenha 1500px de largura, com a propriedade grid-template-columns: auto auto auto para ele criar três itens em três colunas cada um com a mesma largura (que no caso, é 500px pra cada). Podemos substituir por grid-template-columns: 1fr 1fr 1fr pra dividir de forma melhor do que o auto, independente do tamanho da tela, onde cada 1fr é um item. Podemos configurar valores diferentes pra cada célula com as frações, como o valor 1fr 2fr 1fr, onde a coluna do meio é o dobro das outras, onde dividimos em três partes, mas quatro frações (de 375px cada, a do meio tem duas partes de 375px, que é 750px).

Vamos supor uma declaração doida no mesmo container, como grid-template-columns: 100px 20% 1fr 1fr, onde o primeiro elemento tem 100px, o segundo tem 20% do tamanho do container (300px), e as duas últimas frações só serão feitas com o que sobrou, que é 1100px, e cada fração ficará com 550px. Isso é menos usado e não é recomendado usar, mas pode ser encontrado em alguns sites. A mesma declaração também pode ter o repeat (no caso ficaria 100px 20% repeat(2, 1fr)).

Parte 2 da Matéria