Grid
The introduction of the CSS grid module was a major milestone. It is extremely powerful, versatile and useful. It gives finetuned control over the size and position of all elements within the grid.
Basic website layout, with a main article and a sidebar? Grid!
Dynamic layout with tiles and images on the front page? Grid!
Intuitive UI that allows you to drag and drop images or elements around? Grid!
That also means, however, that I can’t explain all of it in just one chapter. This chapter merely gives you the high-level overview and simple, practical syntax for the most common use cases.
If you want, you can view the grid as two flexboxes at once: both vertical and horizontal at the same time. That indicates both how powerful and how complex it is. In fact, if you haven’t read the chapter on Flexbox yet, I highly recommend you do so first. It provides an easier introduction to many ideas described below
Starting a grid
Turning a container into a grid is still as easy as before:
- Use
display: grid;
(block-level element) - Or
display: inline-grid;
(inline element)
All its direct children are now “grid items” and behave as such.
Now the fun starts.
This is not a documentation
As stated before, this course is not a documentation. If you look up the full reference on CSS grid, you’ll be absolutely overwhelmed by the hundreds of options, properties, values and concepts.
The whole point of this course is to narrow it down to only the most practical, most common and simplest elements. To never overwhelm and to gently let you into the world of CSS.
As such, if you want the full run-down, this article by CSS tricks is great.
This chapter leaves out most shorthands (as always), the lesser-used properties, and lumps together properties that apply to both the grid (container) and the grid items.
Let’s start by explaining that last point.
Grid Container vs Grid Items
Most of the concepts below apply to both the container and individual grid items, although the property names are slightly different for each.
Why?
- If you set it on the container, it automatically applies to all grid items.
- If you set it on a grid item, it only applies to the specific ones you selected.
This is the recurring pattern of CSS. You want to set the general properties—true for 90+% of the design—on the containers. But it’s always possible, with a slightly different property, to make exceptions for specific elements lower on the hierarchy.
If you view it like this, the number of properties shrinks to a more manageable size.
As always, play around with the examples below! Try all the values, try changing properties, try modifying the grid. It’s an extremely fun and fast way to learn all the concepts.
Rows & Columns
The first thing to decide are a grid’s dimensions.
To set the distribution for the whole grid, use
grid-template-rows
for the rowsgrid-template-columns
for the columns
To set what space a single item should take up, use
grid-row-start
andgrid-row-end
(for rows)grid-column-start
andgrid-column-end
(for columns)
As you see, the properties are similarly named for the whole grid and individual items. But there’s a small difference in naming to clearly indicate this difference.
For the whole grid, it’s called “grid template”. Because this clarifies that you’re setting a template for all grid items to follow. If you’re merely changing one individual grid item, the “template” part is removed.
The shorthand property to set all of this at once, is simply grid
.
Grid Template
How do you define a grid? You define a “template”. You say “the columns should be sized like this and this”.
Once set, CSS figures out how to follow those rules and fill the whole area with this grid.
Of course, the whole power of grids is that they are responsive. No matter the space, the grid follows the template. To do so, we need to define the columns/rows in a responsive way!
The simplest approach is to use the auto
keyword. It says “add one entry and automatically resize it”.
Check the example below. It simply repeats auto
two times, to add two columns that automatically (fairly) resize to fill the whole space.
Grid Row/Column
You can set these properties to an exact number. For example, grid-column-start: 2
means the item starts at column 2.
But you can also use them to set only a size, by adding the span
keyword in front. For example, grid-column-end: span 2
doesn’t care at what column we end, as long as the item takes up the space of 2 columns.
In the example below, notice how the first element takes up two columns. And the fourth element is forced to start at column 2 (although it would naturally fall on column 1).
Units & Functions
Of course, we can go further than the simple auto
keyword.
The fr
unit
Within grids, you can use the special fr
unit. It stands for fraction. It’s similar to the flex-grow
and flex-shrink
properties mentioned in the Flexbox chapter. With it, you decide what fraction of the empty space is given to this specific row/column.
For example, 2fr 1fr
means …
- We want two columns.
- But the first should fill twice as much space as the second.
In the example below, notice how the fractions control the uneven sizing for the elements.
Minmax
The minmax(a,b)
is the magic wand you’ll need most of the time. It tells CSS: “you’re allowed to resize this column/row, but its size has to stay above a
and below b
”.
It allows responsiveness, while setting clear boundaries.
In the example below, notice how the middle column is bigger than the others. Why? It tries to be the same size as others and fill the same fraction (1fr
), but the minmax()
says “nope, you can’t go lower than 300px”. So it stops at 300 pixels, while the others continue shrinking.
Hopefully, you’re starting to see how much control you have over the resizing and responsiveness of CSS grids.
Related values to research are min-content
, max-content
, fit-content()
, min()
and max()
Repeat
The repeat(num, unit)
function simply saves you some typing.
For example, repeat(4, 1fr)
is just 1fr 1fr 1fr 1fr
.
But it can do a bit more. Instead of a number, you can supply.
auto-fill
to say “fill as many items as you can, even if some are empty”auto-fit
to say “fit the items we have, prefer expanding those over adding more items”
In the example below, the current code expands the items to fill the area (keeping the maximum into account). Change it to auto-fill
, and you’ll see how they all shrink to their minimum, filling the row with many empty grid items.
Alignment
To align the rows (horizontal alignment),
- Use
justify-content
for the whole grid. - Use
justify-self
for a single grid item.
To align the columns (vertical alignment),
- Use
align-content
for the whole grid. - Use
align-self
for a single grid item.
You might have noticed that these properties are named similarly to those for Flexbox, which also do the same. Thus, they also take the same values.
- For aligning a single item, you have
start
,end
,center
andstretch
. - For aligning the whole grid, you have additional values
space-between
,space-around
andspace-evenly
.
In the example below, notice how the whole grid is moved to “end”. But the first item, which has a smaller height, is set to center align within its own box.
The shorthand to set both at once is place-content
and place-self
.
Gap
This is the only styling that only applies the the whole grid container.
Why? Because it’s about the gaps between grid items. (So you can never set it on a grid item on its own, as it’s about spacing between grid items.)
The gap determines the amount of empty space between all the grid items. You can set gap for the two axes seperately, with grid-row-gap
and grid-column-gap
.
The shorthand to set both at once is grid-gap
.
What I left out
Areas
Instead of defining the grid as lines (rows and columns), you can define it as areas. For example, you could reserve a 2x2 block somewhere and call it “header”, which is then filled with a single grid item.
The grid-template-areas
property defines the areas. To assign a grid item to one, you’d use the grid-area
property on it.
Subgrids
You can already create a grid within a grid. Simply set a grid item (or something inside it) to display: grid;
as well, and you can nest as many grids as you want!
What do subgrids add? It allows you to create a grid in a grid, while automatically copying all those great properties you set on the bigger grid.
This is a value for the template. (For example: grid-template-columns: grid;
.)
An experimental property, only implemented in Firefox at the time of writing.
Masonry
A masonry grid is a very common grid layout for homepages and tiled designs. Instead of sticking to strict rows and columns, it allows elements to move up to fill any empty space left in their column.
Think of your typical Pinterest or tiled gallery of images.
This is another value for the template. (For example: grid-template-columns: masonry;
.)
An experimental property, barely implemented at the time of writing.
Auto-Placement
In the examples above, we neatly set a template for our grid and allowed items to fill it.
But what if we had a rogue item? What if we set an item to use “column 4” … while we only have two columns?
The “auto” properties can be used to control how the grid deals with that. (They are grid-auto-rows
, grid-auto-columns
and grid-auto-flow
. All of them set on the whole container, as this is, again, an issue that is unrelated to individual grid items.)
In general, it’s recommended to define a clear structure and stay within it. This quickly feels like putting a band-aid on an ill thought-out design.
Conclusion
For most use cases, a grid is really simple.
- Turn the container into a grid (with
display: grid;
) - Set the size/number of columns (or rows) that you want (with the template)
- Add styles to individual grid items to make it look how you want it to.
It’s recommended to go from big to small. First set properties on the whole grid that work for most situations. Only then set the same style on individual grid items that need it.
First set grid-template-columns
to give your grid 3 columns. But if one item wants to be special and take up two of them, set grid-column-end
on just that one element.
The other way around, focusing on small styles and exceptions first, usually means a lot more work and issues later on.
But if you want more advanced designs, you can surely achieve it using all the other properties. You can align, space, reflow, etcetera any way you need.
Hopefully this article gave a short and gentle introduction to what grids can do, and give you the tools to construct the type of grid you’ll need 90% of the time.
Want to support me?
Buy one of my projects. You get something nice, I get something nice.
Donate through a popular platform using the link below.
Simply giving feedback or spreading the word is also worth a lot.