SITERAW

Responsive design with media queries

A common annoyance amongst webmasters concerns the handling of the visitor's screen resolution, an issue that only got compounded with the advent of smartphones, tablets and other non-PC electronic devices that can browse the Internet and which all possess different screen sizes.

Let's imagine you just finished building your website and even took the time to embellish it with (what you claim is) the web's most jaw-dropping design.

But this design, as elegant as it may be, will usually have a specific width. Say around 900 pixels.

By contrast, my iPhone screen is 5.5 inches wide: 330 pixels.

What would happen should I try accessing your site with my phone is that I would only be able to display the top-left corner and would have to use the very irritating browser scrollbars just to be able to see the totality of your page.

Imagine having to scroll left to right ad nauseam for each line or each sentence.

Even if you were to use a relative width for your design, which is defined in percentage rather than pixels or inches, you could still mess up your layout by having an image, a video player or any other HTML element of which the width is superior to that of a smartphone screen.

So what is the solution?

A responsive design using CSS media queries.

Introduction to media queries

You can think of media queries as conditions for the application of a CSS code.

Very often these conditions will be related to the screen resolution, viewport or output device of the user.

A different layout for each device
A different layout for each device

Every media query is comprised of two parts: the conditions and the rules, the latter of which are only applied if the conditions are met.

Implementing media queries

There are two ways to implement media queries: in the HTML file or the CSS file.

Let's see how they differ.

Within the HTML

This method consists of loading one or more additional CSS files if the media query conditions are met.

We all know how to link the HTML document with an external style sheet.

It's something we learned to do as soon as we discovered CSS.

<link rel="stylesheet" href="style.css" />

You can add an additional <link /> tag with a media attribute which will contain the conditions required for this new CSS file to be loaded and its properties to be applied to our page.

This is known as making a media query.

<link rel="stylesheet" media="screen and (max-width: 1280px)" href="small_resolution.css" />

The value of the media attribute is the condition.

We will see what screen and (max-width: 1280px) means and how you can create your own media queries in a few moments.

Just know that you can provide several CSS files for your web page: one to be applied by default and another one, or more, that are only applied if the media conditions are met.

These new CSS files don't nullify the default one, they simply add additional properties and sometimes replace existing rules.

Within the CSS

My preferred method for using media queries is to place them directly in the same CSS document as the default rules.

The main advantage is that we don't need to manage multiple style sheets.

To do so, all we need is to write @media followed by the condition.

@media screen and (max-width: 1280px)
{

    /* CSS properties go here */

}

Any CSS rule you want applied only if the conditions are fulfilled are to be placed inside the braces.

Media features

Perhaps you may have intuitively grasped what the media query does.

Our example screen and (max-width: 1280px) is a condition which checks if the user's output device is a conventional computer screen and if the maximum width of said screen is 1,280 pixels.

You can see that there are two conditions to be met: the type of output device and its maximum width.

If we only wanted to check the former, we would only need to write screen.

There are many of such rules you can use to build your own media queries.

Here are a few.

Media types

Media types describe the general category of an output device.

Here are the different options.

  • all : suitable for all devices (default).
  • screen : conventional computer screen.
  • print : for printing and print preview.
  • speech : intended for speech synthesizers.

There used to be many more media types such as handheld for mobile browsers and tv for TV screens but they were depreciated.

Media features

Media feature expressions are very similar but usually require a value and are written between parentheses to differentiate them from media types.

Their purpose is to test for specific characteristics of the user agent, output device or environment.

Here are a few of the most useful.

  • width : the width of the viewport (ex. 1280px).
  • height : the height of the viewport (ex. 720px).
  • orientation : device orientation (landscape or portrait).
  • aspect-ratio : width-to-height aspect ratio (ex. 9/5).
  • color : color management in bits-to-pixels (ex. 8).
  • pointer : how accurate is the primary input device (none, coarse or fine).
  • scripting : is scripting (e.g. Javascript) available (none, initial-only, enabled).

There are many more media features but these are the essential ones.

You can prefix the majority of these expressions with either min- or max-. This is particularly useful when dealing with dimensions.

Logical operators

You may want to create a media query that depends on multiple conditions, such as in our first example.

For that purpose we can use these three logical operators: and, not and , (comma, for "or").

Here is how they work.

Conjunction operator

The and operator is used to combine multiple conditions together into a single media query.

All conditions must be met for the CSS to be applied (conjunction).

@media all and (min-width: 800px) and (max-width: 1280px)

The above code targets all output devices between 800 pixels and 1280 pixels wide.

Negation operator

The not keyword inverts the meaning of an entire media query (negation).

It will negate the entire media query it is applied to not just the specific media type of the condition.

@media not screen and (scripting: none)

To fulfill the conditions in the above code, the user must not be on a computer screen and not have scripting disabled.

Disjunction operator

Each query in a comma-separated , list is treated separately from the others.

If any of the conditions in such a list is met, the entire media statement returns true.

@media (min-height: 680px), screen and (orientation: portrait)

The above query will return true if either the minimum height is 680 pixels, or if the user is on a screen with a portrait orientation.

There is also a fourth logical operator called only. Some older browsers that don't know media queries can still interpret the beginning of the rule: they can read @media screen but not the rest of the rule, thus applying the style to all screens even if the rest of the conditions aren't met. Writing @media only screen prevents that.

Practical applications

Now that we've covered the theory of media queries it's time to put what we know into practical application.

We're going to need a baseline HTML document to work with, it can be anything you want as long as it has at least a title and a paragraph to test our queries.

Since I'm lazy, mine will have only a title and a paragraph.

<h1>Welcome to SiteRaw</h1>

<p>SiteRaw is the most awesome site on the web.</p>

Now let's add our default CSS.

h1 { color: red; }

p { font-style: italic; }

And finally our media query with conditional CSS rules.

You can add it immediately following your default CSS code.

h1 { color: red; }

p { font-style: italic; }

@media (max-width: 680px) {

    h1 { color: green; }

    p { color: blue; }

}

Try loading the page in your browser and then changing the dimensions of your window.

As long as the width of your window is at least 680 pixels, only the default CSS will be applied (red titles and italic paragraphs).

But as soon as the width goes under the 680 pixels floor, the additional style contained within the media query command is added (green titles and blue paragraphs).

This is the principle behind responsive design: dynamically changing the website layout depending on the visitor's resolution.

Media queries in CSS
Media queries in CSS

Our code was just a demonstration, as you won't be using media queries to change the color of your text... it's mostly used for adjusting dimensions, removing (via display: none;) some blocks that are just too large for handheld devices and rearranging the design of your pages to be readable on small screens and other web supports.

A responsive website

Now that we know how media queries work and how to apply them using CSS, let's move on to building an actual responsive design.

Our goal is to have a website layout that is compatible with both computer screens as well as handheld devices such as mobile phones and tablets.

Since we already have a fully functional website from our building your website chapter, we'll being using the same HTML and CSS code.

Our HTML and CSS website
Our HTML and CSS website

While this website layout works (very) well on computers, things start to go a little south when the screen size is less generous.

Try reducing the width of your browser window to mimic the approximate dimensions of tablets and mobile phones.

The first step in creating responsive designs is to identify what needs to be dynamically modified via media queries.

Since our layout is organized in blocks, it's just a matter of assessing which ones are raising issues when the dimensions of the browser are reduced.

  • <body> : 760 pixels wide, let's change that to a maximum width
  • <header> : no problems here since there are no fixed dimensions
  • <nav> : takes up too much space, let's remove it
  • <article> : same as with the <body>
  • <aside> : takes too much space, let's put it under <article>
  • <footer> : no problems

The beauty of responsive designs with media queries is that you don't need to touch a single line of HTML code.

We don't even have to edit our default CSS, we can simply add a media query at the end of our stylesheet to apply specific rules if the user's screen is too narrow.

@media (max-width: 760px) {

    body, article { max-width: 760px; width: 100%; padding: 0; }

    section { display: block; }

    nav { display: none; }

    header { text-align: center; }

    article { flex: 0; }

    article h1, article h2 { margin: 25px 0; }

    article p { padding: 0 15px; }
}

You can see the result below.

A responsive design
A responsive design

This is the exact same HTML (and CSS) code, we only added one media query that is activated when the browser window is less than 760 pixels wide.

Targeting mobile browsers

Smartphone screens are much narrower than that of their regular computer counterparts.

To adapt to this reality, mobile browsers have a built in function that zooms out on the entire page and thus reduces the size of every displayed element.

This is called the viewport, you can think of it as the initial zoom scale.

And what does that have to do with media queries and responsive designs?

A lot.

Just like adolescent boys and people on the Internet, mobile browsers will lie about their size.

If you were to try and target mobile phones with the max-width condition, it would compare the specified maximum value with that of the viewport of the browser.

The problem is that there is a discrepancy between the viewport width and the actual physical width of the phone.

For example, an iPhone using Safari will claim that its width is 980 pixels... that's a little more than 10 inches or 25 centimeters.

I doubt that even Steve Jobs' worst prototype ever had a 10 inch wide screen.

More than that, it complicates the use of media queries since we can't use max-width to accurately target mobile browsers.

To resolve that issue, we can either target the device's width itself or adjust the browser's viewport.

Device dimensions

To target the device's dimensions rather than those of the window, which are affected by the viewport, we can use the media features device-width and device-height instead of width and height.

You can of course prefix them with either min- or max- to target the minimum or maximum.

@media (max-device-width: 500px)

Since mobile devices rarely measure more than 500 pixels wide, we can apply a smartphone specific style to our website using the above media query.

Changing the viewport

This is a much less common solution, but you can also change the viewport of the browser with a <meta /> HTML element (which goes inside the document header <head>).

<meta name="viewport" content="width=500" />

To remove the mobile browser zoom that reduces the size of every element on our page, all we need is to match the viewport width with that of the device.

The code is nearly identical.

<meta name="viewport" content="width=device-width" />

These are the two methods for handling the mobile-specific issues of viewport with media queries.

The first method, targeting the device dimensions rather than those of the viewport, is usually the preferred solution.