Introduction to Grid Layout

The traditional solution to layout, based on the box model, relies on the display property + position property + float property. It is very inconvenient for those special layouts, for example, vertical centering is not easy to implement. In 2009, the W3C proposed a new scheme, Flex Layout, which can implement various page layouts in a simple, complete and responsive manner. See my last blog about Flex layout: https://sunra.top/posts/40806/

In this blog we continue to introduce the next new layout: grid layout

As mentioned earlier, flex layout is a one-dimensional layout, while grid layout introduces a two-dimensional grid layout system that can be used to layout the main area layout or small components of the page.

What is Grid?

A grid is a set of intersecting horizontal and vertical lines that define the columns and rows of the grid. We can place grid elements in positions related to those rows and columns.

CSS grid layout has the following characteristics:

  1. Fixed position and elastic orbit size

Mesh can be created with a fixed track size, such as pixel units. It is also possible to create a grid of elastic size using percentages or a new unit’fr 'created specifically for this purpose.

  1. Element Position

Elements can be pinpointed using line numbers, line names, or a grid area. The grid also uses an algorithm to control elements that are not given a clear grid position.

  1. Create extra tracks to include elements

Grid layout can be used to define an explicit grid, but according to the specification it will handle what you add outside the grid, it will automatically add rows and columns when necessary, and it will accommodate as many columns as possible.

  1. Alignment controls

The mesh contains alignment features so that we can control the alignment of objects once placed in the mesh area, and how the entire mesh is aligned.

  1. Control overlapping content

Multiple elements can be placed into grid cells, or the lack of rain can partially overlap each other. The z-index property can then be used to control the priority of the overlapping area display

Grid container

We create a grid container by declaring’display: grid ‘or’display: inline-grid’ on the element. Once we do this, all immediate child elements of this element will become grid elements.

In this example, there is a div element called wrapper as a container, which has five child elements inside.

1
2
3
4
5
6
7
<div class="wrapper">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>

We use ‘.wrapper’ as a mesh container

1
2
3
.wrapper {
display: grid;
}

All immediate child elements are now grid items. In the browser, the conversion of elements to a grid makes no difference, because the grid creates a single-column grid for these elements.

Grid track

We define the rows and columns in the grid using the grid-template-columns and grid-template-rows properties. These properties define the tracks of the grid. A grid track is the space between any two lines in the grid.

I can add column tracks to the previous example by adding the grid-template-columns property, and then define the size of the column tracks.

I now create a grid with three 200 px wide column tracks. The child elements will unfold in each grid cell on the grid.

1
2
3
4
.wrapper {
display: grid;
grid-template-columns: 200px 200px 200px;
}

Fr unit

Tracks can be defined in any length unit. Grid also introduces an additional length unit to help us create flexible grid tracks. The new fr unit represents an equal share of the available space in the grid container. The next grid definition will create three tracks of equal width that will grow and contract with the available space.

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

In the example below, we have created and defined one 2fr orbit and two 1fr orbits. The available space is divided into four equal parts. Two of them are given to the first orbit, and the remaining two orbits each occupy one.

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

In the last example, we mix absolute-size tracks with fractional-unit tracks. The first track is 500 pixels, and this fixed width is taken from the available space. The remaining space is divided into three parts, proportionally divided between two elastic-size tracks.

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

Use repeat () in the track list

Large meshes with multiple tracks can use the repeat () tag to repeat part or the entire track list. As defined in the grid below:

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

Can also be written as:

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

The Repeat statement can be used to repeat parts of a track list. In the example below I create a grid that starts with a track of 20 pixels, then repeats 6 1fr tracks, and finally adds a track of 20 pixels.

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

The Repeat statement can be passed in a track list, so you can use it to create a repeating track list for the multi-track pattern. In the next example, the grid will have a total of 10 tracks, for 1 1fr track followed by 1 2fr track, and the pattern repeats 5 times.

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

Implicit and Explicit Networking

When we created the grid example above, we defined our own column tracks with the grid-template-columns property, but let the grid create rows of the desired content, which will be created in the implicit grid. ** The explicit grid contains the rows and columns you defined in the grid-template-columns and grid-template-rows properties. If you put something outside of the grid definition, or require more grid tracks due to the amount of content, the grid will create rows and columns in the implicit grid **. By default, these tracks will be automatically sized, so they will change size based on their contents.

That is to say, the rows and columns defined by attributes are displayed, and the automatically generated cells are implicit.

You can also use the grid-auto-rows and grid-auto-columns properties in an implicit grid to define a track with a set size.

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

1
2
3
4
5
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 200px;
}

Orbit size and minmax ()

When setting up an explicit grid or defining the size of automatically created rows and columns, we may want to give the grid a minimum size to ensure that they can expand to accommodate the content added inside it. For example, I want my rows to never shrink below 100 pixels in height, but if my content extends to 300 pixels high I want my line-height to extend to that height too.

The grid uses the minmax () function to solve this problem. In the next example I use minmax () as the value of grid-auto-rows. The automatically created line-height will be a minimum of 100 pixels and a maximum of auto. Using auto means that the size of the row will automatically change according to the size of the content: expand the space to accommodate the tallest cell in the row.

1
2
3
4
5
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: minmax(100px, auto);
}
1
2
3
4
5
6
7
8
9
10
<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 are defining grid tracks, not grid lines. Grid will create numbered grid lines for us to locate each grid element. For example, the following three-column, two-row grid has four vertical grid lines.

The order in which the gridlines are numbered depends on the writing pattern of the article. In left-to-right languages, the gridline numbered 1 is on the far left. In right-to-left languages, the gridline numbered 1 is on the far right

Placing mesh elements across tracks

I used grid-column-start (en-US), grid-column-end (en-US), grid-row-start (en-US) and grid-row-end (en-US) properties to put the first two elements into our three-column grid. From left to right, the first element starts at column line 1 and extends to column line 4, which is the rightmost column line in our example. And extends from row line 1 to row line 3, occupying two row tracks.

The second element starts from column line 1 and extends a track. Since this is the default behavior, I don’t have to specify an end line. And it spans two row tracks from row line 3 to row line 5. The remaining elements are automatically placed in the remaining space of the grid.

1
2
3
4
5
6
7
<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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.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;
}

Grid cell

A grid cell is the smallest unit in a grid element, which is conceptually similar to a cell in a table. Now looking back at our previous example, once a grid element is defined in a parent element, its child elements will be arranged in each predefined grid cell.

Grid area

Grid elements can expand one or more cells in a row or column direction, and create a grid area. The shape of the grid area should be a rectangle - that is, you cannot create a grid area similar to an “L” shape.

Grid spacing

Grid horizontal spacing, or grid vertical spacing, between two grid cells can be created using the grid-column-gap (en-US) and grid-row-gap (en-US) properties, or directly using the two merged abbreviations grid-gap (en-US). In the example below, I will create a grid element with a horizontal spacing of 10px and a vertical spacing of 1em.

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

The space used by the spacing will be set aside before the space calculation of the track using the elastic length fr. The size definition behavior of the spacing is the same as that of a normal track, but the difference is that you cannot insert anything into it. From the perspective of positioning as a base line, the spacing is like a wide base line.

Nested grid

A grid element can also become a grid container. In the following example I have a 3-column grid element beforehand and have two cross-track meshes. In this example, the first grid element contains several child elements. ** When these elements are not direct child elements of the grid container, they do not participate in the grid layout and appear as normal doc flow. **

1
2
3
4
5
6
7
8
9
10
11
<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>

1
2
3
4
5
6
7
8
.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 example, the nested grid is not related to its parent. As you can see in the example, it does not inherit the grid-gap (en-US) property from its parent, and the gridlines in the nested grid are not aligned with the parent’s gridlines.

Subgrid

In the Level 1 grid specification, there is a feature called subgrid, which allows us to define a nested grid in the track definition of the parent grid element.

In the current specification, we can modify the nested grid example above to use display: subgrid instead of display: grid, and then remove the track definition. A nested grid will use the track definition in the parent grid element to arrange its grid elements.

It should be pointed out that ** nested grids have two units at the same time - rows and columns. There is no concept of implicit subgrids, which means that you need to ensure that the parent grid element contains enough row and column tracks to accommodate all subgrid elements.

Control hierarchy with z-index

Multiple grid items can occupy the same grid unit. If we go back to placing grid items based on grid line numbers, we can change this to overlap the two grid items.

1
2
3
4
5
6
7
<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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.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;
}

Overall layout and a bit of comparison with the game

We have introduced four types of webpage layout methods:

  • Traditional layout flow with display + position + float
  • table layout
  • flex layout
  • table layout

To sum up, the so-called web page is actually an upgraded version of the paper version of the newspaper. HTML is the content of the newspaper, CSS is the layout of the newspaper, and JS adds some interaction to the newspaper.

So in essence, I think that the browser is also a rendering engine, and the most essential meaning of the game engine is the same, but the browser is a web rendering engine, rendering the HTML hyperlinke doc, is an upgraded version of the newspaper, and The game engine can render and simulate a 3D world.