Olá Web Developers!
Há um bom tempo que os navegadores já suportam bem o CSS Grid. Porém, ainda há pessoas com algumas dúvidas sobre o seu funcionamento. Por isso desenvolvi um guia interativo para te ajudar a entender como ele funciona.
Já fizemos aqui um guia completo sobre FlexBox. Para conferir:
Guia Interativo FlexBox - Parte 1 (Containers) Guia Interativo FlexBox - Parte 2 (Itens)
Caso você esteja em dúvida sobre usar Flexbox ou CSS Grid, também já fizemos um post sobre isso: Flexbox ou CSS Grid?
Curso Material UI - Trabalhando com temas
Conhecer o cursoO Que É CSS Grid?
O CSS Grid é um sistema de estruturação de layout que o CSS nos fornece. Diferente do Flexbox, que apenas nos permite trabalhar em uma única dimensão, o CSS Grid nos permite configurar layouts em duas dimensões (linhas e colunas). A junção de linhas e colunas formam uma grade, o que dá o nome a esse sistema (Grid).
O CSS Grid é bem poderoso e completo, permitindo que certas coisas sejam feitas de mais de uma maneira, o que pode confundir muitos iniciantes. Portanto, aqui irei mostrar as principais partes da forma mais simples para que você já termine de ler este post sabendo trabalhar com o CSS Grid.
Primeiro de tudo temos que saber que teremos propriedades CSS para trabalhar com o elemento que possui nossos itens (grid container ou elemento pai) e propriedades para os nossos itens da grid (elementos filhos).
Grid Container
Neste primeiro post veremos as propriedades que ficam no elemento pai dos nossos itens, o grid container. Teremos basicamente um container com alguns itens dentro. Dependendo do exemplo a quantidade de itens poderá ser alterada.
<div class="container" >
<div class="item" ></div>
<div class="item" ></div>
<div class="item" ></div>
<div class="item" ></div>
<div class="item" ></div>
<div class="item" ></div>
</div>
Display
Primeiro precisamos definir que o nosso container é do tipo “grid”; Fazemos isso com a propriedade “display”.
.container{
display: grid;
}
Isso irá criar uma grid do tipo block
, significando que o .container
irá ocupar a linha inteira.
Caso você queira containers inline
, utilize display: inline-grid
;
grid-template-columns e grid-template-rows
Como estamos trabalhando com uma grade, precisamos indicar quantas linhas e quantas colunas nossa grade terá.
Para colunas usamos o grid-template-columns
e para linhas usamos o grid-template-rows
.
Se queremos 3 colunas, não indicamos com o número três. O que fazemos na verdade é indicar qual o tamanho de cada coluna que queremos. A medida pode ser em qualquer unidade (px, em, %, cm, etc). Cada valor deve ser separado por um espaço.
Exatamente da mesma maneira nós declaramos as linhas utilizando a propriedade grid-template-rows
.
Até agora só declaramos o tamanho das nossas colunas e linhas. Você deve ter notado que nossos itens vão se organizando na grid de acordo com a ordem em que estão no HTML.
Porém, o CSS Grid nos permite ir além disso: podemos dar nomes para cada área da nossa grade e depois indicar onde cada elemento deve ir. Dessa maneira fica bem simples de entender a estrutura da nossa grid. Fazemos isso com a propriedade grid-template-areas
.
Vamos alterar um pouquinho o nosso HTML. Iremos colocar as classes header
, sidenav
, content
e footer
nos itens da grid para podermos indicar a posição de cada um deles depois.
<div class="container" >
<div class="item header" ></div>
<div class="item sidenav" ></div>
<div class="item content" ></div>
<div class="item footer" ></div>
</div>
Para cada item, vamos declarar a propriedade grid-area
, que serve para indicar o nome da área em que cada elemento deverá ocupar na grid. Para facilitar eu dei o mesmo nome das classes, mas você pode dar o nome que quiser.
.header{
grid-area: header;
}
.sidenav{
grid-area: sidenav;
}
.content{
grid-area: content;
}
.footer{
grid-area: footer;
}
Agora vamos ao que interessa: indicar o nome das áreas da nossa grid.
Para dar nomes às áreas de uma mesma linha, escrevemos dentro de aspas ""
. Ao abrir novas aspas estaremos indicando que estamos indo para a linha seguinte.
No exemplo abaixo nós escrevemos o nome das áreas em uma única linha. Mas para ficar mais simples de entender nós poderíamos ter escrito em linhas separadas. Fica visualmente mais legível:
.container{
grid-template-areas: "header header"
"sidenav content"
"footer footer";
}
Repetimos header
e footer
duas vezes porque declaramos duas colunas e queremos que eles ocupem as duas.
Experimente mudar os nomes das áreas de lugar e veja que nossos elementos irão mudar de posição também. Algumas sugestões:
- “sidenav header” “sidenav content” “sidenav footer”
- “header header” “content sidenav” “footer footer”
- “header header” “content sidenav” “footer sidenav”
Se quiser criar uma área sem nome, coloque .
. Experimente: “header header” “content sidenav” “. footer”
grid-column-gap, grid-row-gap e grid-gap
Nossos itens estão todos colados. Podemos indicar qual o espaço entre linhas e colunas.
Para isso usamos as propriedades grid-column-gap
e grid-column-row
.
O grid-gap
é um atalho para declarar as duas propriedades em um só lugar.
Se você passar um único valor, os dois serão aplicados para o espaço para linhas e colunas. Se passar dois valores, o primeiro será para linhas e o segundo para colunas.
.container{
grid-gap: 20px;
grid-gap: 20px 50px;
}
- O prefixo
grid-
destas propriedades está sendo removido e já é suportado nos navegadores modernos. Portanto, também pode-se utilizar as propriedadescolumn-gap
,row-gap
egap
.
Curso TypeScript - Avançado
Conhecer o cursojustify-items
Alinha todos os itens da grid horizontalmente dentro de sua própria célula (área).
- stretch (padrão): estica os itens horizontalmente para eles preencherem sua célula
- start: alinha os itens no início de suas células
- end: alinha os itens no final de suas células
- center: alinha os itens no centro de suas células
align-items
Alinha todos os itens da grid verticalmente dentro de sua própria célula (área).
- stretch (padrão): estica os itens verticalmente para eles preencherem sua célula
- start: alinha os itens na parte de cima de suas células
- end: alinha os itens na parte de baixo de suas células
- center: alinha os itens no centro de suas células
place-items
Atalho para align-items
e justify-items
em uma única declaração.
justify-content
O justify-item
alinha cada item dentro de sua própria área. Já o justify-content
alinha horizontalmente as áreas em relação ao container.
- stretch: redimensiona os itens da grid para preencherem a largura do container. Apenas funciona se você não tiver declarado uma largura para as colunas.
- start: alinha as áreas no início da grid
- end: alinha as áreas no final da grid
- center: alinha as áreas no centro da grid
- space-around: distribui as áreas com o espaço a sua volta
- space-between: distribui as áreas com o espaço entre elas
- space-evenly: distribui o espaço igualmente entre as áreas
align-content
O align-item
alinha cada cada item dentro de sua própria área. Já o align-content
alinha verticalmente as áreas em relação ao container.
- stretch: redimensiona os itens da grid para preencherem a altura do container. Apenas funciona se você não tiver declarado uma altura para as linhas.
- start: alinha as áreas no topo da grid
- end: alinha as áreas na base da grid
- center: alinha as áreas no centro da grid
- space-around: distribui as áreas com o espaço a sua volta
- space-between: distribui as áreas com o espaço entre elas
- space-evenly: distribui o espaço igualmente entre as áreas
place-content
Atalho para align-content
e justify-content
em uma única declaração.
grid-auto-columns e grid-auto-rows
Pode ser que você precise criar novas linhas ou colunas, as quais ainda não estão declaradas. Ao serem criadas, qual o tamanho delas? Estas propriedades nos permitem indicar qual será o tamanho de novas linhas e colunas criadas.
Um exemplo bem simples é caso você não tenha declarado o tamanho das linhas ou colunas. Ao adicionar novos elementos, eles ficarão com o tamanho indicado nestas propriedades.
Nós aprendemos a posicionar os itens da grid passando o nome das áreas. Porém, há outra maneira (um pouco mais complicada) de se fazer isso. Após indicar o tamanho das áreas e colunas, podemos indicar em que linha/coluna o item começa e em que linha/coluna ele termina. Ficaria assim:
.item{
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 2;
grid-row-end: 3
}
/*ou com os atalhos:*/
.item{
grid-column: 1 / 2;
grid-row: 2 / 3;
}
/*ou com esse atalho*/
.item{
grid-area: 1 / 2 / 2 / 3;
}
Se você declarar, por exemplo, para um item se posicionar em uma linha ou coluna que não foi declarada, ele ficará com as dimensões declaradas em grid-auto-columns
e grid-auto-rows
também.
grid-auto-flow
Se você possui itens que não possuem uma área declarada para ficar, esta propriedade indica se estes itens devem ir para uma nova linha ou coluna.
grid
Atalho para definir em uma única declaração as seguintes propriedades: grid-template-rows
, grid-template-columns
, grid-template-areas
, grid-auto-rows
, grid-auto-columns
e grid-auto-flow
Funções e Valores Especiais
O CSS Grid também veio com palavras-chave que guardam valores especiais e também novas funções para dar ainda mais poder à criação de nossos layouts.
Valores Especiais
Ao declarar as dimensões das linhas e colunas, podemos indicar algumas palavras especiais ao invés de valores numéricos:
- min-content: o elemento ficará com o tamanho mínimo de seu conteúdo
- max-content: o elemento ficará com o tamanho máximo de seu conteúdo
- auto: utiliza o espaço disponível
No exemplo a seguir, o primeiro item ficará com o tamanho mínimo de seu conteúdo, ou seja, seu texto. O segundo item ficará com o tamanho máximo necessário para caber seu conteúdo (texto). Já o terceiro elemento ficará com o espaço que sobrou.
A unidade fr
Além de indicar a dimensão de linhas e colunas com as tradicionais unidades como px
, %
e em
, agora também contamos com o fr
.
Esta unidade indica fração.
No código abaixo cada uma das colunas ficará com 1/3 do espaço disponível (1fr + 1fr + 1fr = 3).
.container{
/***********/
grid-template-columns: 1fr 1fr 1fr;
/***********/
}
No código abaixo a primeira coluna ficará com 50px, a segunda com 2/5 do espaço disponível e a terceira, com 3/5 (2fr + 3fr = 5).
.container{
/***********/
grid-template-columns: 50px 2fr 3fr;
/***********/
}
Experimente brincar com os valores das colunas no Playground abaixo:
A função minmax()
Imagine que você tenha uma linha ou coluna que pode variar de tamanho, mas que ela não pode passar de um valor mínimo ou máximo. Esta função nos permite indicar ambas as dimensões limites.
No código abaixo a primeira e terceira coluna terão 1fr de largura. A segunda coluna terá seu tamanho alterado de acordo com a largura de seu container. O tamanho mínimo será 100px e o máximo será 50% da largura do container (isso mesmo, podemos misturar unidades diferentes!).
.container{
/***********/
grid-template-columns: 1fr minmax(100px, 50%) 1fr;
/***********/
}
Isso ajuda muito a ter mais controle do tamanho dos elementos e também nos poupa de escrever vários media queries
.
A função fit-content()
Esta função recebe um único parâmetro, o tamanho máximo que um elemento pode chegar. É como se você usasse o min-content
, mas com um controle de tamanho máximo que o elemento pode ter.
Uma diferença principal com o minmax()
é que o minmax()
sempre buscará ocupar o maior espaço possível, enquanto o fit-content()
não ocupará mais espaço do que o necessário.
A função repeat()
Quando precisarmos criar mais de uma linha ou coluna com a mesma dimensão, utilize a função repeat()
para não ter que ficar escrevendo várias vezes. Primeiro indicamos o número de repetições e depois, o valor a ser repetido.
No código abaixo nossa primeira coluna terá 50px de largura. Depois teremos 3 colunas com 20px e uma última com 1fr.
.container{
/***********/
grid-template-columns: 50px repeat(3, 20px) 1fr;
/***********/
}
Experimente mudar a quantidade de repetições e o valor da dimensão dos itens repetidos no Playground abaixo.
auto-fill e auto-fit
Junto ao repeat()
podemos usar as palavras especiais auto-fill
e auto-fit
. Isso ajuda muito na hora de criar layouts responsivos de forma bem simples.
Nos exemplos abaixo, note que eu não indiquei quantas colunas eu quero. Na função repeat()
eu usei os valores auto-fill
e auto-fit
.
O auto-fill
tenta preencher o espaço disponível com quantos itens der, não importando se os itens estão vazios. Já o auto-fit
também tenta colocar quantas colunas der, expandindo os itens para caber no espaço disponível.
Veja que, como estamos usando a função minmax()
, também temos controle do tamanho mínimo e máximo dos itens.