Putting media queries in their place

Okay this is a bit of a techie, nerdy, question. It was too long to fit into a tweet so I have posted it here instead.

I have recently become a fan of object orientated CSS (or at least my limited understanding of it).

Object orientated CSS

This means that each element on a page has CSS that is unreliant on its position in the DOM. You could take that element and place it elsewhere on the page and it would appear the same.

I have also taken this slightly further and made sure that editing one element is not going to screw up another. Each element stands on its own.

It is true that this generates a little more code, but I massively prefer it as I can see all the CSS that effects a particular element in a single place. Changes are so much easier to make.

Responsive design and OO CSS

This got me thinking about responsive design and media queries. Traditionally these are kept in separate stylesheets that are triggered when a certain breakpoint is reached.

This breaks my lovely system of having code grouped together on a per element basis. I have therefore started putting media queries alongside my other styling rather than in a separate stylesheet.

My code would look something like this…

<blockquote>This is a <a href="#">quote</a></blockquote>

blockquote { width:100%; }

blockquote a { color:red }

@media only screen and (min-width: 640px) {width:50%;}

Now all my styling is in the same place. If I need to change the blockquote, I only have one place to look.

Not only that, but this involves fewer calls to the server because the media queries are all contained in a single CSS file.

My question is why does this suck? Why isn’t everybody embedding media queries alongside other CSS?

My initial thought was that perhaps a browser doesn’t load CSS files unless a breakpoint is reached. However, this doesn’t appear to be true. At least not according to some initially testing done by Craig and Dan have done (although to be fair these weren’t extensive).

So what is the problem? Let me know in the comments below.

  • mccombscreative

    We always develop responsive queries inline (in the same stylesheet). We also develop all of our CSS using LESS

    The only external stylesheets we run are conditional IE sheets.

    • fffh_moderator
    • fffh_moderator

      Plus, with LESS, can’t you embed the media queries in the same block as the rest of the CSS?  (Also, that other, aborted post was me.  It can be deleted by others as it seems that I cannot.)

      Sorry; I just can’t get DISQUS to let me log out of this account. Oh well.

    • http://boagworld.com/ Paul Boag

      How do you avoid IE choking on the media queries?

      • tom_usher

        If you’re designing mobile/content first, then IE just gets served that version of the site (along with a stylesheet of any IE specific tweaks you include). It just ignores all the fancy responsive stuff altogether.

  • tom_usher

    Put them where it makes the most sense from a maintainability perspective for you and the rest of the team; it’s usually all going to be minified and compressed before it’s served to anyone anyway.

    I always put the media queries in the module file for the component they affect – SASS offers some neat ways to keep this structured and maintainable.

  • http://twitter.com/shoghon Scott Phelps

    Using CSS preprocessing (less or sass) can eliminate the need for this method.

    By creating a variables and then operations, you only have to make the change in one place and it can change the others (even in other stylesheets).

    For a very clean representation of this process, I highly recommend digging into the framework Twitter Bootstrap. 

  • http://www.alwaystwisted.com Stuart Robson

    You could do this with media query bubbling available in LESS and Sass (3.2). I wrote a blogpost on how to ‘do it’ in LESS-

    http://alwaystwisted.com/post.php?s=2012-05-05-everyday-im-bubbling-with-media-queries-and-less 

    which led to this blogpost on how I now write ‘responsively’ – 

    http://alwaystwisted.com/post.php?s=2012-05-28-how-im-rolling-my-media-queries

    But you could just conintue writing seperate LESS files and compile them differently for IE like this –

    http://alwaystwisted.com/post.php?s=2011-12-01-a-less-approach-to-mobile-first-css-supporting-older-ie-browsers

    There’s no current way (in LESS) to filter out bubbling to create an IE stylesheet. You could give them ‘the mobile’ stylesheet (or Base, that’s a much more appropriate term). Or just ‘ignore’ <IE9 *ducks*

  • http://complexcompulsions.com/ Jeremy Worboys

    Same as others I use a similar method with SASS of placing the media query within the block I am styling. SASS will then bubble these to the top when compiling. I do my compiling with LiveReload and have it run https://gist.github.com/2611083 (still looking to improve) when it has finished the compile to group all of the common queries and move them to the bottom. 

  • http://twitter.com/stephanierieger Stephanie Rieger

    We split breakpoints up. Major breakpoints e.g. wide design/layout breakpoints are specified in the document head while minor design tweaks are specified in each individual style sheet. 

    This in effect, creates media queries inside of other media queries (or breakpoints inside of breakpoints :-). There will always be (way) more minor breakpoints than major ones, so this approach only results in a few more http requests than using a single style sheet (and only devices that match the wider breakpoints will incur those extra request(s) anyhow). 

    Each style sheet builds on the prior one (rather than replacing it outright) so the later style sheets are often quite lightweight…only including the differences that apply to that breakpoint range. We’ve found this approach makes it much easier to visualize/grok the design as a somewhat organic system of multi-layered progressive enhancements rather than a segregated ‘mobile layout’, ‘tablet layout’ etc. (which ultimately maps to nothing specific  given that larger devices are not necessarily more capable than smaller ones). 

    The mis-correlation of viewport size and capabilities is of course a common weakness of responsive design but thinking of each layout as a distinct thing makes the process of addressing the problem that much harder.

  • http://twitter.com/zrzonln Helge-K. Wang

    @media only screen and (min-width: 640px) {.className: width:50%;/* All classes/id’s that should be used on a resolution higher than 640px,  goes here, not just single values :) */}

  • chris_d2d

    I ran into a similar conundrum designing my latest responsive site. I wanted to include the media queries in a master stylesheet to cut back on http requests.  The issue I ran into was whether or not I should group styles based on their elements/classes (i.e. what you have done with the blockquotes) or whether I should group them by media query. I use SASS so the blockquote like structure seemed to make sense in the nested .scss document. 

    However, upon reflection, I am wondering if grouping based on media queries rather than elements/classes might cut down on repetition of the @media criteria. in large complicated stylesheets might this have any significant impact on the stylesheet size?

  • http://www.facebook.com/profile.php?id=36920343 Phillip Kynaston

    I think it’s about performance. Having a few media queries that contain lots of rules has to be faster than potentially hundreds of media queries. Remember that this is performance at the client side – it’s dependent on what the users’ hardware is..

    It may be clearer/easier for the developer to read, but if it affects the rendering time in the browser then should we not lump all rules together still?

    Interesting point though to see if the extra stylesheets are actually loaded anyway, then just not used, or whether they are loaded on request, at certain widths. Surely if they are all loaded then it makes a mockery of the mobile-first approach.. As I understood, the very point of this is that extra css (and images) are only loaded on bigger viewports. I’m going to go and do some tests now…

  • Mike Hopley

    I don’t see any problem with your method, Paul. I think embedding media queries inside stylesheets is typically preferable, because it reduces HTTP requests.

    Note that OOCSS has *two* main principles:

    1. Separate structure and skin.
    2. Separate container and content.

    You already mentioned (2): avoid location-dependent styles. (1) is about organising your CSS so that you can reuse existing styles to create new variations.

    For example, suppose you have a CSS3 button with gradients, shadows, and rounded corners. If you want to make a blue button and a red button, don’t repeat all that code. Instead, specify a base style (e.g. the red button) and extend it with a new class (to make it blue instead). This means using multiple classes on the HTML element.

    Also note that OOCSS — when done well — typically results in a significant reduction in code, not an increase. Surprisingly, this holds true for the HTML as well as the CSS. The CSS reduction is much greater, however.

  • http://twitter.com/PauldeWouters PauldeWouters

    I agree, using SASS/ Compass solves these issues

  • http://aaron-gustafson.com Aaron Gustafson

    Yeah, like Stephanie, we usually split the design up into major and minor breakpoints, using the linked stylesheets in the head for major breakpoints and  media blocks in said stylesheets for minor breakpoints. All breakpoints are typically assigned in a mobile first pattern starting with no media query and moving up the scale using min-width tracked to the font size (which takes care of Android’s pesky zoom states). Occasionally, we might sequester a small set of styles within a range of sizes by adding in a max-width query too, but it’s rare,
    Combined with SASS, which will compress your CSS and merge styles nested in identical @media blocks), this has resulted in smaller CSS files, fewer HTTP requests, and a smaller overall footprint on smaller/less-capable devices. It’s a win all around.

  • http://www.facebook.com/profile.php?id=1744371328 Joel Drapper

    Sass 2.3 makes this awesome. http://mikefowler.me/thoughts/passing-content-to-mixins-in-sass/

  • http://twitter.com/andmiriam Miriam Thomas

    I think there are a few things to consider here.

    1. putting styles for various break points in a separate file means that you can quickly and easily turn off ALL styles for that screen width (or device width). It means that you don’t have to go hunting through a file with styles all over the place. It’s also cleaner looking.

    2. Performance. Fewer media queries. Better for the user

    3. All that being said – it IS much easier from a development perspective to edit all the various versions of an element at once. Without having to hunt through three (at least) different files.

    So I guess it comes down to what the goal is for a particular project. And ultimately how extensive your media query styling will be. If you are adding one or two fixes for a particular screen size – why not put it all in the same file?

    I’ve recently been leaning towards separate files. But I’m ready to be convinced otherwise.

  • http://www.alwaystwisted.com Stuart Robson

    After a pleasant hour hacking around in LESS I figured out a possible solution that’s highly maintable and can be extremely specific in creating a mobile first stylesheet using LESS and including support for IE – 
    http://alwaystwisted.com/post.php?s=2012-06-05-another-approach-to-mobile-first-css-whilst-supporting-internet-explorer

  • http://twitter.com/matsaukeo Matt Keogh

    This is how I created my last responsive design:

    Two major breakpoints in different CSS files. “Global” and “Wide”.

    Each file has an index at the top and is split into easy to understand sections – eg: 4=outside structure, 5=individual pages.

    At then end of each of those I have some minor breakpoints. These are based on the original design’s columns at fairly equal intervals. I find that constant resizing of the screen to see when things breaks will create too many breakpoints. Using common device widths is pointless as these will change.

    I played with the idea of having each elements style (link in your example) have its own media query. The problem is you end up with millions of the same delarations of media queries – not good for bloat or in case you change your mind.

    The “global” css file is served to all device widths – if there is something that I definitely don’t want the wide devices to see I hide it using a media query.

    Both global and wide is served to lessthanIE9. BUT I make the website non-liqued for those browsers. That way I don’t have worry about advanced CSS that is used to lay the site out or that is served up by the inner media queries. What I do is make sure that lessthanIE9 can understand ALL the css it needs to lay out the “desktop” version.

    Hope that makes sense! – It’s a method that I’m still tweaking and I don’t think anyone really has a one size fits all solution yet.

  • Kevin Purnelle

    Just remember that the development files should not be the same than production files.
    Nothing wrong with your method :)

    As developers we should always work on “highly comprehensive maintainable code” and use a tool that will turn it into an “ugly optimized code”. That’s what minifiers do.
    In our particular case, individual media queries should be automatically grouped as some persons have already said here.

Headscape

Boagworld