Se você pensa que só o bootstrap tem esse recurso, se enganou...a CSS é a fonte dele não o bootstrap.
Outro detalhe importante é seja qual for o recurso ele tem que ser responsivo, ou seja, obedecer ao tamanho da tela de exibição do browser.
Se você é um dos brontossauros da internet como eu deve se lembrar que na pré-história remota quando a gente precisava alinhar múltiplos itens verticalmente a gente usava a tag table e ela fazia esse serviço. Uma simples página de login a gente precisava usar uma table para alinhar os itens verticalmente.
Felizmente tanto o HTML quanto a CSS agora fazem isso de uma maneira muito melhorada, menos código e mais recursos de formatação. O complicado hoje é manter esses recursos na memória...são tantos.
O Grid é um recurso de 'fatiamento' horizontal da linha corrente de renderização do browser onde podemos dividir ela em partes iguais ( para que a exibição fique homogênea ) e ainda podemos definir o espaçamento ou 'esticar' o elemento por n espaços, como mesclar 'mesclando' coluna2 como no excel. O mais loco é que ao expandirmos verticalmente o item de uma linha o item da linha seguinte pode ser impactado pelo tamanho do item da linha anterior/superior. Vamos ver esse recurso abaixo neste documento.
A gente costuma usar muito o recurso flex-grid para fazer essa tarefa de dividir a linha de exibição horizontalmente, mas o grid é mais fácil de ser usado e por esse motivo tem ganhado a preferência dos programadores. Contudo há circunstâncias, como um barra de navegação, que o flexbox leva vantagens sobe o grid.
A primeira coisa é que o grid atual numa tag container. Para dizer que nesse container usaremos o grid usamos o estilo 'display: grid;'. Note que a aplicação apenas do estilo 'display: grid;' não faz nada porque não definimos divisões ou as partes que cada elemento ocuparão. Por default os elementos ocupam todo o espaço se nada for definido.
Coloquei no estilo 'border: 1px solid black;' para que as regiões ocupadas por cada elemento fiquem bem claras.
Para definir 'quanto' que o elemento deve ocupar devemos definir as propriedades colunas (col) e linhas (row).
A propriedade coluna do grid é o estilo Grid-Template-Columns.
Importante : Grid-Template-Columns define a largura dos itens no grid.
Inicialmente no container definimos quantas colunas terão os itens contidos. Por exemplo, se no estilo colocarmos 'grid-template-columns: repeat(1fr,1fr,1fr);' a linha será divida em 3 partes horizontalmente e igualmente.
Podemos definir quantas colunas o elemento deverá ocupar. Lembre-se coluna é definida de cima para baixo. O default é uma fração da linha, ou seja 'grid-template-columns:1fr'. Agora você deve estar perguntando o que significa essa 'fração' ou 1fr. A fração é em quantas partes a linha foi dividida. Se só tem um elemento na linha esse 1fr ocupará a linha inteira. Se houver 2 elementos na linha, 1fr ocupará metade da linha e assim por diante . O espaço é dividido igualitariamente para cada elemento da linha.
No exemplo abaixo temos um grid simples com 3 elementos dividindo igualitariamente uma linha.
Código
<div style="display:grid;grid-template-columns: 1fr 1fr 1fr;">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
</div>
Como é exibido
No elemento container quando definimos '<div style="display:grid;grid-template-columns: 1fr 1fr 1fr;">' informamos que a linha deverá ser 'dividida' em 3 partes. Colocamos a seguir 3 itens e eles foram exibidos conforme demonstrado acima.
Note que o estilo display:grid não define o formato exato que deve ser dado as colunas do grid e quem faz isso são os parâmetros da tag que definem exatamente como o grid deve ser dividido.
Agora no exemplo acima uma quarta coluna... lembre-se que no container definimos 3 colunas. Como ela será exibida ?
Como é exibido
Como previsto, se o elemento não cabe na linha corrente ele é automaticamente deslocado para a linha de baixo. Este comportamento também irá acontecer caso a largura da tela do browser seja insuficiente para abrigar a largura mínima de cada elemento definido no grid. Por exemplo, defino que cada coluna tem 400 pixels de comprimento e ao exibir na tela o browser descobre que é um celular na vertical que só cabe 576 pixels de largura. Sendo assim ele colocará o primeiro elemento na linha corrente e os demais na linha seguinte.
Agora no exemplo lá de acima com 3 colunas retiramos uma coluna. Vai ficar um buraco ?
Como é exibido
Note como o tamanho das colunas fica constante sempre. Com isto vimos que uma vez definida na tag container o número de colunas a serem exibidas isto será obedecido a risca e sempre, cada coluna terá um tamanho fixo igual as demais colunas.
Como dissemos acima a propriedade coluna do grid é o estilo Grid-Template-Columns. E o estilo que define as linhas é o Grid-Template-Rows.
Importante : Grid-Template-Rows define a altura dos itens no grid. Note que se não for definido a altura da linha será exatamente a necessária para o elemento ser exibido, ou seja, terá a altura do maior elemento da linha do grid.
O estilo mais usado na formatação do grid horizontalmente (rows) é a sua altura. Vamos supor que queremos que a altura seja de 100 px. Note também que manteremos a definição de colunas para podermos comparar o que o estilo row influência na tag.
Código
<div style="display: grid; grid-template-columns: 1fr 1fr 1fr; grid-template-rows:100px">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
</div>
Como é exibido
O estilo grid-template-rows é muito importante quando colocamos imagens ou mesmo alinhar os itens ao centro do box do elemento.
Suponha agora que você tenha mais de uma linha no grid. A primeira linha tem um texto e a altura boa seria uns 50 pixels mas a segunda linha contém imagens e a altura ideal seria 150 pixels. Note que ambas as linhas terão o mesmo número de colunas (largura) mas a altura da primeira será menor que o da segunda. Vejamos como fica.
Código
<div style="display: grid; grid-template-columns: 1fr 1fr 1fr; grid-template-rows:50px 150px">
<div class="item">Linha 1-Item 1</div>
<div class="item">Linha 1-Item 2</div>
<div class="item">Linha 1-Item 3</div>
<div class="item">Linha 2-Item 1</div>
<div class="item">Linha 2-Item 2</div>
<div class="item">Linha 3-Item 3</div>
</div>
Como é exibido
O exemplo acima é muito utilizado quando desejamos 'alturas' diferentes para os elementos do mesmo grid. Note que se você colocar 2 grids juntos um com uma altura e outro com outra ficaria um espaçamento entre eles.
Temos jeitos de contornar esta questão de separação entre grids, mas não seria a maneira correta.
Nos exemplos acima como eu defini border: 1px solid black; a região ocupada por cada elemento é bem definida. Pode ser que em certas ocasiões você deseje uma 'margem' ou 'espaçamento' entre cada elemento. Se desejar use o parâmetro gap.
Código
<div style="display: grid; grid-template-columns: 1fr 1fr 1fr; grid-template-rows:50px;gap:10px;">
<div class="item">Linha 1-Item 1</div>
<div class="item">Linha 1-Item 2</div>
<div class="item">Linha 1-Item 3</div>
<div class="item">Linha 2-Item 4</div>
<div class="item">Linha 2-Item 5</div>
<div class="item">Linha 3-Item 6</div>
</div>
Como é exibido
Note que o gap é retirado do espaço da segunda linha e isso torna o gap inimigo do segundo item. Se o gap é de 10 pixels é dada uma margem de 5px em volta de todo elemento. Sendo assim vamos contornar o problema aumentando a altura da segunda linha exatamente a metade do tamanho do gap.
Código
<div style="display: grid; grid-template-columns: 1fr 1fr 1fr; grid-template-rows:50px 55px;gap:10px;">
<div class="item">Linha 1-Item 1</div>
<div class="item">Linha 1-Item 2</div>
<div class="item">Linha 1-Item 3</div>
<div class="item">Linha 2-Item 4</div>
<div class="item">Linha 2-Item 5</div>
<div class="item">Linha 3-Item 6</div>
</div>
Como é exibido
No exemplo acima as 2 linhas agora tem a mesma altura graças ao aumento dado a altura da segunda linha...a primeira tem 50 pixels e a segunda 55 pixels. Raramente a gente usa isso, mas é bem conveniente saber dessa questão.
A definição do grid até aqui não está complicada, mas você há de convir que 'style="display:grid;grid-template-columns: 1fr 1fr 1fr;"' parece meio repetitivo e não é o padrão do grid.
Sendo assim, o jeito comum de fazer isso é trocar o parâmetro 1fr pelo parâmetro repeat. O parâmetro repeat possui dois valores, o primeiro é o número de vezes e o segundo é a altura de cada coluna do grid. Vejamos como fica.
Código
<div style="display: grid; grid-template-columns: repeat(3,1fr);">
<div class="item">Linha 1-Item 1</div>
<div class="item">Linha 1-Item 2</div>
<div class="item">Linha 1-Item 3</div>
</div>
Como é exibido
Colocando o parâmetro 'grid-template-columns: repeat(3,1fr)' a exibição fica igual ao grid-template-columns: 1fr 1fr 1fr, mais sucinto quando a altura das colunas é a mesma para todos elementos do grid.
Até agora falamos do container do grid que define como seus elementos serão exibidos, mas e se quisermos que um elemento do grid seja exibido diferentemente do outro, ou seja, 'mesclado' como falamos no Excel ou que ocupe 2 ou mais colunas, 2 ou mais linhas, como isso será possível ?
Existe um parâmetro chamado 'grid-column' que permite 'mesclar' as colunas. No exemplo abaixo exibo 2 linhas..a primeira com 3 colunas como nos exemplos anteriores e a segunda 'expandindo a primeira coluna' por 2 colunas. Veja como fica.
Código
<div style="display: grid; grid-template-columns: repeat(3,1fr); grid-template-rows:50px;">
<div class="item">Linha 1-Item 1</div>
<div class="item">Linha 1-Item 2</div>
<div class="item">Linha 1-Item 3</div>
<div class="item" style="grid-column:1/3">Linha 2-Item 4</div>
<div class="item">Linha 2-Item 5</div>
<div class="item">Linha 2-Item 6</div>
</div>
Como é exibido
No exemplo acima na linha 2 definimos que o item 4 da linha 2 deveria começar na primeira coluna e terminar na terceira coluna e por esse motivo ele ocupou 2 itens do grid. O próximo item-5 coube na linha, mas o item-6 não coube na linha e por esse motivo foi exibido logo abaixo.
Como ficaria de ao invés de colocar no parâmetro style="grid-column:1/3 ( começa na coluna 1 e termina na 3) se eu colocasse na 2 e terminasse na 3 ???
Como é exibido
Doidera mas funciona. O item-4 começou na segunda coluna e foi até a terceira. O item-5 ainda coube na linha e foi exibido na linha o item-6 não coube e foi colocado na linha de baixo.
Acima vimos como o estilo style="grid-column:x/y" define a largura de um item do grid. Ainda temos o estilo style="grid-row:x/y" que pode 'mesclar' os itens do grid verticalmente definindo alturas diferenciadas para cada um deles.
Abaixo vou definir 2 linhas sendo que na primeira linha vou definir que o item1 ocupe 2 colunas e os demais nada de especial. Veja como fica.
Código
<div style="display: grid; grid-template-columns: repeat(3,1fr)">
<div class="item" style="grid-column:1/3;grid-row:1/2">Linha 1-Item 1</div>
<div class="item">Linha 1-Item 2</div>
<div class="item">Linha 2-Item 1</div>
<div class="item">Linha 2-Item 2</div>
<div class="item">Linha 2-Item 3</div>
</div>
Como é exibido
Note que para o estilo grid-row:1/2 funcionar você obrigatoriamente precisa do estilo grid-column:1/3; no mesmo item do grid.
Você pode combinar esses estilos do grid praticamente para fazer o mosaico que quiser, contudo raramente precisará fazer isso. Veja abaixo um exemplo interessante mixando todos esses 'estilos'.
Código
<style>
.item1 {
grid-column: 1/3;
grid-row: 1/2;
}
.item2 {
grid-column: 3/4;
grid-row: 1/3;
}
.item6 {
grid-column: 2/4;
}
</style>
<div class="grid-container">
<div class="item item1">Item 1</div>
<div class="item item2">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item item6">Item 6</div>
</div>
Como é exibido
Imagine imagens e vídeos em cada um desses itens do grid...ficaria muito bom né ?