Inline or combined media queries in Sass? Fight!

| 8 replies | Short URL: http://benfra.in/20x

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:

And got a few responses:

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.

About The Author

8 Responses to “Inline or combined media queries in Sass? Fight!”

  1. Franz

    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.

  2. anotheruiguy

    Science says that it’s not a real issue. As ugly as it feels, there are WAY MORE wins in keeping your media queries local to your module versus any other solution.

    If you are still concerned, run the test for yourself and look at the output – http://aaronjensen.github.io/media_query_test/

    BUT!!!! And I offer a huge but here, using extends we can make a bad situation better. There is nothing to say that all your media queries need to be mixins, therefore repeated code. As illustrated in this example (https://github.com/Toadstool-Stipe/stipe/blob/master/stylesheets/stipe/grid/_media_extends.scss) you can output a series of placeholder selectors for your grid within media queries. This will allow you to use these placeholder selectors within media queries.

    By placing the placeholder output towards the end of your CSS manifest (https://github.com/Toadstool-Stipe/toadstool/blob/master/sass/style.scss#L50), this will aggregate all the uses of the extended selectors in one place, at the foot of your CSS document. Check out this SassMeister gist (http://sassmeister.com/gist/7709878)

  3. Keith

    If you are creating CSS that follows a component design pattern, then having the MQs inline within the component is to me the only place they should live. Having a separate file for a specific MQ, breaks that pattern.

  4. Matt Berridge

    What about rendering performance? Is it more intensive for the browser to paint / tweak 134 media queries instead of 12, especially on resize?

    I use the ‘per-module’ method always (makes total sense to me, especially if you’re using BEM too) but was wondering about performance in this regard, and was considering looking at employing Grunt Combine Media Queries at build in future.

  5. Ben Frain

    Hi Matt,

    I think it’s not so much about the browser rendering and re-painting as I believe it will parse the CSS in one go and then paint to screen in one go.

    However, the more CSS the UA has to parse the more inefficient it will be. The question is ‘how much more inefficient’ and is it a real tangible difference? I don’t think there’s a binary answer here – it depends on the specifics of what you are building.

    However, if you can create a tool chain that automagically concatenates the media queries into one before the CSS hits production, there will be *some* benefit, however slight, so why not do it. If however, getting the MQs combined necessitates altering your workflow, I think the answer is that it probably isn’t worth worrying about on the average project. There are almost always better gains to make elsewhere.

  6. Bman

    Hey Ben!

    Awesome article ;)

    Globbing media queries seems to suggest that a bunch of elements are going to change because they reached a particular screen width. Setting them inline goes hand in hand with altering an element based on how it looks given a particular screen width. To me the former is efficient but makes it easier to forgo the attention to detail and harder to manipulate when it gets super large. The latter helps us build a mental sequencing of particular elements which is great for keeping code lean and gives us more flexibility in the long run on a module by module basis. I love the latter!

    On the human centered computing side keeping them inline is close to the idea of “mapping”. Switches, toggles, or widgemacallits should always be placed closest to the part that it manipulates. That way we can build a strong relationship between things by the way they are grouped.

  7. Adam Bloomer

    I’m a recent convert to Sass, having previously used Less but as far as media queries goes, I’m still trying to figure out the best way for me. I’m currently on a project where I’ve completely modularised my Sass files to really harness it’s power and make the CSS much more structured. I have however extracted my media queries into a separate file which, on reflection, is probably harder to maintain.

    I agree with your approach and will be using it in my next build however I may not be nesting media queries as deeply as you suggest in the article on each responsive element. I am planning on declaring my media breakpoints once below my ‘desktop’ styles which will contain all of the responsive styles for that particular module. It’s kind of a halfway house approach but still ensures if you are doing amends/fixes in the future, you are still working predominantly from one field for each element or group of elements you are modifying.

  8. Adam Bloomer

    sorry, that should be ‘working from one file’ in the last sentence.

Leave a Reply

Notify me of followup comments via e-mail. You can also subscribe without commenting.

294Days
294 days since this post was last revised. Specific details have probably changed.
1329 words
MENU