CSS has come a long way since its introduction in 1998. Over the past 20 years we have seen great advancements on the original spec released by W3C, most notably with the advent of CSS3 in the early 2010’s which gave us selectors, media queries, multiple backgrounds, border radius and gradients amongst other improvements. In spite of these advances layout has remained a pain point for many developers when it comes to styling with CSS.
Floating and clearing elements can be frustrating with many developers admitting that they don’t even understand how clearing an element actually works.
The advent of flexbox and it’s wide-scale adoption in recent years has solved some common layout problems such as centering and content distribution but does not really give us much control over 2 dimensional layouts. Enter CSS Grid.
CSS grid is a new layout model which offers us more control over the positioning of elements inside of a grid container irrespective of what order the markup is in.
“In addition, due to its ability to explicitly position items in the grid, Grid Layout allows dramatic transformations in visual layout structure without requiring corresponding markup changes. By combining media queries with the CSS properties that control layout of the grid container and its children, authors can adapt their layout to changes in device form factors, orientation, and available space, while preserving a more ideal semantic structuring of their content across presentations.”
There are a number of resources available (linked at the end of this article) that detail the CSS Grid spec in its entirety, notably https://gridbyexample.com by Rachel Andrews who has been working with the specification over the last five years.
Here we are going to take a look at some of the most interesting features that CSS Grid has to offer along with a few examples of their use.
See the Pen CSS Grid Demo by Ciaran Canavan (@CiaranCanavan) on CodePen.
The example above illustrates a basic grid layout using CSS grid. The sizing of columns and rows is done on the grid container itself. Here we are using grid-template-columns and grid-template-rows to specify our layout.
For mobile we only need to amend our grid-template-columns in order to re-order them.
Note the use of the new fr unit in this example. fr means fraction and is a unit of length. Using the fr unit we can instruct a column to occupy a fraction of the space available rather than assigning it a specific percentage or pixel value.
See the Pen CSS Grid Masonry Style by Ciaran Canavan (@CiaranCanavan) on CodePen.
This next example shows how we can create a masonry style grid using CSS Grid only (look ma, no JS!)
We have defined three different ‘block’ sizes using:
grid-column-end and grid-row-end
The grid rows and columns are then defined on the grid container.
We define the rows using:
grid-auto-rows: minmax(60px, auto);
The minimal function defines each row as having a minimum height of 60px and a max height of auto.
The columns are then defined using:
grid-template-columns: repeat(auto-fill, minmax(60px, 1fr));
Using the repeat function we stipulate that every column has a min width of 60px and max width of 1fr. Auto-fill then ensures that columns will populate the row automatically depending on the width of the row.
We ensure that when blocks automatically re-flow on window resize, the auto-placement algorithm used by CSS Grid uses a dense packing algorithm. This attempts to fill in holes earlier in the grid, if smaller items come up later.
See the Pen CSS Grid Template Areas by Ciaran Canavan (@CiaranCanavan) on CodePen.
Our last example looks at using grid template areas to create the ‘holy grail’ layout.
As per our other examples, we start by defining our columns and rows on the grid container using
grid-template-columns and grid-template-rows.
Additionally, we then set:
"header header header"
"menu main sidebar"
"footer footer footer";
This defines our template areas within the grid structure. By simply re-ordering these template areas we can create a different layout.
In this example we use a media query to re-order our template areas for mobile using: