Andi Smith

Media Queries: The Next Generation

2012 really felt like a progressive step forward for Responsive Web Design. As big corporate companies like Starbucks and Microsoft as well as governments began to introduce breakpoints in to their web pages to cater for the diverse range of devices now available on the market, it no longer felt like the technology was only for use for blogs and news sites. Responsive Design proved it was ready for mass consumption.

In parallel, using a responsive grid became popular as a convienent way of handling column configurations over breakpoints. From simple grids like the one used in Twitter Bootstrap to the SASS driven SUSY that allows you to keep semantic markup while managing columns over breakpoints; grids in a responsive design became popular.

Using these techniques, we could ensure that content was king and provide the optimal experience for our users regardless of how they were viewing our web page.

There Appears To Be a Problem.

But for all the possibilities media queries allow, there appears to be a problem with the current selection of available conditions. We're often told that we should build for content first and not design, yet the most widely used media queries are built in completely the opposite way: min- width and max-width. These two media queries measure the width of the page

  • often this is useful but there are situations where this isn't helpful, particularly on larger scale websites.

Suppose we were to create a small module on our page, for example a carousel, which sits across two columns of our three column grid. This module will be used across multiple pages and we are unsure how it will be configured over these pages.

2 Column

In a responsive design, we may create two or more breakpoints for this module to ensure that items resize as the page gets smaller, such as reducing the size of the font. Our module is responsive. But the media queries that determine when these breakpoints occur are based on the page width not the container width, so this module is actually only responsive within the context of placing it within two columns.

You can view a demo of the responsive two column carousel here (note the carousel is static for the purposes of this demo).

If we use the same module on another page, but give it a different number of columns, then the breakpoints we created before may be rendered impractical (or worse). Let's look at the same carousel module but sitting across three columns:

3 Column

Because we've changed the size of the container, the breakpoints set for this search module are now sub-optimal for the configuration of columns. The things we reduced in size before now shrink too early, and we are left with a lot of extra space.

You can view a demo of the responsive three column carousel with our original breakpoints here.

This is not such a big problem for three columns, it's a bit small but we can usually get away with this. Let's see what happens when we reduce the number of columns our module spans.

If we change our module container to span a single column the problem is much worse. Now the module container is too small, so the media queries we provided to shrink our content are inappropriate. Our page looks a mess.

1 Column

You can view a demo of the responsive one column carousel with our original breakpoints here.

A Solution

There's no point complaining about a problem without proposing a solution; and the solution in this case seems to be the argument for a new type of media query which can react to a container's properties rather than the page properties. In the case of our example, this would be a media query that can react based on the width of a container defined by the user rather than the whole width of the page.

In an ideal world, perhaps we'd solve this problem in CSS like this:


.container {

  @media screen and (max-width: 400px) {
    h3 {
      /* narrow styles */
    }
  }

  @media screen and (min-width: 401px) and (max-width: 800px) {
    h3 {
      /* wider styles */
    }
  }

}

But CSS doesn't support nested queries like SASS and LESS does, so perhaps a more suitable solution to the problem would be to create new media queries conditions min-width-of and max-width-of (and the equivalent height conditions) like so:


@media screen and (max-width-of(.container): 400px) {

  .container h3 {
    /* narrow styles */
  }
}

@media screen and (min-width-of(.container): 401px) and (max-width-of(.container): 800px) {

  .container h3 {
    /* wider styles */
  }

}

Now when we resize the page, our content would be able to resize when the container meets the condition, rather the page.

Conclusion

For rich content web sites, responsive web design can be a complicated procedure; and as developers push responsive in to 2013 the problem is only going to get more complicated.

Grids can help reduce complexity, but we are still reliant on measuring page properties rather than the properties of the actual container that holds our content. Here's hoping that in the future it becomes possible to create media queries based on containers so that we can allow greater flexibility on our web pages.

Appendix: Until Then

Not wanting to detract from the article above, I did want to share a solution that is possible in today's browsers, although it isn't particularly 'nice' and relies on JavaScript.

By using JavaScript to calculate and compare the container and page widths, we could apply a class to our container to determine how many columns it is currently occupying. This class would then drive the size of our content in the same way our media queries were in the above examples. Like I said, not a pretty solution - but a workaround until the bigger issue is resolved.