An alternative to Flexbox is CSS Grid. As the name implies it is particularly useful when building grids. Often layouts can be replicated in both flexbox or CSS Grid. For example, 'grids' can be created with flex-wrap
, however CSS Grid does provide more control. It is often described as a two-dimensional layout system as opposed to Flexbox's primarily one-dimensional approach.
The display
Property, Grid-containers and Grid-items
There are familiar patterns in the setup of flexbox and grid.
A CSS grid is created with the display
property with a value of grid
:
The HTML element given a property of display:grid
is now a grid-container and its immediate children are grid-items.
Grid Lines and Tracks
Once declared as a grid
lines and tracks provide the dividing lines of the grid.
When working with Google Chrome Dev Tools the grid's lines and tracks can be made visible.
The tracks represents the rows and columns of the grid. The lines enclose each track. How each grid-item relates to the tracks can be controlled by range of CSS grid properties.
Column Tracks / Row Tracks
Before looking at what one can be done for individual grid-items, we will look at the grid-template
property. This can be used to create a template of rows and columns. For example, to create a grid with 3 columns we could use:
This creates three column 'tracks':
To give this layout two rows we would add:
This creates three column 'tracks':
The fr
unit is often associated with grid. It is unitless value used that represents a fraction of the available space. In the example so far the space has been allocated evenly. Changing the fr
values will change how much space a grid-item occupies.
See the Pen Grid Module Playground by Martin Cooper (@mustbebuilt) on CodePen.
CSS Grid has the same container properties for alignment that we saw with flexbox. For example you can control the justification of the grid-items with justifiy-content
and also apply gutters with gap
.
Working with grid-row/column-start/end
Sometimes a developer would like more control over an individual grid-item. For this we can use the grid-row-start
, grid-row-end
, grid-column-start
and grid-column-end
properites that are used to set the line where the row or column should start and end.
Notice that in the example above, there is a grid-item of class fourthitem
.
If we wanted this to 'span' over two columns we could extend the example above with a class
rule for fourthitem
such as:
Here we tell the div.fourthitem
to start on the first line and span until the third line.
Notice that when this is done the following grid-items will continue to try and fit into the defined template.
An alternative shorthand to the use of grid-column-start
and grid-column-end
is grid-column
which takes both the start and end values in the format of:
We could also do this with rows for example:
Notice how this places the fourthitem
at the start of the grid in row one completely changing the layout. As you can see grid is very powerful.
Header, Side bar, Content, Footer Layout
To see a practical example let's recreate the Header, Side bar, Content, Footer Layout from the Flexbox Examples.
Start with a simple HTML structure of:
We could then make the .container
a grid container and apply a template to create a two column grid with 1fr 3fr
split. That is one column 25% the other 75%. We can then use the grid-column
property to allow the header
and footer
to span over both columns.
See the Pen Header Footer SideBar CSS Grid by Martin Cooper (@mustbebuilt) on CodePen.
grid-column: span 2;
as an alternative to grid-column:1/3;
.Named Grid Areas
A further technique is to define areas in the container. Taking the same HTML structure as above we could define template rows and colums and then additionally grid-template-areas
where we use names to indicate the layout.
With the layout described as 'template areas' we can then apply these to the appropriate grid-items.
This approach allows you to create complex layouts in a clear and maintainable way.
See the Pen Header Footer SideBar CSS Grid by Martin Cooper (@mustbebuilt) on CodePen.