Unlimited Wordpress themes, plugins, graphics & courses! Unlimited asset downloads! From $16.50/m
  1. Web Design
  2. HTML & CSS

A “Readability First” Approach to Media Queries and Layout

Read Time:23 minsLanguages:

There are a few different approaches to multiple-resolution-friendly web design and the application of media queries which have emerged in recent years. Some of the practices you've probably already heard about include:

  • "Mobile First" - Starting at a narrow phone oriented width of around 320px and then increasing in size from there.
  • "Desktop Down" - Beginning with a full-sized design then scaling down as required.
  • "Content First" - Establishing test content at the beginning of the process and then designing around it progressively.
  • "Device Specific" - Targeting a series of device-specific resolutions with breakpoints at corresponding px values, e.g. phones at 320px to 480px, tablets at 768px to 1024px, 1200px+ for desktop etc.
  • "Device Agnostic" - Creating a 'one design fits all' system which flexibly fits to any resolution.
  • "The Goldilocks Approach" - Leaving the base font size to the browser or user to set as preferred, then building an em driven layout on top of it using three layouts: 'Too Big', 'Too Small', 'Just Right'.

In this article I'll be talking about a methodology that is a mixture of some of the above, with a few extras stirred in. It's both "Content First" and "Device Agnostic", and was originally inspired by the typography focused em based "Goldilocks Approach".

I like to think of it as a “Readability First” approach. The designs resulting from this approach:

  • are optimized for the easiest, most comfortable reading experience possible, based on research data regarding eye movements among average readers.
  • fluidly adjust to any resolution, even on the latest "8.3459 inch mini-fridge phone".
  • proportionally scale along with browser or user font size settings.

The ideas that comprise this approach aren't new, but they're mixed together to create a particular flavor of responsive design.

And to go along with this flavor I'll also be sharing with you a script named "RDBL", which I've created to help you assess how readable your text content is at various points. Even if you don't adopt the "Readability First" method you might still find this little widget helpful in whatever responsive design approach you do use.

“Readability First” Principles

There are a four simple principles which form the basis of this “Readability First” approach, though how you implement them will vary somewhat from one design to the next.  They are as follows:

1. Don't set an explicit base font size; leave that to browser or user preference

The idea of leaving the defaults alone and not setting an explicit base font size for your document is a concept I was introduced to by The Goldilocks Approach.

The general idea behind this is based on the following:

  1. Browsers have default font sizes in place which are thought to be the most readable for various devices depending on resolution and pixel density.
  2. Users may also set their own default font size at a level which is comfortable for them.

By not overriding these defaults with your own base font size you can allow your design's text to automatically resize depending on browser and user preference. This in turn gives you a head start with readability on various devices and for individuals from word go.

In some cases you may have to make adjustments if a font is particularly small or large relative to most other fonts at default size. There can be quite substantial variation between the actual size of two fonts even if set to supposedly the same size in code.

However, if you do need to scale the default font-size in order to normalize it, do so with a relative value, i.e. percentage or em, applied to the html element. In this way your overall text size will still be determined by the browser / user settings and the rest of principles of this approach can be implemented.

2. Enter dummy content at the beginning of the design process, not the end

When we think about web "design" it's easy to get caught up in the "design" part of the process, sometimes adding in content only as the last part of the process after everything else is in place.

However, in our approach text content is added at the very start of the process, before any visual styling at all is applied. The rough overall process is:

  1. Insert dummy text in a section or article element.
  2. Select the font-family and font-weight settings that will be used.
  3. Add relative unit based CSS to control the layout around this text in a way that will optimize readability (more on this in the coming sections).
  4. Add visual styling as a sort of "paint job" over the top of this layout, adjusting if required.

This is essentially the reverse of the process made popular in the past where design would start with visual styling in a PSD, then CSS layout code would be generated to fit the design, typography CSS code would be added in to emulate whatever was in the PSD, and lastly some dummy text would be inserted to demo the finished product.

The reason we have flipped this process is:

  1. For a visual "paint job" to successfully adapt along with a flexible layout you need to know what that layout will be.
  2. To generate a flexible, readability optimized layout you need to see how text within it will appear in the browser.
  3. To see how the text will appear you need to know its font-family and font-weight due to the variance in size these can cause.
  4. To choose and apply font-family and font-weight settings, you need dummy text.

So, while tweaks to typography settings can certainly be made later on in the process as part of polishing the design, the essential selections of font-family and font-weight should be applied to dummy text before settling on layout and styling.

3. Build your design in relative % and em/rem values, not px

In this approach as a general rule you don't use px units. Instead, everything from height & width, to margins & padding, to border radius & width is set in relative % and em / rem units.

The primary reasons for this are:

  1. By using % values on layout wrappers and columns you can create a design that fluidly flows in width between your breakpoints rather than jumping from one width to the next.
  2. By using em / rem values on everything else your whole design will scale proportionally with the browser / user set base font size.

Fluid % based wrapper & columns

To create a wrapper around your design which will allow for fluid fit to the viewport in between breakpoints, use the following technique:

Firstly, we set the wrapper to be 100% of the viewport width. This means that should a visitor be viewing your design at somewhere in between two of your breakpoints they won't see empty spaces around the outside, instead it will be properly flush with the edges.

However, text at 100% width on a wide screen monitor is not going to be easily read at all. So we then enter a max-width setting of 40em meaning that even on a large monitor the site's wrapper will never be wider than this amount. This value can be adjusted further for readability as will be described in the sections below.

Columns within this wrapper can also have % values applied to them rather than px, so they too will fluidly adjust within viewports. Padding and borders can be applied to percentage based columns in em values without throwing out the layout by ensuring your design's box-sizing property is set to border-box. Margins on columns should be set in % values.

Note: Read more about working with this type of layout system in my article on grid mixins.

Uniformly scalable em/rem layout design

By using em / rem instead of px the various layout aspects of your design will always have the best possible relationship with your text content. No matter what setting the browser or user has, the base font size of your whole design will scale proportionally, where otherwise text would just change size within a fixed container:

Not only will your design look better if it scales proportionally, but it will be easier to read as well. We create spacing around text content very much with the goal of making it as easy as possible for the visitor to read that content. Only if the spacing is scaled along with text size can we ensure we preserve the benefit of these carefully designed layout elements.

4. Keep your primary text content within an ideal range of characters per line

Naturally in a "Readability First" method the core focus is on text content and its presentation. Most sites have an area in which their primary content is held and as such we begin with optimizing that space for readability. Once the primary content area is optimized the rest of the layout can be built around it.

The way we optimize the primary content area for readability is by targeting an ideal range of characters per line that, according to research, will be the most comfortable and natural for an average reader.

Characters per saccade, saccades per line

When we read text most people don't look at each individual letter or word one at a time. Instead, we tend to direct our eye at group of characters at a time, using peripheral vision to take them all in. Each time the eye moves from one group of characters to the next that jump is called a "saccade". A saccade can cover anywhere from 1 - 20 characters, but the average is between 7 and 9.

If there are too many characters / saccades per line the eyes grow strained and tired, and if there are too few the reader has to break focus to go to the next line too often to properly absorb the content.

There is some debate on the exact number of saccades the average reader is comfortable to make per line, however after much research I found that around nine is a value that tends to find general agreement. Based on these numbers, in order to optimize readability for the average reader the number of characters per line should be between 63 (for seven saccades) and 81 (for nine saccades).

Note these numbers should be used as a general guide. Strictly speaking, a reader who struggles greatly might take in only nine characters in nine saccades, while a highly skilled reader could take in one hundred and eighty. So while you should target this range, if your layout is a little higher or lower than this range that's perfectly fine.

How To Implement “Readability First”

Now that you're familiar with the principles of “Readability First” I'll walk you through how to implement them in a layout. I'll do this by showing you how the demo for the RDBL script I mentioned previously was created.

This is just monochrome "programmer art" for the sake of demonstration, but you can apply these principles and techniques to virtually any design style.

Start by finding the maximum readable em based width

In order to keep your primary content area to a maximum of approximately 81 characters per line you'll need to restrict its width accordingly, even for wide screen layouts. This usually amounts to a maximum width of somewhere around 35em - 40em give or take a few 'ems'.

This ties into what we covered above regarding our fluid site wrapper at 100% width with a maximum of around 40em. This maximum width setting will be one of the values you tweak in order to keep your characters per line below the upper readable limit. So if you're creating a single column design, your site's outer wrapper would be somewhere around 35em - 40em plus whatever padding amount you place around the text.

If you're creating a multi-column design on the other hand, the column widths would also be added on to the overall width of your wrapper. For example, if your primary content area needed to be no wider than 40em and was inside a column at a width of 66.66%, with a sidebar next to it at 33.33%, your outer wrapper element would need a max-width setting of around 60em. This might seem complicated at first but it's actually something that is quite straight forward to implement in practice, as you'll see below.

No matter what you do with your design, you will figure out the maximum width your primary content area needs to stay within the range of readability first. Once your upper limit is determined you can begin adding other layout elements, then fluidly optimizing as much as possible for the entire range between that maximum width and zero.

By putting readability first you are not choosing to put a specific device type first such as desktop or mobile. Instead, you're considering all devices and browser resolutions and planning for them simultaneously from the very beginning.

Using RDBL to find your maximum readable width

Initially I used a combination of resizing my browser, a width readout plugin, a character counter, Firebug and a calculator in order to figure out my maximum width. But before commencing this article I decided to make my life and yours a little easier with a script that will handle the whole process for you. You can grab a copy of the script on GitHub.

RDBL will give you a little slider bar above your design, and a readout of various pieces of information you'll find helpful as part of this process. You simply tell it which part of your site is you're targeting to assess readability, i.e. your primary content area, and it will tell you if that element is "Too Wide", "Too Narrow" or "In Range".

Note: the script will automatically look for an article, section or main tag, (in that order of preference), but you can also enter any class name or ID in the "Target Content Element" field instead.

You can drag the little slider to resize your site, (this emulates resizing the browser in a more manageable way), and it will automatically update the readout as you go along. When the little green "In Range" display turns red you can look at the information displayed to see what point this occurred at.

You can use the information displayed to determine the maximum readable width of your primary content area, and to that end there is also a rough estimate displayed of what that readable range will be.

In this example I have started with some dummy content in a very basic HTML layout, placing an article element inside a main element wrapper (you can use whatever tags you prefer):

Note: As part of your HTML document, make sure you include the viewport  meta tag so the media queries you add later will respond at the point you expect on devices of differing pixel density:

I then also apply some very basic CSS which leaves the default font-size alone, sets the box-sizing property to border-box, creates a fluid wrapper around my content, sets my primary text content to use the font-family "Open Sans" from Google Webfonts, and the font-weight of that text to 400:

This is all I need to figure out the maximum readable width for text using this font-family and font-weight, through RDBL, by doing the following.

First, I load up my simple layout in Firefox and see whether the little readability flag shows up red or green:

At 40em wide this text comes out at around 85 characters per line, which is just a little too high. This is an average taken from the first paragraph of text in the target element.

Now I have two options. The first is to just use the upper number from the "Estimated Readable Em Range" displayed on the read out as my maximum, which in this case is 38.117em. However, this is an estimation, so I can also use the slider to gradually shrink the site until I see the readability flag turn green and take the em width displayed at that point:

This turns out to be 38.5em, pretty close to the estimate. So I change the max-width setting of the wrapper to this value:

And on refresh RDBL will now show that the text is within readable range at its maximum possible width.

Adding padding

Now that I know my maximum readable width is 38.5em I want to add some padding around the edges of this content. I change the CSS for my article element as follows (with a background color so you can see the padding):

To allow for the extra 2.25em of width added to each side of the article, I add 4.5em to the main wrapper's max-width. You can even automate this process through using CSS preprocessor variables.

Now on refresh padding is added, but as the interior width of 38.5 em has been preserved the readability flag is still green.

Multi-column layouts

If I were just designing a single column layout I'd be able to proceed onto the next stage of setting up breakpoints now, knowing that my primary content is set at its maximum readable width. But what about multi-column layouts?

The process is essentially the same as above: just create your multi-column layout with flexible percentage based widths, then shrink down your site with the RDBL slider bar until you find the right max-width to apply to your wrapper to keep your content within readable range.

To convert this layout from a single column layout to multi-column by adding a sidebar, I start by adding an aside element into my HTML after the article element:

I then add some CSS to turn the article and aside elements into percentage width based columns. Because I'm adding an extra column the main wrapper will also now need to be wider to accommodate it. However I'm not sure yet exactly what width the wrapper should be to fit in the new sidebar and still keep the content at readable width.

As such I temporarily comment out the main wrapper's max-width setting. This will allow me to use the RDBL slider bar to scale the layout down from 100% until I find the new setting that should be applied.

I then refresh the page and, as before, gradually reduce the width of the layout until the readability flag turns green.

When the flag turns green the "Current Document Width" readout shows a value of 66.25em so I uncomment my main wrapper's max-width setting and change it to 66.25em. Now on refresh I have a fluid two column layout where the primary content is set within readable range by default.

You can use this same approach to add as many columns as you like, resetting your wrapper max-width then scaling down your layout with RDBL until you find the new value that should be applied in order to preserve your primary content's readability.

Find readability 'break points' then optimize via media queries

Originally, the term "breakpoint" didn't have anything to do with something being broken. However for the purposes of this method we're going to take the word quite literally. With our maximum readable width in place in our design we can start scaling down to find the "points" at which our readability "breaks", i.e. when RDBL shows its red flag again. We'll then add media queries to adjust the layout at each of these points.

Using the RDBL slider bar to reduce the width of the two column layout, the first point at which the red flag shows up again is 54.812em, this time showing "Too Narrow" due to the characters per line dropping below 63.

This is the first readability "break point", and so I'll create a media query to prevent the primary content area from reaching this point. I want to make the adjustment before the point at which the layout becomes too narrow, so I use the RDBL slider bar to bump the width up again just enough to go back to the green flag. At this point the read out tells me I'm at 55em wide. I copy the contents of the "Media query code" field and paste it into my CSS:

I now have to decide the best way to adjust the layout at this point. I know from the earlier single column stage of the design that the primary content needed a maximum width of 43em. This means that 55em would be too wide for the primary content to fill as a single column so I can't just move the sidebar out of the way entirely yet. Instead I can just reduce its size, allowing the content to take up more space.

I do this by decreasing the percentage width of the aside element, and increasing the percentage width of the article element:

I now refresh the page and start scaling down again, and this time I get past the 55em point with the main content still in readable range.

The next point at which readability breaks is at 50.875em when the text again becomes too narrow. Again, I nudge the width up just enough to get back into the green, and copy the media query from the RDBL widget, this time at 51em. This is still too wide to convert the layout to a single column so once more I increase the article width and decrease the sidebar:

The next readability break point appears at 47.5em, and the sidebar is now getting to small to make it any thinner. However I'm still a little higher than the 43em originally set on the main wrapper in order for the content to stay readable in a single column. So what do I do?

The answer is to go ahead and convert the layout into a single column at this point anyway, but to add enough padding to the article element that the content within will still be within readable range. So I create another media query at 47.75em, increase the article padding to 4em, and convert the layout to a single column:

On refresh the layout is now in readable range at a single column once it becomes narrower than 47.75em.

Continuing on with scaling down the next point at which readability breaks is 40.187em with the text being too narrow. The layout is already in a single column, so now the only thing left to do to allow more space for the content is to reduce the padding. To do this I create a media query at 40.5em and set the padding back to its original amount.

With this final media query in place the layout can now be safely scaled all the way down from the default maximum width, staying within readable range and fluidly filling the viewport the entire time.

Should you repeat all the above steps for yourself you'll notice at this point that if you scale down further again you will see the "Too Narrow" red flag. However you have already optimized for readability to the greatest degree possible. You can't reduce padding any further without impairing readability by having text too close to the edges. You can also guess that anyone viewing at this size is probably on a small device, so making font size smaller would also further only impair readability.

As such, even though the text will stray below the minimum characters per line amount from here down, you'll have actually already optimized for readability at all these small sizes as well as can possibly be done.

However the "Too Narrow" flag below this point is not of major concern, as devices only capable of viewing at a size less than this comprise just 2.9% of the mobile space, and even then they will only have around 5 - 6 characters per line too few which is still acceptable.

Adding your visual styling "paint job"

Once you have your complete readability first fluid layout in place you know what you have to work with as far as implementing visual styling goes. In fact you'll be likely to create a few unstyled layouts like these and use them many times over with different styling applied.

As you apply your visual styling you may find you need to adjust the layout to a degree, and if so just use RDBL to keep tweaking your settings to ensure you remain within readable range.

I won't go into a lot of detail on design here, however there are a few general recommendations I have in order to keep your site fluid:

  • Wherever possible use CSS3 instead of images, (e.g. for shadows, gradients, rounded corners, borders, glows) as styles created in this way are fully scalable as long as em / rem values are used.
  • Use font icons (e.g. Fontello) instead of image icons as they too will scale along with the browser / user font size.
  • Where you do use images as backgrounds, try to ensure they can be tiled to fill up whatever space your design must scale to fit.

Note: If you're used to working with Photoshop to create heavily image-driven design elements, you might like to check out using Adobe Edge Reflow instead as a means to generate CSS3 styles in a way that's familiar to you. Check out my article here on "5 Useful Things You Can Do With Reflow Now" for more information on that option.

Extra Notes, Tips and Wrapping up

The techniques shown in the implementation section of this article are just one example of how you can put the "Readability First" approach to work. There are no hard and fast rules to how you decide to deal with readability "break points", and if you were to make completely different adjustment choices than I did in the same scenario that's perfectly fine.

Every design is different and you should expect to make some judgment calls during the application of this approach. If something doesn't look right to you then go ahead and tweak the acceptable characters per line range RDBL uses, because with all the variance from one font to another it's impossible to make this an exact science.

You can change the characters per line range any time by altering the values directly in the widget, or you can feed in your preferred range when you run the script's initialization function e.g. init_rdbl(63, 90);

As you're scaling your layout up and down don't worry if you see a brief flash of the red "Too Wide" or "Too Narrow" flag. If there are one too few characters showing for 0.001ems of width it's no biggie. As long as you only see that red flash for a moment you can consider your layout to be within readable range.

I hope to have shared with you some new ideas for how you approach your layout design process, and at the very least a useful tool in the form of the RDBL script. Have fun making your own content first, device agnostic, "readability first" site designs!

Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.