CSS Grid Layout with Responsive Breakpoints
Here's an easy way to build responsive layouts with a new-ish CSS feature (circa ~2017). It combines two techniques—CSS Grid + SCSS breakpoint mixins—in a way I hadn't seen in other tutorials/StackOverflow threads.
This is an alternative approach to older layout methods that depend on floats, flexbox, and tables. Mastering
display: grid and taming
@media queries can help free you from frameworks like Bootstrap, Tailwind, etc. You can write lightweight, maintainable CSS from scratch instead!
Here's what we'll make:
A simple layout that changes at a single breakpoint. It's easy to add more breakpoints and related CSS rules.
Table of Contents - CSS Grid Layout with Responsive Breakpoints
A. Toolset ↑ Table of Contents
We'll combine CSS Grid Layout —supported by all major browsers beginning in 2017—with SCSS mixins to create a responsive layout.
Our goal here is a barebones starting point with as little code as possible. Basically, this is a scaffold for tinkering with CSS Grid in a useful context 1.
The following examples are written in Slim and SCSS. I explain most of the code with inline comments. These code samples are from a skeletal Rails app (repo here) but you don't need to understand Rails to follow along. File paths are relative to the app's root directory.
B. HTML ↑ Table of Contents
Here's the HTML (Slim) 2:
stylesheet_link_tag (👆 line 8) imports two SCSS files:
The line order is important. We import
breakpoints.scss first so we can call its mixins.
C. Responsive Breakpoints ↑ Table of Contents
breakpoints.scss does two things:
- Defines breakpoints, and
- Defines 3 SCSS mixins for interacting with the breakpoints elsewhere in our CSS:
Here is a heavily-commented version of
breakpoints.scss (uncommented version here):
D. Grid Layout ↑ Table of Contents
Now we'll use CSS Grid to create a simple nested grid layout. I'll explain what we're doing before jumping into the code.
First we set up a grid on
.page-grid. This grid has three (3) rows and one (1) column. The
.main divs default to
display: block and are therefore stacked. In other words, we're developing "mobile first."
Then, when window width exceeds 640px, our mixin applies a subgrid to
.main divs sit side-by-side in the subgrid row at least 600px high.
.sidebar has a grey background.
To be clear,
display: grid is not really necessary for
.page-grid in our example. I went with
display: grid to make it easier to extend the layout later 3.
Below is a heavily-commented version of
index.scss (uncommented version here):
Extending this grid from here is easy. Use
respond-above(screen) to apply breakpoint-specific CSS rules. You could also define additional breakpoints in
breakpoints.scss and call
respond-between($lower, $upper) to apply rules to ranges.
I hope you find this template and walk-through useful. Happy layout designing!
app/views/pages/index.html.slim. I've consolidated into one file for simplicity.
display: gridfor layout elements in a design.