Inline or combined media queries in Sass? Fight!
One of the things that disappointed me at Handheld Conference was seeing Eddie Machado explain the way that Sass was used for building up the Handheldconf.com website.
He was showing how they had used a Sass partial for different viewports. So for example:
@import main-styles.scss
@import media-query800.scss
@import media-query1000.scss
@import media-query1200.scss
These aren’t the names that Eddie used by the way. But this was the technique employed. Nothing wrong with that per se. It’s a choice, that’s all.
However, one of the most useful parts of Sass for me is being able to nest media queries as I go. So for example, if I’m writing a module, it might look something like this:
.name-space-ComponentName {
width: 80%;
@include MQ(Mplus) {
width: 100%;
}
}
This would compile to this CSS:
.name-space-ComponentName {
width: 80%;
}
@media only screen and (min-width: 47.5em) {
.name-space-ComponentName {
width: 100%;
}
}
I cover this approach extensively in ‘Sass and Compass for Designers’ so if you’re interested, you could take a look at that (I know, cha-ching). Alternatively, here’s a cut and paste Media Query mixin for Sass you can adapt to your needs.
So, seeing things done the ‘other’ way, I couldn’t understand why someone would choose that option, so I tweeted the following as I was listening:
Kids, don't separate media queries into separate partials. Use a mixin and do them inline. Much easier. #handheldconf => doing it wrong.
— Ben Frain (@benfrain) November 28, 2013
And got a few responses:
https://twitter.com/franzheidl/status/406122253127258112
@benfrain depends on the scale. Doesn't work as well on large scale builds in some situations with more complex modules
— Ashley Watson-Nolan (@WelshAsh_) November 28, 2013
I’ve heard the ‘bloated output’ argument in the past (a lot). I think it’s weak and I’m yet to be convinced otherwise by any real empirical data. Or even quite how it ‘doesn’t work as well on large scale builds’ as Ashley Nolan describes.
Personally, from my anecdotal testing, whether media queries are written inline or as a separate section, ultimately, it makes little difference.
As the people who were arguing against this method were using ‘large scale’ and ‘big projects’ as some kind of way to bat aside the technique I thought I would offer some hard, (admittedly anecdotal) empiracal evidence to support my argument.
I have a BIG CSS file. It’s for a BIG project with a BIG audience. 🙂
It has 134 inline media queries. I think that’s a fair amount? Here’s the numbers:
Number of inline Media Queries used: 134
Raw size with expanded output: 121.7KB
Compressed (minified) size: 100.7KB
Gzipped size (how it should be delivered over the wire): 18.4KB
Now, just for shits and giggles, I took exactly the same file and processed it through the Grunt Combine Media Queries plugin. This takes separate (inline) media queries produced by pre-processors (Sass or LESS) and combines them.
Same file. Only difference is that it has combined media queries rather than ‘inline’. Numbers. Combined there is only 12 media queries. A saving of 122 media queries – gosh that’s a lot. Maybe they have a point? Not so fast Batman:
Number of inline Media Queries used: 12
Raw size with expanded output: 111.5KB
Compressed (minified) size: 94.9KB
Gzipped size (how it should be delivered over the wire): 18.3KB
So, the end result is that NOT inlining media queries saves a user 0.1KB (actually just 65 bytes) over the wire. Is that bloat? Not on my watch. But if you want to make that saving, there’s still no good reason not to inline media queries with Sass. Just ensure your build tool takes care of combining them for you.
I remain utterly convined that if you want ease of authorship, then inlining media queries with Sass is the way to go. I’ll happily be convinced otherwise if someone can write up a compelling argument of why they are a bad practice?
Round 2
Since originally writing the post, both Ashley and Franz pointed out their concern wasn’t file size bloat but more the maintainability across a large complex project. Franz was kind enough to explain in detail in the comments so I’m quoting that here:
I didn’t refer to bloat purely in terms of file size, I’m more concerned about it on a ‘conceptual’ level: Having the same MQ multiple times (probably 100+ times!) in the output doesn’t feel especially efficient to me. If you really do care about that on a purely ‘conceptual’ level is a different question, if you have no problem with that and it gzips to less, fine.
In terms of dimensional breakpoint media queries though I much prefer having them all in one place (= all modifications to components, layout, etc. inside one single media query) for a reason: It’s of fundamental value to have it obvious to me and other developers on the project to see at a single glance which components/elements are modified under which conditions and how, and what their dependencies are.
Having to search through all the source to understand that is the CSS equivalent to spaghetti code and a maintainability nightmare.In fact, I’m currently using a hybrid approach:
I do inline resolution media queries (for hi-res resources), I’m using mixins that automatically include these for all elements for me. Having to declare these collected somewhere else wouldn’t help much, they’re basically doing the same thing without any dependencies, collecting them would increase development effort for nothing.
I do collect dimensional/viewport media queries in a file of their own though, for the reasons for reasons of clarity and maintainabilty as described above, I consider the trade-off of doing so to be immense.
After all, I think how you do it is down to a) preference and b) what your priorities are in terms of being DRY, maintainability, rubustness, level of abstraction, separation of concerns, etc. Both methods have their specific cost and pay-off, and there certainly is, once again, no silver bullet method here. You have to find the balance that fits you and the conditions of your project.
I’ll concede that authorship style is down to the individual/team and if that’s a preference thing that works for you, sure, go for that. I don’t concede however, that it makes it any easier. I’d argue the opposite. I’d define a component like so:
.name-space-Component {
width: 80%;
display: table-cell;
vertical-align: middle;
position: relative;
&:after {
position: absolute;
top: 50%;
margin-top: -.5rem;
}
// Override for Mplus sizes
@include MQ(Mplus) {
width: 90%;
}
// Override for Lplus sizes
@include MQ(Lplus) {
width: 95%;
}
// Override for XLplus sizes
@include MQ(XLplus) {
width: 100%;
&:after {
font-size: $text12;
}
}
// Override if it’s in a warning
.warning & {
color: $color-warning;
}
}
Hopefully that example is fairly clear. I define a component just once. Once across the whole project, irregardless of the project size, the number of partials used or any other metric used to decide what constitutes a ‘big’ project or not. Any changes to that component are contained within that block. If there are changes for different viewports, changes for whether or not it is nested within a different specific element, changes for if it also has a certain data- attribute – all in there. No matter what, everything to do within that module goes in that one block of code.
What could be more maintainable? Once place, one definition, one place for other developers. See something in the dev tools that needs to change? Just copy the HTML class and search the Sass folder for it (or use the dev tools to edit live). You’re safe in the knowledge there will be no other place the style can be overwritten.
So, I’m still not convinced but I appreciate Franz taking the time to explain the reasoning.
The most positive thing to take is that by using Sass for your media queries you can do it whatever way suits you.
Hi Ben,
thanks for the article. I didn’t refer to bloat purely in terms of file size, I’m more concerned about it on a ‘conceptual’ level: Having the same MQ multiple times (probably 100+ times!) in the output doesn’t feel especially efficient to me. If you really do care about that on a purely ‘conceptual’ level is a different question, if you have no problem with that and it gzips to less, fine.
In terms of dimensional breakpoint media queries though I *much* prefer having them all in one place (= all modifications to components, layout, etc. inside one single media query) for a reason: It’s of fundamental value to have it obvious to me and other developers on the project to see at a single glance which components/elements are modified under which conditions and how, and what their dependencies are.
Having to search through all the source to understand that is the CSS equivalent to spaghetti code and a maintainability nightmare.
In fact, I’m currently using a hybrid approach:
I do inline resolution media queries (for hi-res resources), I’m using mixins that automatically include these for all elements for me. Having to declare these collected somewhere else wouldn’t help much, they’re basically doing the same thing without any dependencies, collecting them would increase development effort for nothing.
I do collect dimensional/viewport media queries in a file of their own though, for the reasons for reasons of clarity and maintainabilty as described above, I consider the trade-off of doing so to be immense.
After all, I think how you do it is down to a) preference and b) what your priorities are in terms of being DRY, maintainability, rubustness, level of abstraction, separation of concerns, etc. Both methods have their specific cost and pay-off, and there certainly is, once again, no silver bullet method here. You have to find the balance that fits you and the conditions of your project.