CSS Grid

Parts of the grid

Simple grid

Grid tracks

Grid tracks define where content in the grid can be placed, essentially the rows and columns of the grid. There are two types of grid:

The following things can be configured for grid tracks:

grid-template-columns: <column-defs>
grid-template-rows: <column-defs>
Explicit grid track definitions.
grid-auto-columns: <column-defs>
grid-auto-rows: <column-defs>
Implicit grid track definitions.
grid-template-columns: 10px 20px Fixed size tracks.
grid-template-columns: 1fr 2fr
grid-template-columns: minmax(20px, auto)
Flexible size tracks can be defined with the following units:
  • fr is a special grid unit which means 1 fraction of available space.
  • % can also be used.
  • minmax(<min>, <max>) allows tracks to adjust based on content size, but not go above or below a certain range.
grid-template-columns: repeat(3, 1fr) The repeat utility function allows you to repeat track listings a number of times.
grid-gap: 15px Sets the gap (gutter/alley) between grid tracks.

Explicit grid examples

The fr unit

The fr unit's behaviour is a little more complicated than just 1 fraction of the space of the grid. The important details are:

  1. The fraction of the grid given by 1fr isn't a fraction of the grid's total space, but a fraction of the available space. This means if there's a fixed with column in there, any fractional units will divide up the remaining space between themselves, rather than using a fractional size of the entire grid.
  2. Grid items can grow beyond their fractional size. If the min-content size of a grid item is greater than the configured fractional amount for a column then the column size will expand to fit that content. In this case the defined fractional amount will be different than actual columns size.

    Note you can fix this by using the minmax(0, 1fr) function to set the minimum width of a column to 0. This basically causes the grid to ignore min-content and always size to the given fractional amount.

For columns it's more correct to say: the fr unit sets the minimum width of a track as a fraction of the available space.

fr vs. %

Why use the fr unit instead of %?

minmax()

The minmax() function allows you to set a minimum and maximum on a grid track.

Fluid grids with auto-fill and auto-fit

General sizing algorithm

The auto-fill and auto-fit properties can be used to automatically determine the number of columns to use based on the available space and the configured column sizes. Some rules:

  1. The largest number of columns possible are created that won't cause an overflow of the grid container. The size of these columns is as follows:
    1. If the max track size is definite use that.
    2. Otherwise use the min track sizing function.
  2. If using a max track size of fr or auto, then any remaining space will be divided up among the columns.

auto-fill vs. auto-fit

The difference between auto-fill and auto-fit can be seen when the number of grid items is less than the number of automatically created tracks:

  1. auto-fill will leave empty tracks there
  2. auto-fit will collapse empty tracks and divide space between tracks with defined grid items.

Differences from simple fixed column sizes

The core difference between :
  repeat(3, minmax(30px, 1fr))
and
  repeat(auto-fill, minmax(30px, 1fr))

is auto-fill automatically changes the number of columns used, where as the fixed one doesn't.

Placing items

Grid lines

Whenever you explicitly place items on a grid you specify their position using grid lines. Relevant properties:

grid-column-start: 1
grid-column-end: 3
grid-column: <grid-column-start> / <grid-column-end>
Column positions for a grid item.
grid-row-start: 1
grid-row-end: 3
grid-row: <grid-row-start> / <grid-row-end>
Row positions for a grid item.
grid-area: <grid-row-start> / <grid-column-start> /
<grid-row-end> / <grid-column-end>
Shorthand property for entire grid item area.
grid-row: 2 / span 4 span specifies that an item should span the given number of tracks.
grid-column: -1 / -2 Negative numbers start from the end track.

Other notes:

Examples

Named grid lines

Grid lines can be given names and referenced elsewhere by their names.

The same line names can be used for multiple lines. Note:

Examples

Template areas

You can define how items will be placed in a grid using a string template syntax. See below for details:

grid-area: grid-area-name Grid items are given a name with the grid-area property.
grid-template-areas:
  "grid-area-name   grid-area-name  "
  "grid-area-name-2 grid-area-name-2"
The grid container then has a template defined which references these named areas and positions the corresponding items as defined in the template. Each row is a new quoted line. Each name in a line is a column.
grid-template:
  "grid-area-name grid-area-name" 40px
   1fr            1fr
A shorthand alternative to grid-template-areas which allows you also specify the row and column definitions. The row definitions are at the end of each row and the column definitions are below each column.
grid: <grid-template> Exactly the same as grid-template, but also resets implicit grid properties (for auto placement).

Notes:

Interaction between named lines and areas

If you define a named grid area then you will automatically get corresponding named lines generated for that area. E.g. if you have an area named header then you will get the following line names automatically generated for both columns and rows: header-start and header-end.

The same applies in reverse as well. If you have lines with the same name that form an area then the corresponding named area is automatically generated and can be used to place grid items. The lines must start with the same name and end in -start and -end.

Automatic placement

The previous sections have covered explicitly placing items in the grid. Items that are not placed explicitly as defined above will be placed automatically. Automatic placement happens as follows:

  1. First empty positions in the explicit grid are filled up.
  2. When the explicit grid is full new grid tracks are created according to implicit grid definitions and these are filled up.

Here are some relevant properties:

grid-auto-rows: 1fr Defines implicit grid rows. Multiple tracks are supported and repeat once used (not supported in Firefox). The default value is auto.
grid-auto-columns: minmax(50px, auto) Defines implicit grid columns. Multiple tracks are supported and repeat once used (not supported in Firefox). The default value is auto.
grid-auto-flow: [row | column] [dense] Defines whether extra rows or columns are created when the explicit grid is full. Defaults to row.
If you specify dense then no empty gaps will be left is possible (defaults to sparse where empty spaces aren't back-filled).
order: 2 Can be used to control the order grid items are automatically placed in the grid (defaults to 0). Items that have the same order are placed in DOM source order.
grid-column-start: auto
grid-column-end: span 2
You can combine auto placement with track spanning if you set an end property to span and leave the start property as auto. This will leave empty spaces if it can't fit. By default smaller items won't go back and fill empty spaces if they can fit (unless dense is specified as described above).

Aligning items and tracks

In CSS grid you can align items in grid areas, and grid tracks within the grid. Alignment applies when the item or track is smaller than the area or grid. There are two axis to be aware of:

The following properties apply:

Property Applies to Axis Individual or all Default Notes
align-self Items in grid areas Block Individual stretch
start if the item has an intrinsic aspect ratio
align-items All
justify-self Inline Individual
justify-items All
place-self Block and inline Individual
place-items All
margin Block or inline Individual 0 You can also align items with fixed or auto margins.
align-content Tracks in grid Block All start (why grid items appear in top left) If an item spans multiple tracks then it may be stretch when track alignment changes.
justify-content Inline
place-content Block and inline