Introduction to CSS Grid Layout Basics – part I

Matching the grid design layout on the web has always been a challenge. If you’ve been around the web long enough, you probably used, or at least heard about most of these – table based layouts, float based layouts, and finally, flexbox based layouts. Although all of these worked (and still do), none of them were meant to be used for page layout.

Enter the CSS Grid Layout.

What is it?

CSS Grid Layout or simply ‘Grid’ is W3C’s solution for the layout problem we’ve all been tackling since the birth of the web. It’s the latest CSS module that provides us with a two-dimensional grid-based layout system. Basically, it enables us to align elements into columns and rows. But not just that! With it’s more advanced features, creating complex page layouts is a breeze.

Is it well supported?

According to, CSS Grid’s global browser support is around the 71% mark. Thats’s pretty good, but not good enough to use in most production environments just yet. However, you can always check the browser statistics for the website you’re working on and decide whether or not the Grid layout is worth implementing.

Here is a ‘per browser’ support screenshot:

CSS Grid browser support according to
CSS Grid browser support according to

For more details click on the image or the link above.

Any new terms I should be aware of?

There are a few new terms and concepts associated with the Grid spec that you need to get comfortable with so you can learn to use the grid properly and unlock it’s full potential.

Grid container & grid items

Grid container is the container element on which display: grid is applied. The children that are direct descendants of the grid container are grid items.

Grid lines

Grid lines are the horizontal (row) and vertical (column) lines that form the grid structure. They are used to position grid items inside the grid. Each one has a numerical index associated with it, starting with 1 from the start of the grid, or -1 starting from the end of the grid.
In the example below, there are 4 column grid lines and 4 row grid lines that form the grid. Column line 3 (from the start)/-2 (from the end) is highlighted.

Grid lines
Grid lines

Grid cells, tracks, areas

A grid cell is the space between 2 adjacent row grid lines and 2 adjacent column grid lines. It’s a “basic grid unit”, conceptually similar to a table cell. In the example below, the grid cell is the highlighted part between the 2nd and 3rd row grid lines, and 3rd and 4th column grid lines.

A grid track is the space between 2 adjacent grid lines. Essentially, you can think of the grid tracks as the rows and columns of your grid. In the example below, the grid track is the highlighted part between the 1st and 2nd row grid lines.

A grid area is the space surrounded by four grid lines, made up of multiple grid cells. In the example below, the grid area is the highlighted part that takes up 4 grid cells, and is surrounded by the 2nd and 4th row grid lines, and 1st and 3rd column grid lines.

Grid cell, track, area

How does it work?

Grid container

Grid container can be created by setting the display property with a value of grid or inline-grid. All direct children of the newly created grid container become grid items.
When display: grid is used, grid items are placed in rows by default and span the full width of the grid container. On the other hand, display: inline-grid will make the grid as wide as the widest grid item (similar behaviour as display: inline-block).

Rows and Columns

grid-template-rows: 70px 100px

A row track is created for each value specified for grid-template-rows. Track size value can be a length, a percentage, a fraction of the free space in the grid (using the fr unit), or a keyword auto, which will fill up the remaining space available.

In the example below, items 1 and 2 have fixed heights of 75px and 100px. Because only 2 row tracks were defined, heights of items 3 and 4 are defined by their contents.

grid-template-columns: 150px 75px 200px

A column track is created for each value specified for grid-template-columns. Like rows, track size value can be a length, a percentage, a fraction of the free space in the grid, or a keyword auto.

In the example below, grid items 1, 2 and 3 have fixed widths of 150px, 75px and 200px. If you add 3 more grid items (items 4,5,6), they will be placed on a new row track because only 3 column track sizes are defined; and their column sizes will be equal to items 1, 2 and 3.

grid-template-rows: minmax(100px, auto);
grid-template-columns: minmax(100px, auto)

For both grid-template-rows and grid-template-columns, the minmax() function can be used to define the minimum and maximum track size. It accepts 2 arguments: the first is the minimum size of the track and the second is the maximum size. Besides length values, the function also accepts the keyword auto, which allows the track to grow/stretch based on the size of the content.

grid-template-rows: repeat(3, 150px);
grid-template-columns: repeat(4, 1fr)

repeat() function can be used to create a grid with multiple items that have the same size. It accepts 2 arguments: the first one represents the number of times the defined track should repeat, and the second is the track definition.

repeat() can also be used within track listings. For example grid-template-columns: 50px repeat(3, 100px) 50px. This will create 5 column tracks. First and last column tracks will be 50px wide. The 3 tracks in between will be 100px wide each.

Grid gaps (gutters)

Grid gaps between rows and columns are created by using grid-column-gap and grid-row-gap properties, or the shorthand grid-gap property that combines both.

grid-row-gap: 30px;
grid-column-gap: 15px

is the same as

grid-gap: 20px 15px;

Assigning names to grid lines

By default, grid lines have a numerical indexes associated with them. They can also be assigned a name when defining the grid with the grid-template-rows and grid-template-columns properties. Those names can be used instead of the numerical indexes to position grid items inside the grid.

grid-template-rows: [row1] 1fr [row2] 1fr [row3];
grid-template-columns: [col1] 1fr [col2] 1fr [col3]

Grid lines can have multiple names assigned to them: grid-template-rows: [row1-start row-first] 1fr [row1-end row2-start] 1fr [row2-end row-last].

Lines can also be assigned the same name with the repeat() function. Lines with the same name are also assigned a occurrence number for easier identification.

grid-template-rows: repeat(2, [row-start] 1fr [row-end])
grid-template-cols: repeat(2, [col-start] 1fr [col-end])

Assigning names to grid areas

Just like grid lines, grid areas can also be named with grid-template-areas property. These names can be used to position grid items inside a grid.

grid-template-rows: 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr 1fr;
grid-template-areas: "header header header"
"content content sidebar"
"footer footer footer"

Positioning grid items

Grid items are positioned by grid lines or grid areas.

Item positioning by grid lines

Grid lines can be referenced by their numerical index or name.

grid-row-start: 2;
grid-row-end: 3;
grid-column-start: 2;
grid-column-end: 3

is the same as

grid-row: 2 / 3;
grid-column: 2 / 3

is the same as

grid-area: 2 / 2 / 3 / 3

Here is the same example using grid line names:

grid-row-start: row2;
grid-row-end: row3;
grid-column-start: col2;
grid-column-end: col3

is the same as

grid-row: row2 / row3;
grid-column: col2 / col3

grid-area shorthand can’t be used with grid line names.

If the grid line names are generated using the repeat() function, generated occurrence number also needs to be specified, separated by whitespace.

grid-row: row-start 2 / row-end 2;
grid-column: col-start 2 / col-end 2

Grid items by default, span only one row and column track, but can span multiple row and/or column tracks using the same properties to position them.

grid-column-start: 1;
grid-column-end: 4

is the same as

grid-column: 1 / 4

is the same as

grid-column: span 3

Same logic can be applied to rows:

grid-row-start: 1;
grid-row-end: 3

is the same as

grid-row: 1 / 3

is the same as

grid-row: span 2

The keyword span, is always followed by the # of columns or rows to span.

Item positioning by grid areas

Let’s reuse the example found in the ‘grid area naming’ section and position a grid item inside the header area.

grid-row-start: header;
grid-row-end: header;
grid-column-start: header;
grid-column-end: header

is the same as

grid-row: header;
grid-row: header

is the same as

grid-area: header

Final thoughts

That’s it for the ‘part I‘ of the ‘Introduction to CSS Grid Layout Basics’ series.
part II‘ will cover implicit grids, item layering, and aligning grid items and tracks.


About Luka Čavka

I’m a front-end developer from Split, Croatia, with a passion for responsive web development, especially HTML and CSS coding. During 7+ years of professional experience I have worked with clients from various fields and have published more than a few hundred websites. In my spare time I enjoy tinkering with new front end tools/techniques and having a beer (or two) at the local pub.