Skip to content

Date: 3 Aug 2014



Accessible Responsiveness

One question that kept coming to my mind when I was learning how to create Responsive web pages last year was, "Why do almost all articles and tutorials on media queries only show examples with screen widths specified in pixels?" Surely queries written that way could only be guaranteed to work correctly if the user had his browser running at the same font size as the developer?

After all, one of the most important aspects of web development is Accessibility, as it makes the difference between being seen by all who want, or dis-enfranchising a large segment of the Internet population from enjoying - or in some cases even seeing - our sites.

And an important requirement of Accessibility is to ensure we allow for poor-sighted people who need to run with the text magnified. They frequently do this using the "text-only zoom" facility available on most browsers, as that has a particular advantage over plain zoom of the entire page. Not to mention some normal sighted people who have set their browsers to smaller font size as a matter of simple preference. Not to mention, also, that Disability Discrimination law in the UK and Europe, and similar laws in America, prohibits ignoring poor-sighted people in our work. W3C, the World Wide Web Consortium, specify that web pages should zoom to 200% without problem.

So our web pages must not only be responsive, we have the responsibility to make them accessible with it.

The Problems with Pixelised Breakpoints

There are several problems inherent in defining media query breakpoints in px units, in the form:


@media all and (max-width: 500px) { ... }

Pages that work fine, in the font size the developer used, suddenly behave all wrong when viewed in a different text size. Just a few of the things that can go wrong when the users change from normal to larger text size include:

  • Very long words become wider than their containers.
  • Text overflows out of the bottom of containers that have both width and height fixed in pixels.
  • Columns of text holding several words a line at normal text size may hold only two or three words of larger size text, making reading difficult.
  • Menus, that previously reorganised at the breakpoint width, now either drop options to the next line or disappear off screen.
  • Headings that at normal size just fit a single line now arbitrarily split onto several lines.
  • Lines of text coerced by "nowrap" overflow their containers.

Long sections of text in columns become jerky to read if there are too few words per line, making reading a very tiresome business. And the effect of headings is often spoilt if they are split over two lines, especially when split in the wrong place, for instance if it is just a single short word that gets pushed down.

A more unusual problem, but one I have seen more than once on web sites, is where very small buttons or links, often a small image, are situated right up against the scroll bars at the right of the window, preceded by a label. The developer sets the media query breakpoint so that the screen is rearranged just at the point where the button is about to touch the scroll bar....at normal text size. But if the user's browser is set to large text size, the text label takes up just enough extra space to push the button right under the scroll bar, making it invisible and unavailable!

And in a tiny twist of life's humour, an example of a very long word extending beyond its containing element is to be found on....oh dear, I really don't know how to put this delicately. Yes, it's on the lovely responsive page on W3C's own site.....advertising their brand new course on yes, you've guessed it, Responsive Web Design. Oh well, c'est la vie!

Basically, anything whose position is affected by previous text is liable to be out of position when unusual text sizes are in force. When problems like this are encountered, they will be solved simply by using a different unit of measurement for the media query breakpoints, as described below.

Why?

I didn't have time during my initial foray into responsive work to investigate why the tutorials should all restrict themselves to pixels in the way they did - perhaps I had just picked a few bad sites to learn from? I went ahead and used other measurements anyway in my next site, and they worked fine. However, I returned to the subject today, and did a little poking around. The results were interesting.

What I found

First, I found the reason for this almost universal use of pixels in media queries was because that's how W3C suggest doing it. In their Recommendation of 19 June 2012, and earlier documents from as long ago as 2002, the first four examples of media queries involving screen width (Examples 5,12,18,24) all use px units. True, the fifth example uses em units, but by then the "px" message has been read and understood! Unfortunately the document doesn't give any guidance on the factors to consider when choosing between px and em units.

Developer articles have, in general, used similar examples as W3C. In fact, when I Googled for the CSS code in W3C's Example 5 and Example 24, I realised that some articles and tutorials have simply copied over these examples in their entirety!

Next I Googled for: css media queries. Of the first 12 tutorial articles on media queries showing up in search results, at the time of writing this, almost all showed media query examples specifying widths only in px units.

So the tutorials simply take the line inadvertently espoused by W3C, and there the matter rests. None of them consider if this is really the best way to teach how to write a media query.

And Further...

The next thing I noticed was that these articles were themselves on responsive pages (as you might expect), rearranging their contents as I narrowed and widened my browser window. So surely, if they were using "pixelised" breakpoints themselves, I would find that most of these pages would not work as expected if I enlarged or shrunk the browser text size?

I was wrong. They all worked. They had all, except one, fixed the font size, so that text zooming was impossible! (in the most widely used browser, Internet Explorer; though others cope better.) Well, that is certainly one way of solving the problem and who cares about accessibility anyway! The one site that allowed variable fonts paid the price at larger zoom settings, because large areas of text, which was in columns, contained only one or two words per line. Reading its pages was a real chore.

Now fixing the font size, as most will know, is not good for accessibility. In some browsers (particularly Internet Explorer even at v11, and Google Chrome up to v36) it means people with poor eyesight cannot zoom the text to a larger size. They can, of course, zoom the whole page but that, for all non-responsive, fixed-width web sites (still the vast majority at time of writing this) means the page overflows the browser window. If the user is using a notepad, tablet or other similar device that are not wide enough to show the full width of the larger page, this means they cannot read long lines of text without constantly scrolling back and forth. Not a good user experience, and one that will likely send them away from the site with the next click!

The Solution

So how to make our media queries properly accessible? The answer is perfectly simple:

Instead of using pixels in our media query breakpoints, simply use em units.

Suppose we have a query like:


@media all and (max-width: 30em) {...}

to achieve some change when the screen size is equal to or smaller than 30 em. It will work equally well whatever the text size in the user's browser, large or small, because the query is now taking account of the text size. That is to say, the changeover will occur when elements are in the same position, relative to each other, regardless of text size. At the point the media query takes effect and rearranges the content, the page will look the same to the user using large text-only zoom as it does to the user using your default text size.

This requires no extra work on the developer's part. In all breakpoints we just convert the number of pixels to the corresponding number of em units.

An Example Menu

Take a menu, for instance, that starts as the usual list of words spaced out in a single line. We want to create a media query that will compress the menu for narrower screens, by removing the unnecessary padding and introducing vertical lines dividing the options instead:


Original menu:
        
 Home       About       Products       Contact us 

compresses to:
        
 Home|About|Products|Contact us 

Suppose the menu's length is exactly 640px. So it is too long for screens narrower than that, and we will want to have a media query that triggers for all screens less than or equal to 640px width. Let's also assume we are using Medium sized font (i.e. the size is 16px). So 1em is 16px.

To convert 640px to em units, we just divide by the font size. I.e. 640/16 = 40em. Our media query breakpoint will therefore need to be 40em or higher. (If we are using any other font size, the calculation is the same: divide the no of pixels by the font size to get the number of em units). So our query will be:


@media all and (max-width: 40em) {...}

Now what happens if the user is actually using a text-only zoom of, say, 150%? At this size, 1em = 24px (1.5 x 16), so our 40em menu will now be 960px in length. Clearly it is now much too long for a 640px device, and if the user is using a device that wide they will only see the compressed version of the menu. Only device screens wider than 960px will show the uncompressed menu.

Obviously it is not possible to write separate media queries according to the user's text size, but we don't need to. Using the breakpoint of 40em produces the change to the compressed menu, just at the point needed to avoid the menu misbehaving, whatever text size is in use.

Value ranges

There is just one important matter to be aware of, when using em units in media queries. It arises when specifying ranges using min-width and max-width. When using pixels in a series of media queries for different width ranges, we do something like this:


@media all and (max-width: 480px) {...}
@media all and (min-width: 481px) and (max-width: 800px) {...}
@media all and (min-width: 801px) {...}

Here we have chosen min-width values that are just 1 pixel greater than the max-width value in the previous range.

It's a bit different with em values, because 1em is equal to many pixels. If you had:

@media all and (max-width: 30em) {...}

@media all and (min-width: 31em) {...}

while it might look as though you have covered everything, in actual fact there is a small range of pixels, between 30em and 31em. That range is not covered by the above media queries, so whatever CSS style has gone before at the start of your stylesheet is what will be picked up and used on any screens whose width just happens to fall within that particular rang of pixels. So if, on a PC, you gradually shrink your desktop window down, just as it goes into this range you'll see the display jump around, picking up styles that should not be applying at all at this point!

One way to solve this would be to choose values that do not equate with any known device screen width, but that would be cumbersome, and too prone to error, or future devices using one of those values.

The solution is to write your queries like this:


@media all and (max-width: 30em) {...}
@media all and (min-width: 30.01em) and (max-width: 50em) {...}
@media all and (min-width: 50.01em) {...}

The range continuation widths are now specified to 2 decimal places, .01, a much smaller degree of accuracy than one pixel, so all pixel width's are now included in one query or the other. (Note that 1 decimal place would not be enough, given that 1em can be more than 10px, again depending on font size. But .01 is small enough to be certain.)

Conclusion

Using media queries with breakpoints specified in em units, you will be able to create designs that are not only responsive, but accessible to poor-sighted users as well.

References:

By Guy Hickling

I would welcome your thoughts on this subject...



Please speak your heart here:-

- No need to prove you're a human being. I'll just take your word for it.

There are several problems inherent in defining media query breakpoints in px units
All content on this site is the copyright of the author