You’ve got a three-column grid, but when the browser window. is less than 500px wide, you break to a one-column grid. Let us review some of the ways.
1) Top-Level Media Query
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
@media (width < 500px) {
.grid {
grid-template-columns: 1fr;
}
}
Code language: CSS (css)
Aside from the slightly-newish media query syntax there, this has deep browser support and is a classic way of achieving our goal.
Advantages?
- The single top-level media query could contain other selectors so you can do more work under the logic of a single media query.
Disadvantages?
- You need to repeat the
.grid
selector (more code, error prone). - You need to repeat the
grid-template-columns
property (more code, error prone). - The property you are changing isn’t particularly close to the original.
2) Nested Media Query
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
@media (width < 500px) {
grid-template-columns: 1fr;
}
}
Code language: CSS (css)
Advantages?
- The nesting puts the property you are changing nearby the original, helping understanding at a glance what changes.
- You don’t have to repeat the
.grid
selector.
Disadvantages?
- The 500px breakpoint might be a common one where you make other changes to the design. Nesting might have you sprinkling/repeating them throughout the code rather than consolidating the changes together.
3) Variablizing the Columns
html {
--cols: 1fr 1fr 1fr;
}
.grid {
display: grid;
grid-template-columns: var(--cols);
@media (width < 500px) {
--cols: 1fr;
}
}
Code language: CSS (css)
We’re continuing the nesting here, but using a custom property to store and apply the grid-template-columns
value.
Advantages?
- As a custom property set at a high level, this value could be re-used in other places.
- Don’t have to repeat the
grid-template-columns
property.
Disadvantages?
- Naming things is hard.
- Sometimes custom property usage causes abstraction that is more confusing than helpful.
4) Using a Custom Function
@function --cols() {
result: 1fr 1fr 1fr;
@media (width < 500px) {
result: 1fr;
}
}
.grid {
display: grid;
grid-template-columns: --cols();
}
Code language: CSS (css)
Newfangled CSS! Custom value functions return a single value, and thus can be used to abstract away logic.
Advantages?
- Abstracted away logic can make the more declarative design block easier to read.
- Like a custom property, the function can be re-used.
Disadvantages?
- Very low browser support so far.
- Abstraction doesn’t always mean more understandable code.
- Unfortunate you can’t pass an argument for the media query size.
5) Custom Function + if()
@function --cols() {
result: if(
media(width < 500px): 1fr;
else: 1fr 1fr 1fr;
)
}
.grid {
display: grid;
grid-template-columns: --cols();
}
Code language: CSS (css)
Even more newfangled CSS! (Also, you could imagine using if()
alone for grid-template-columns
without the custom function I’m sure.)
Advantages?
- The custom function doesn’t need two
result
properties which could be a smidge confusing. - The more conditions there are, they more terse and nice feeling the
if()
syntax looks.
Disadvantages?
- Very low browser support, especially combining two brand new features.
- So friggin fancy it nearly breaks my old eyes.
So?!
What do you think? What is your favorite here? Or do you have an alternate entry?
I wrote “Advantages?” and “Disadvantages?” (with the question marks) as not all of them are objectively one or the other. You might feel differently.
Good piece! One nit to pick: it’s better to use
rem
thanpx
in media queries.That way, if the user cranks up the font size, the layout can adjust accordingly and stay at one column until more space is available, instead of trying to force gigantic text into three columns with only a few hundred pixels of room to work with.