Media Queries with Less

Alex Libby

October 2014

In this article by Alex Libby, author of Learning Less.js, we'll see how Less can make creating media queries a cinch; we will cover the following topics:

  • How media queries work
  • What's wrong with CSS?
  • Creating a simple example

(For more resources related to this topic, see here.)

Introducing media queries

If you've ever spent time creating content for sites, particularly for display on a mobile platform, then you might have come across media queries.

For those of you who are new to the concept, media queries are a means of tailoring the content that is displayed on screen when the viewport is resized to a smaller size. Historically, websites were always built at a static size—with more and more people viewing content on smartphones and tablets, this means viewing them became harder, as scrolling around a page can be a tiresome process!

Thankfully, this became less of an issue with the advent of media queries—they help us with what should or should not be displayed when viewing content on a particular device.

Almost all modern browsers offer native support for media queries—the only exception being IE Version 8 or below, where it is not supported natively:

Media queries always begin with @media and consist of two parts:

The first part, only screen, determines the media type where a rule should apply—in this case, it will only show the rule if we're viewing content on screen; content viewed when printed can easily be different.

The second part, or media feature, (min-width: 530px) and (max-width: 949px), means the rule will only apply between a screen size set at a minimum of 530px and a maximum of 949px. This will rule out any smartphones and will apply to larger tablets, laptops, or PCs.

There are literally dozens of combinations of media queries to suit a variety of needs—for some good examples, visit http://cssmediaqueries.com/overview.html, where you can see an extensive list, along with an indication whether it is supported in the browser you normally use.

Media queries are perfect to dynamically adjust your site to work in multiple browsers—indeed, they are an essential part of a responsive web design. While browsers support media queries, there are some limitations we need to consider; let's take a look at these now.

The limitations of CSS

If we spend any time working with media queries, there are some limitations we need to consider; these apply equally if we were writing using Less or plain CSS:

  • Not every browser supports media features uniformly; to see the differences, visit http://cssmediaqueries.com/overview.html using different browsers.
  • Current thinking is that a range of breakpoints has to be provided; this can result in a lot of duplication and a constant battle to keep up with numerous different screen sizes!
  • The @media keyword is not supported in IE8 or below; you will need to use JavaScript or jQuery to achieve the same result, or a library such as Modernizr to provide a graceful fallback option.
  • Writing media queries will tie your design to a specific display size; this increases the risk of duplication as you might want the same element to appear in multiple breakpoints, but have to write individual rules to cover each breakpoint.

Breakpoints are points where your design will break if it is resized larger or smaller than a particular set of given dimensions.

The traditional thinking is that we have to provide different style rules for different breakpoints within our style sheets. While this is valid, ironically it is something we should not follow! The reason for this is the potential proliferation of breakpoint rules that you might need to add, just to manage a site.

With care and planning and a design-based breakpoints mindset, we can often get away with a fewer number of rules. There is only one breakpoint given, but it works in a range of sizes without the need for more breakpoints. The key to the process is to start small, then increase the size of your display. As soon as it breaks your design (this is where your first breakpoint is) add a query to fix it, and then, keep doing it until you get to your maximum size.

Okay, so we've seen what media queries are; let's change tack and look at what you need to consider when working with clients, before getting down to writing the queries in code.

Creating a simple example

The best way to see how media queries work is in the form of a simple demo. In this instance, we have a simple set of requirements, in terms of what should be displayed at each size:

  • We need to cater for four different sizes of content
  • The small version must be shown to the authors as plain text e-mail links, with no decoration
  • For medium-sized screens, we will add an icon before the link
  • On large screens, we will add an e-mail address after the e-mail links
  • On extra-large screens, we will combine the medium and large breakpoints together, so both icons and e-mail addresses are displayed

In all instances, we will have a simple container in which there will be some dummy text and a list of editors. The media queries we create will control the appearance of the editor list, depending on the window size of the browser being used to display the content.

Next, add the following code to a new document. We'll go through it section by section, starting with the variables created for our media queries:

@small: ~"(max-width: 699px) and (min-width: 520px)";
@medium: ~"(max-width: 1000px) and (min-width: 700px)";
@large: ~"(min-width: 1001px)";
@xlarge: ~"(min-width: 1151px)";

Next comes some basic styles to define margins, font sizes, and styles:

* { margin: 0; padding: 0; }
body { font: 14px Georgia, serif; }
h3 { margin: 0 0 8px 0; }
p { margin: 0 25px }

We need to set sizes for each area within our demo, so go ahead and add the following styles:

#fluid-wrap { width: 70%; margin: 60px auto; padding: 20px; background: #eee; overflow: hidden; }
#main-content { width: 65%; float: right; }
 #sidebar {
width: 35%; float: left;
ul { list-style: none; }
ul li a { color: #900; text-decoration: none; padding: 3px 0; display: block; }
}

Now that the basic styles are set, we can add our media queries—beginning with the query catering for small screens, where we simply display an e-mail logo:

@media @small {
#sidebar ul li a { padding-left: 21px; background: url(../img/email.png) left center no-repeat; }
}

The medium query comes next; here, we add the word Email before the e-mail address instead:

@media @medium {
#sidebar ul li a:before { content: "Email: "; font-style: italic; color: #666; }
}

In the large media query, we switch to showing the name first, followed by the e-mail (the latter extracted from the data-email attribute):

@media @large {
#sidebar ul li a:after { content: " (" attr(data-email) ")"; font-size: 11px; font-style: italic; color: #666; }
}

We finish with the extra-large query, where we use the e-mail address format shown in the large media query, but add an e-mail logo to it:

@media @xlarge {
#sidebar ul li a { padding-left: 21px; background: url(../img/email.png) left center no-repeat; }
}

Save the file as simple.less. Now that our files are prepared, let's preview the results in a browser. For this, I recommend that you use Responsive Design View within Firefox (activated by pressing Ctrl + Shift + M). Once activated, resize the view to 416 x 735; here we can see that only the name is displayed as an e-mail link:

Increasing the size to 544 x 735 adds an e-mail logo, while still keeping the same name/e-mail format as before:

If we increase it further to 716 x 735, the e-mail logo changes to the word Email, as seen in the following screenshot:

Let's increase the size even further to 735 x 1029; the format changes again, to a name/e-mail link, followed by an e-mail address in parentheses:

In our final change, increase the size to 735 x 1182. Here, we can see the previous style being used, but with the addition of an e-mail logo:

These screenshots illustrate perfectly how you can resize your screen and still maintain a suitable layout for each device you decide to support; let's take a moment to consider how the code works.

The normal accepted practice for developers is to work on the basis of "mobile first", or create the smallest view so it is perfect, then increase the size of the screen and adjust the content until the maximum size is reached. This works perfectly well for new sites, but the principle might have to be reversed if a mobile view is being retrofitted to an existing site.

In our instance, we've produced the content for a full-size screen first. From a Less perspective, there is nothing here that isn't new—we've used nesting for the #sidebar div, but otherwise the rest of this part of the code is standard CSS.

The magic happens in two parts—immediately at the top of the file, we've set a number of Less variables, which encapsulate the media definition strings we use in the queries. Here, we've created four definitions, ranging from @small (for devices between 520px to 699px), right through to @xlarge for widths of 1151px or more.

We then take each of the variables and use them within each query as appropriate, for example, the @small query is set as shown in the following code:

@media @small {
#sidebar ul li a { padding-left: 21px; background: url(../img/email.png) left center no-repeat; }
}

In the preceding code, we have standard CSS style rules to display an e-mail logo before the name/e-mail link. Each of the other queries follows exactly the same principle; they will each compile as valid CSS rules when running through Less.

Summary

Media queries have rapidly become a de facto part of responsive web design. We started our journey through media queries with a brief introduction, with a review of some of the limitations that we must work around and considerations that need to be considered when working with clients. We then covered how to create a simple media query.

Resources for Article:


Further resources on this subject:


You've been reading an excerpt of:

Learning Less.js

Explore Title