Blog
Learning CSS Grid
CSS Grid Course Website by Wes Bos Opens in new tab
I really liked the JavaScript30 Opens in new tab course by Wes Bos Opens in new tab, where you get to code 30 different projects with plain JavaScript. Now he published another course which is also available for free. This time it's all about learning CSS Grid Opens in new tab. In this blog post, I will document everything I learned about CSS Grid in the course.
What you can learn from this blog post:
- General setup and basics of CSS Grid Development
- Implicit vs. explicit Grid
- Grid-auto-flow
- Sizing tracks
- Repeat function
- Sizing Grid items
- Placing Grid items
- auto-fit and auto-fill
- Using minmax() for responsive grids
- Grid template areas
- Naming lines in CSS Grid
- Grid-auto-flow dense block fitting
- CSS Grid alignment + centering
- Re-ordering Grid items
- Real-world examples
General setup and basics of CSS Grid development
In the first few videos, Wes talks about the tooling setup for the course. He uses browsersync Opens in new tab for the local development which is an npm package that automatically updates your browsers once you change the HTML, CSS, images, or other project files.
It is such a great tool I couldn't work without, and that is why browsersync has had its safe spot in my build tool setup with gulp for a long time.
Wes also talks about the basics of CSS Grid development with the firefox
developer tools. The basic principle reminds me of flexbox. You always have a
parent where you set display: grid
and define the settings for columns, rows,
and the gap between them.
Child elements inside this parent can be positioned separately. The firefox dev tools have a special layout window included where you can highlight the grid View and also show the numbers of the grid cells, which is extremely helpful when developing CSS Grid.
Implicit vs. explicit Grid
The difference between explicit and implicit grid tracks is simple. When you
explicitly define grid columns with grid-template-columns: 100px 100px
you get
explicit grid tracks.
If the browser notices that there is not enough space for all your items he automatically creates a second row.
So these tracks are called implicit because the browser creates them and not explicitly you.
The same applies if you have four items and define two rows. If you now add two
more items, the browser implicitly creates a new row. With grid-auto-rows
and
grid-auto-columns
, you can style any implicitely created row or column.
Grid-auto-flow
If you have two items, define two columns using
grid-template-columns: 200px 400px
and then add a third item, the browser will
put this item automatically in a new row below like, described before, with
implicit tracks.
This means grid-auto-flow
is set to row by default. If you set grid-auto-row
to column
, the third item will be automatically put into a new column next to
the other items.
Sizing tracks
The fr
unit represents the amount of space left after all elements are laid
out.
If you define three columns with grid-template-columns: 200px 200px 1fr
, the
first two columns will be 200px wide, and the last one will take up all the
space that is left.
fr
stands for fractional unit, but Wes likes to call it free space which
helps with remembering the idea of the fr unit.
It is also possible to use the auto keyword. Then an item will be sized according to the content it contains.
CodePen - CSS Grid - sizing tracks Opens in new tabRepeat function
Instead of writing:
grid-template-columns: 1fr 1fr 1fr 1fr;
you can simply use the CSS Grid repeat function and write:
grid-template-columns: repeat(4, 1fr);
CodePen - CSS Grid - repeat function Opens in new tab
Sizing Grid Items
By default, grid items just flow one after another, and as there is space for each one, they will fit themselves into the grid as they can.
There is also a way to more precisely size grid items inside a parent grid
container. The instruction grid-column: span 2
tells the browser to size the
specific child element with the space and width of two columns. The same goes
for grid-row: span 2
.
Placing Grid Items
There are also better ways to position grid items than just sizing them. With
grid-column-start
and grid-column-end
you can define where a grid item
should start and where it should end. There is also a shortcut property for this
so with grid-column: 2 / 5
, the grid item starts with the second column and
ends before the fifth.
You can also define that the grid item should start at the first column and span
over two columns with grid-column: 1 / span 2
.
If you want your grid item to start at the first column and span over the last,
but you don't know how many columns you have, just use grid-column: 1 / -1
.
The second CodePen example below shows all the different ways to place grid items inside a grid container. Have a look into the CSS to check how it is done.
CodePen - CSS Grid - Spanning and Placing Cardio Opens in new tabauto-fit and auto-fill
With the auto-fill
expression inside the grid-template-columns
declaration
you can tell the browser, "hmm, I'm not sure how many columns I want, make each
150px wide, for example, and then fill it with as many columns as possible".
So grid-template-columns: repeat(auto-fill, 150px);
does that.
The difference between auto-fill
and auto-fit
is visible when you have not
enough items to fill the grid.
With auto-fill
the grid will create as many columns as possible, although you
don't have enough items. So if you have four items and there is space for six,
the explicit grid ends after six items. In comparison to that, auto-fit
ends
the grid when all available items are placed inside your grid.
In the CodePen example below, open the firefox dev tools, enable the grid view
in the layout window, and you will see the difference between auto-fit
and
auto-fill
.
Using minmax for responsive grids
With minmax()
, you can tell the browser to make the items in a column a
minimum width of 150px
and a maximum width of 1fr
, for example. So the items
will automatically adapt to the available space.
This is also a great way to create a responsive grid without media queries.
When the grid items already have the minimum width declared with minmax()
and
the browser window gets smaller; they will automatically jump into the next row.
The CodePen example below also shows the difference between auto-fit
and
auto-fill
in combination with minmax()
.
Grid template areas
Grid Template areas come in handy for building a whole layout of a page. Say you want to have two sidebars left and right and a content place between them. Below you want to have the footer spanning over the whole row.
With grid template areas, you can type your grid parent into the
grid-template-areas
instruction exactly how you want the layout to look.
On the grid items, meaning the child items of the parent, you then tell each
item with grid-area
which part of the layout it should be. That's it! Simple
and easy full-page layout.
The firefox dev tools also offer the possibility to display your grid area names so you can quickly check if your layout is displayed as you wish it to be.
CodePen - CSS Grid - Grid Template Areas Opens in new tabNaming lines in CSS Grid
By default, you declare to span your grid items over the columns and rows by
using the line names 1,2,3, and so on. CSS Grid also offers the possibility to
rename your line names on the grid-template-columns
and grid-template-rows
declaration on the parent.
So if your initial declaration for the columns and the rows on the grid container is like this:
grid-template-columns: 1fr 500px 1fr;
grid-template-rows: repeat(10, auto);
and you want to span an item inside the middle column from the top to the tenth line you would say:
grid-column: 2;
grid-row: 2/10;
By renaming your columns and rows, you can now position your item inside this grid using the new line names.
grid-template-columns: [site-left] 1fr [content-start] 500px [content-end] 1fr [site-right];
grid-template-rows: [content-top] repeat(10, auto) [content-bottom];
CodePen - CSS Grid - Naming Lines in CSS Grid Opens in new tab
Grid-auto-flow dense block fitting
Grid-auto-flow is, by default, set to row, so every item that does not fit in the same row will automatically be put into a new row below. This can be helpful but also not really useful in a lot of cases.
If you have a grid with ten columns and you want every sixth item to span over
six columns, there will be a lot of empty space because the six-column-long item
often can't fit in the same row and is put into the next row via
grid-auto-flow: row
and the space left over is not filled with other items.
In this case, the dense value comes to help. MDN Opens in new tab describes this value as follows:
"Dense is a keyword specifying that the auto-placement algorithm uses a 'dense' packing algorithm, which attempts to fill in holes earlier in the grid, if smaller items come up later. This may cause items to appear out-of-order, when doing so would fill in holes left by larger items".
Go ahead and turn the grid-auto-flow: dense
instruction on and off in the
CodePen example below to see the difference.
CSS Grid alignment + centering
Flexbox made centering items on a page really easy. CSS Grid also has its ways to center items without problems.
There are two main properties that can be used for that. justify-_
defines
everything on the row axis, and align-_
defines everything on the column axis.
With justify-items
and align-items
, you can define the alignment for your
grid items on the grid container. There is also a shorthand called place-items
which you can give two values, the first for the justify-_ property and the
second for the align-_ property.
If your grid items don't fill up your whole grid, you can use justify-content
and align-content
to align them as one inside your grid container.
Finally, with justify-self
and align-self
, you can overwrite the alignment
settings on the container and specify them on a single grid item.
Re-ordering Grid items
Imagine having a ten-column wide grid with a logo on the left that spans over two columns, a nav on the right that spans over eight columns, and a full-width content below.
It is possible to change the order of the logo and the nav easily so that the logo will be on the right and the nav on the left.
By default, every item has a value of 0 on the order property. So giving the nav
order: 0
, the logo order: 1
, and the content order: 3
will achieve the
re-ordering.
It is important to mention that this technique will goof up the order a screen reader will read it, so it is kind of bad practice concerning accessibility if you use this on a bunch of paragraphs, for example. But for a nav and a logo, it does not matter that much.
CodePen - CSS Grid - Re-ordering Grid items Opens in new tabReal World Examples
Nesting Grid with album layouts
In this example, you can see several album info boxes consisting of an image and a few details about the album. To achieve this layout, you have to define the columns on the main grid first, which contains every album info box.
With the following expression, you can define a grid that has columns with a
minimum width of 400px
and a maximum width of 1fr
.
grid-template-columns: repeat(minmax(400px, 1fr));
So depending on the available space, the Grid will add columns or remove columns and shrink or expand them accordingly, which creates a fully flexible and responsive layout without media queries.
To achieve the layout inside the album info boxes, it is important to know that grid items can also be grid containers, as we know from flexbox already.
So you can add two columns into every album info box so the album image has a
width of 150px
and the text takes all the remaining space. Vertical alignment
is also possible.
display: grid;
align-items: center;
grid-template-columns: 150px 1fr;
CodePen - CSS Grid - Nesting grid with album layouts Opens in new tab
CSS Grid image gallery
The next example is about building an image gallery with CSS Grid. The basic grid for this consists of repeating columns and rows that are 100px wide and high. This example is extended with a little bit of JavaScript to give each image a different width and height.
Therefore you have to make an array with a length of 50. Array.from
is pretty
useful in this case. Every Item of this array is an array itself consisting of
two random numbers between 1 and 4. These two values will describe the
horizontal and vertical length of the image.
For every item of the digits array, you then have to build the HTML, which consists of the image, an overlay, and a close button. By using ES6 destructuring, you can insert the randomly generated numbers for the horizontal and vertical values and use them as CSS class names.
By doing that, you will get 50 different images in the grid with a random row
and column-span between 1 and 4. Using the dense value on the grid-auto-flow
property, you can avoid having too many empty spots in between.
Another useful thing I learned here is that by setting two grid items in the same row and column, they will overlap. Very practical for adding overlay elements.
Flexbox vs. CSS Grid
In general, CSS Grid can do everything Flexbox can do. Some people say that Flexbox is for laying out elements in one dimension, and CSS Grid is for laying out elements in two dimensions.
In this example, Wes shows how things solved previously with flexbox can be done with CSS Grid and in what scenarios Flexbox is still the winner. You can find all the examples in the CodePen below.
CodePen - CSS Grid - Flexbox vs. CSS Grid Opens in new tabRecreating CodePen
In this example, you are recreating CodePen, the tool I have used to display all the examples before. CodePen is a development environment that allows you to write code in the browser and see the results immediately.
This example is good practice for learning to layout different sections of a page with CSS Grid. Basically, it is all about grids inside other grids.
CodePen - CSS Grid - Recreating CodePen Opens in new tabBootstrappy Grid with CSS variables
Bootstrap became very popular for implementing an easy way to use a responsive grid on a website. It implemented CSS classes for the orientation of your elements, how they should behave on different viewports, and how far they would span in your grid.
So a div with the class of col-sm-4
would span over four columns on a viewport
equal to or greater than 768px wide.
In this example Wes shows how to achieve the Bootstrap principle with CSS Grid.
CodePen - CSS Grid - Bootstrappy Grid with CSS Variables Opens in new tabResponsive Website
In this example, Wes shows how to build a whole responsive website with CSS Grid. He divides the page into several sections and then uses almost every technique of CSS Grid learned in the course to lay out the page.
Another thing Wes teaches here, and I liked, is the usage of aria attributes on buttons. So Instead of adding and removing a CSS class on the button, you can simply check the aria attributes value of the button and also use the aria attributes value for styling.
In this example, the button to open the navigation menu has the aria attribute
aria-expanded="false"
which indicates by default that the menu is not
expanded.
Additionally, it has the aria attribute aria-controls="menu-list"
which
indicates that the button controls the element with the class of menu-list which
is, in this case, the navigation.
By changing the values of these attributes with JavaScript, you can toggle the menu easily.
CodePen - CSS Grid - Responsive Website Opens in new tabFull bleed blog layout
The last example is about building a blog layout with sections of different width and elements.
CodePen - CSS Grid - Full bleed blog layout Opens in new tabSources & further reading
- The CSS Grid course by Wes Bos Opens in new tab
- A complete guide for CSS Grid by Chris Coyier Opens in new tab
- CSS Grid Layout by the Mozilla Developer Network Opens in new tab
- A collection of examples, videos, and other information to learn CSS Grid by Rachel Andrew Opens in new tab
- Auto-Sizing Columns in CSS Grid: 'auto-fill' vs. 'auto-fit' by Sara Soueidan Opens in new tab
- Layout Land, a YouTube Channel by Jen Simmons all about CSS Grid Opens in new tab
I hope you enjoyed this post and learned something new. If you have any questions, feel free to reach out to me via Email Opens in new tab.
If you want to support me, you can buy me a coffee. I would be very happy about it!
βοΈ Buy me a coffee βοΈI wish you a wonderful day! Marco