Conceitos básicos de Grid Layout

Esta tradução está incompleta. Ajude atraduzir este artigo.

CSS Grid Layout prevê funcionalidades para criação de um sistema de grid bi-dimensional para layout CSS. Grids que podem usados para "layoutar" tanto as grandes regiões de uma página como os pequenos elementos de uma interface de usuários. Esse artigo é uma introdução ao CSS Grid Layout e à terminologia técnica que consta da Especificação para o CSS Grid Layout Level 1. As funcionalidades aqui mencionadas serão detalhadas e explicadas nas demais seções componentes desse Guia.

O que é grid?

Grid é uma malha formada pela interseção de um conjunto de linhas horizontais e um conjunto de linhas verticais – um dos conjuntos define colunas e outro linhas. Derntro de um  grid, respeitando-se a configuração criada pelas suas linhas, pode-se inserir elementos da marcação. As CSS grid layout preveem as seguintes funcionalidades:

Dimensões fixas ou flexíveis

Você pode criar grids com dimensões fixas – por exemplo: definindo dimensões em pixels. Ou criar grids com dimensões flexíveis definindo-as com uso de porcentagem ou da nova unidade CSS fr criada para esse propósito.

Posicionamento de itens

Você pode posicionar com precisão itens de uma página usando o número que define uma linha do grid, usando nomes ou ainda fazendo referência a uma determinada região do grid. Existe ainda um algorítmo de controle do posicionamento de itens da página que não possuem uma posição capaz de ser explícitamente definida no grid.

Criação de grids adicionais

Além da possibilidade de se criar um grid inicial para o layout a Especificação prevê também a possibilidade de se adicionar linhas e colunas para layoutar conteúdos adicionados fora do grid inicial. Funcionalidades tal como adicionar "tantas colunas quanto necessárias em um grid container existente" Fsão previstas nas Especificações.

Alinhamento

Estão previstas funcionalidades de alinhamento que possibilitam controlar o alinhamento dos itens de uma página posicionados no grid e também o alinhamento do prórpio grid como um todo.

Controle sobre conteúdos sobrepostos

Em uma célula do grid podem ser posicionados mais de um item da página e também é possível que se defina sobreposição parcial de áreas. Esse controle de layers é feito com uso de z-index.

CSS Grid Layout é uma poderosa Especificação que se for combinada com outras Especificação das CSS, tal como flexbox, possibilita a criação de layouts que até então eram impossíveis de serem criados com CSS. Tudo começa com a criação de um grid dentro de um grid container.

Grid container

Cria-se um grid container com as declarações CSS display: grid ou display: inline-grid para um elemento da marcação. Assim declarando, todos os elementos filhos diretos daquele container se transformam em grid items.

No exemplo mostrado a seguir um elemento div container ao qual foi atribuída a classe wrapper contém cinco elementos filhos.

<div class="wrapper">
   <div>One</div>
   <div>Two</div>
   <div>Three</div>
   <div>Four</div>
   <div>Five</div>
</div>

Façamos de .wrapper um grid container.

.wrapper {
  display: grid;
}

Todos os elementos filhos diretos agora são grid items. Observando a renderização em um navegador web você não notará nenhuma diferença em relação a renderização já conhecida de um elemento container com seus cinco elementos filhos, pois no exemplo foi criado um grid constítuido de uma única coluna para acomodar os elementos filhos.  At this point you may find it useful to work in Firefox Developer Edition, which has the Grid Inspector available as part of the Developer Tools. If you view this example in Firefox and inspect the grid, you will see a small icon next to the value grid. Click this and the grid on this element will be overlaid in the browser window.

Using the Grid Highlighter in DevTools to view a grid

As you learn and then work with CSS Grid Layout this tool will give you a better idea of what is happening with your grids visually.

If we want to start making this more grid-like we need to add column tracks.

Grid Tracks

We define rows and columns on our grid with the grid-template-columns and grid-template-rows properties. These define grid tracks. A grid track is the space between any two lines on the grid. In the below image you can see a track highlighter – the first row track in our grid.

I can add to our earlier example by adding the grid-template-columns property, then defining the size of the column tracks.

I have now created a grid with three 200-pixel-wide column tracks. The child items will be laid out on this grid one in each grid cell.

<div class="wrapper">
   <div>One</div>
   <div>Two</div>
   <div>Three</div>
   <div>Four</div>
   <div>Five</div>
</div>
.wrapper {
  display: grid;
  grid-template-columns: 200px 200px 200px;
}

The fr Unit

Tracks can be defined using any length unit. Grid also introduces an additional length unit to help us create flexible grid tracks. The new fr unit represents a fraction of the available space in the grid container. The next grid definition would create three equal width tracks that grow and shrink according to the available space.

<div class="wrapper">
   <div>One</div>
   <div>Two</div>
   <div>Three</div>
   <div>Four</div>
   <div>Five</div>
</div>
.wrapper {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

In this next example we create a definition with a 2fr track then two 1fr tracks. The available space is split into four. Two parts are given to the first track and one part each to the next two.

.wrapper {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
}

In this final example we mix absolute sized tracks with fraction units. The first track is 500 pixels so this fixed width is taken away from the available space. The remaining space is divided into three and assigned in proportion to the two flexible tracks.

.wrapper {
  display: grid;
  grid-template-columns: 500px 1fr 2fr;
}

Track listings with repeat() notation

Large grids with many tracks can use repeat() notation to repeat all or a section of the track listing. For example the grid definition:

.wrapper {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

Can also be written as:

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

Repeat notation can be used for a part of the track listing. In this next example I have created a grid with an initial 20-pixel track, then a repeating section of 6 1fr tracks then a final 20-pixel track.

.wrapper {
  display: grid;
  grid-template-columns: 20px repeat(6, 1fr) 20px;
}

Repeat notation takes a track listing, therefore you can use it to create a repeating pattern of tracks. In this next example my grid will consist of 10 tracks, a 1fr track followed by a 2fr track, repeated five times.

.wrapper {
  display: grid;
  grid-template-columns: repeat(5, 1fr 2fr);
}

The implicit and explicit grid

When creating our example grid we defined our column tracks with the grid-template-columns property, but let grid create rows as needed for the content. These rows are created in the implicit grid. The explicit grid consists of the rows and columns you define with grid-template-columns and grid-template-rows. If you place something outside of that defined grid, or due to the amount of content more grid tracks are needed, then grid creates rows and columns in the implicit grid. These tracks will be auto sized by default, so will size based on the content inside them.

You can also define a set size for tracks created in the implicit grid with the grid-auto-rows and grid-auto-columns properties.

In the below example we use grid-auto-rows to ensure that tracks created in the implicit grid are 200 pixels tall.

<div class="wrapper">
   <div>One</div>
   <div>Two</div>
   <div>Three</div>
   <div>Four</div>
   <div>Five</div>
</div>
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 200px;
}

Track sizing and minmax()

When setting up an explicit grid or defining the sizing for automatically created rows or columns we may want to give tracks a minimum size, but ensure they expand to fit any content that is added. For example I may want my rows to never collapse smaller than 100 pixels, but if my content stretches to 300 pixels in height I would like the row to stretch to that height.

Grid has a solution for this with the minmax() function. In this next example I am using minmax() in the value of grid-auto-rows. Automatically created rows will be a minimum of 100 pixels tall, and a maximum of auto. Using auto means that the size will look at the content size and so stretch to give space for the tallest thing in a cell in this row.

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: minmax(100px, auto);
}
<div class="wrapper">
   <div>One</div>
   <div>Two
   <p>I have some more content in.</p>

<p>This makes me taller than 100 pixels.</p>
</div>
   <div>Three</div>
   <div>Four</div>
   <div>Five</div>
</div>

Grid Lines

It should be noted that when we define a grid we define the grid tracks, not the lines. Grid then gives us numbered lines to use when positioning items. In our three column, two row grid we have four column lines.

Diagram showing numbered grid lines.

Lines are numbered according to the writing mode of the document. In a left to right language line 1 is on the left hand side of the grid. In a right to left language it is on the right hand side of the grid. Lines can also be named, and we will look at how to do this in a later guide in this series.

Positioning items against lines

We will be exploring line based placement in full detail in a later article, the following example demonstrates doing this in a simple way. When placing an item we target the line – rather than the track.

In the following example I am placing the first two items on our three column track grid, using the grid-column-start, grid-column-end, grid-row-start and grid-row-end properties. Working from left to right, the first item is placed against column line 1, and spans to column line 4, which in our case is the far right line on the grid. It begins at row line 1 and ends at row line 3, therefore spanning two row tracks.

The second item starts on grid column line 1, and spans one track. This is the default so I do not need to specify the end line. It also spans two row tracks from row line 3 to row line 5. The other items will place themselves into empty spaces on the grid.

<div class="wrapper">
   <div class="box1">One</div>
   <div class="box2">Two</div>
   <div class="box3">Three</div>
   <div class="box4">Four</div>
   <div class="box5">Five</div>
</div>
.wrapper { 
    display: grid; 
    grid-template-columns: repeat(3, 1fr); 
    grid-auto-rows: 100px; 
} 
.box1 { 
    grid-column-start: 1; 
    grid-column-end: 4; 
    grid-row-start: 1; 
    grid-row-end: 3; 
} 
.box2 { 
    grid-column-start: 1; 
    grid-row-start: 3; 
    grid-row-end: 5; 
}

Don't forget that you can use the Grid Inspector in Firefox Developer Tools to see how the items are positioned against the lines of the grid.

Grid Cells

A grid cell is the smallest unit on a grid, conceptually it is like a table cell. As we saw in our earlier examples, once a grid is defined on a parent the child items will lay themselves out once in each cell of the defined grid. In the below image I have highlighted the first cell of the grid.

The first cell of the grid highlighted

Grid areas

Items can span one or more cells both by row or by column, and this creates a grid area. Grid areas have to be rectangular – it isn’t possible to create an L-shaped area for example. The highlighted grid area spans two row and two column tracks.

A grid area

Gutters

Gutters or alleys between grid cells can be created using the grid-column-gap and grid-row-gap properties, or the shorthand grid-gap. In the below example I am creating a 10-pixel gap between columns and a 1em gap between rows.

.wrapper {
   display: grid;
   grid-template-columns: repeat(3, 1fr);
   grid-column-gap: 10px;
   grid-row-gap: 1em;
}
<div class="wrapper">
   <div>One</div>
   <div>Two</div>
   <div>Three</div>
   <div>Four</div>
   <div>Five</div>
</div>

Any space used by gaps will be accounted for before space is assigned to flexible length fr tracks, and gaps act for sizing purposes like a regular grid track, however you cannot place anything into a gap. In terms of line-based positioning, the gap acts like a fat line.

Nesting grids

A grid item can become a grid container. In the following example I have the three-column grid created earlier, with our two positioned items. In this case the first item has some sub-items. As these items are not direct children of the grid they do not participate in grid layout and so display in normal document flow.

<div class="wrapper">
   <div class="box box1">
       <div class="nested">a</div>
       <div class="nested">b</div>
        <div class="nested">c</div>
    </div>
    <div class="box box2">Two</div>
    <div class="box box3">Three</div>
    <div class="box box4">Four</div>
    <div class="box box5">Five</div>
</div>

Nested grid in flow

If I set box1 to display: grid I can give it a track definition and it too will become a grid, the items then lay out on this new grid.

.box1 {
   grid-column-start: 1;
   grid-column-end: 4;
   grid-row-start: 1;
   grid-row-end: 3;
   display: grid;
   grid-template-columns: repeat(3, 1fr);
}

In this case the nested grid has no relationship to the parent. As you can see in the example it has not inherited the grid-gap of the parent and the lines in the nested grid do not align to the lines in the parent grid.

Subgrid

In the level 1 grid specification there is a feature called subgrid which would let us create nested grids that use the track definition of the parent grid.

Subgrids are not yet implemented in any browsers, and the specification is subject to change.

In the current specification, we would edit the above nested grid example to use display: subgrid rather than display: grid, then remove the track definition. The nested grid will use the parent grid tracks to lay out items.

It should be noted that the nested grid is in both dimensions—rows and columns. There is no concept of the implicit grid working with subgrids. This means you need to ensure that the parent grid has enough row and column tracks for all the subitems.

.box1 {
   grid-column-start: 1;
   grid-column-end: 4;
   grid-row-start: 1;
   grid-row-end: 3;
   display: subgrid;
}

Layering items with z-index

Grid items can occupy the same cell. If we return to our example with items positioned by line number, we can change this to make two items overlap.

<div class="wrapper">
   <div class="box box1">One</div>
   <div class="box box2">Two</div>
   <div class="box box3">Three</div>
   <div class="box box4">Four</div>
   <div class="box box5">Five</div>
</div>
.wrapper {
   display: grid;
   grid-template-columns: repeat(3, 1fr);
   grid-auto-rows: 100px;
}
.box1 {
   grid-column-start: 1;
   grid-column-end: 4;
   grid-row-start: 1;
   grid-row-end: 3;
}
.box2 {
   grid-column-start: 1;
   grid-row-start: 2;
   grid-row-end: 4;
}

The item box2 is now overlapping box1, it displays on top as it comes later in the source order.

Controlling the order

We can control the order in which items stack up by using the z-index property - just as with positioned items. If we give box2 a lower z-index than box1 it will display below box1 in the stack.

.wrapper {
   display: grid;
   grid-template-columns: repeat(3, 1fr);
   grid-auto-rows: 100px;
}
.box1 {
   grid-column-start: 1;
   grid-column-end: 4;
   grid-row-start: 1;
   grid-row-end: 3;
   z-index: 2;
}
.box2 {
   grid-column-start: 1;
   grid-row-start: 2;
   grid-row-end: 4;
   z-index: 1;
}

Next Steps

In this article we have had a very quick look through the Grid Layout Specification. Have a play with the code examples, and then move onto the next part of this guide where we will really start to dig into the detail of CSS Grid Layout.

Etiquetas do documento e colaboradores

Etiquetas: 
 Colaboradores desta página: guigrecco, Maujor
 Última atualização por: guigrecco,