Default Column
Progressive Enhancement begins with a sound default
Table of Contents
One of the biggest decisions to make when designing a site is
what column layout shall we use for each page?
Also,
what about all the different device widths?
and
what about older legacy browsers?
. How can we keep everyone happy?
The answer is a good default, cross-browser, one-column layout that will allow additional columns
to be added when needed, using progressive enhancement techniques.
Linear Layout
The good thing about building web sites is, if no CSS is available, all marked up content will be fluid and look good in any device at any width.
Ensure that each web page has the following:
- Document Outline. Use headers to structure your page so that users can quickly navigate a page by scanning the headers and their importance in the document.
- Important Content First. Users and search engines expect to find the most important content in a document very quickly. Locate this content at the top of the page.
- Semantic. Mark up content with semantic and valid code.
- Fully Functional. Without any client-side technologies, every page must be fully-functional with default behaviours. Server-side technologies must be in place so that users can interact with any business process the site may offer. Consider client-side processes as progressive enhancements, giving users with more capable devices a better experience.
Mobile First
The one column layout should begin life taking up 100% of the device width and all content should be fluid. This will ensure that no matter what device is used to view the content, the page will have all the features of the linear layout, plus some nice styling with CSS to make the content look good and fit nicely with the theme of the site.
Thus, leave the content to expand to the full width of the viewport with some small margin clearance. All small devices will appreciate this one column, fluid layout.
Main Style-Sheet
First, the main style-sheet is loaded by all capable devices, which enhances the linear layout to give basic styling and full viewport one column layout. The code snippets here will just focus on the layout properties.
<!-- Markup -->
<html>
<head>
...
<link rel="stylesheet" href="/c/style.1.0.css"/>
...
</head>
<body>
<!-- Note the div content container (Not an HTML5 section or article)
This will allow basic styling in non-JavaScript legacy IE browsers -->
<div id="content" role="main">
...
</div>
</body>
<html>
/* style.1.0.css */
/* Some background effect */
html {
background: #a9333f;
}
/* The page wrapper */
body {
background: #fbf8f8;
margin: 1em auto;
/* No width so expands to viewport */
}
/* The content wrapper */
#content {
margin: 0 1em 0 .6em;
}
Non-CSS3 Media Query Devices
Older browsers, such as IE8 and below, do not support media queries. This can be fixed using libraries such as Respond.js but I wanted a non-JavaScript solution and I also want to encourage IE users to upgrade to a more HTML5 compliant browser and give those users A Better Experience. (We need to move the Internet forward).
Conditional Media Queries
My solution is to use a linked style-sheet that only media query supporting browsers will load. Within this style-sheet, we can now use media queries, to adjust layouts at different widths and apply other enhanced CSS properties to progressively enhance these more capable devices and provide a better experience.
A positive for older browsers is that they do not need to load a whole bunch of CSS code they do not understand.
Enhanced Style-Sheet
Next, the enhanced style-sheet is loaded by all devices that support media queries, which enhances the basic layout to allow responsive layouts. The code snippets will focus on just the layout properties.
<!-- Markup -->
...
<link rel="stylesheet" href="href="/c/enhance.1.0.css" media="only screen and (min-width: 1em)/>
...
/* enhance.1.0.css */
@media screen and (min-width: 10em) {
body {
/* smallest font-size at 10em (160px) */
font-size: .8em;
}
}
@media screen and (min-width: 15em) {
body {
/* slight increase at 15em (240px) */
font-size: .9em;
}
}
/* Remain 100% width fluid for all widths up to 20em (320px) */
@media screen and (min-width: 20em) {
body {
/* Reduce page width and expose some background */
width: 96%;
/* Font size continues to increase as width is greater */
font-size: 1em;
}
}
/* As the width increases, we can continue to adjust the layout and font size */
@media screen and (min-width: 40em) {
body {
width: 94%;
font-size: 1.1em;
}
}
Content Too Wide
If no further action was taken on this content and it was viewed in a device that is wider than a small desktop, it would be very difficult to read. If you take a look at this paragraph in such a device, then you will see the issue and realise that we need to do something in order to give the user a better reading experience.
What we need to do now is have a few different column Layouts.
Before we look at column control using media queries.
- what about those old IE browsers that will always see long line lengths like these?
- What about many of the bugs we will find in IE browsers?
Helping IE Browsers
We can see that older IE browsers will have to read long line lengths as it currently stands. To fix this we can use IE conditional comments to target and fix these legacy devices. We should auto-center and give the page an ideal reading width of about 37em; and fix some bugs.
<!-- Markup -->
...
<!--[if (lte IE 8) & (!IEMobile)]>
<link rel="stylesheet" href="/c/ie.1.0.css"/>
<![endif]-->
...
/* ie.1.0.css */
body {
width: 37em;
_text-align: center; /* IE6 */
}
#content {
_text-align: left; /* auto-center fix IE6 */
margin: 1em;
}
Media Queries
Internet Explorer
So, the decision has been made not to try and enhance IE version 8 and below. These browsers will still have a decent design, have access to all site content and be fully-functional with any business processes the site may offer. They just will not get any bells and whistles and other client-side enhancements.
If you want to support these browsers, you will have to let the user suffer the loading of additional JavaScript libraries in order for them to get a similar experience. I feel it is better to encourage these users to upgrade to a more capable browser and get be rewarded with a much Better Experience.
Applying Media Queries
When I first started using media queries, my focus was on targeting devices, such as mobiles, smartphones, ipads, small desktops, etc. by their width in pixels.
Now that my designs have moved away from fixed pixel layouts to fluid and elastic, responsive layouts, I have not been comfortable with targeting numerous devices in varying pixel widths, sometimes in landscape mode and other times in portrait mode. Surely we should focus on the design and work in fluid units rather than pixels?
Fluid Media Queries
Breakpoints
A good fluid design practise is to use percentage for horizontal and ems for vertical measurements. To represent pixels as a fluid unit, we can use ems. Given that generally, 1em maps to about 16px, a set of media query basic breakpoints could be used as a starting point.
Notice how the ems in the table are easy to remember and map nicely to most device resolution widths in use today.
Breakpoint Examples
Thus, for device widths greater than 640px, instead of;
@media screen and (min-width: 640px) { }
We can use a media query that fits in well with a fluid design:
@media screen and (min-width: 40em) { }
To target small screen devices only, we might use:
@media screen and (max-width: 15em) { }
To target a range of device, perhaps small to medium desktops, try:
@media screen and (min-width: 40em) and (max-width: 50em) {
Media Query Usage (Detailed)
- Remember, the first set of CSS properties have no media query and will apply to all devices. The focus is mobile first and good overall content presentation.
- Next check IE styles and override mobile settings for small to medium desktop settings. No further layouts or enhancements will apply to IE version 8 or below.
- Start with smallest width media query that you feel your design and layout should change. Override basic layout properties were needed. Add enhancements.
- Move on to next larger media query, working your way to the largest one. Override previous media query properties and continue to add enhancements as the canvas size increases.
- Delete any unused media queries that are not useful to the design.
- Is the breakpoint right for your design? Adjust browser width to hit breakpoints and see if it looks good. Otherwise, if it looks rubbish, modify, add or remove breakpoints until the layout works for your design. Don't forget, it is about the design layout at different widths, not about individual device browsers.
px | em |
---|---|
160 | 10 |
240 | 15 |
320 | 20 |
480 | 30 |
640 | 40 |
800 | 50 |
960 | 60 |
1120 | 70 |
1280 | 80 |
1440 | 90 |
1600 | 100 |
1760 | 110 |
1920 | 120 |
Usage (Brief)
- Default Styles. Mobile first.
- IE overrides & bug fixes.
- Smallest media query next.
- Work through to largest.
- Delete unused media queries.
- Adjust breakpoints to meet design
Fixed to Fluid Conversion
Another useful formula for converting pixel based fixed layouts to fluid layouts is target ÷ context = result
Example Conversions
You have a two column layout. One is 200px and the other is 440px. The overall width is 640px (an old design). You want to go fluid and use % values. The context would be 640px.
/* Column one target (200px) ÷ context (640px) = result (in %) */
200 ÷ 640 = (0.3125 * 100) = 31.25%
/* Column two target (440px) ÷ context (640px) = result (in %) */
440 ÷ 640 = (0.6875 * 100) = 68.75%
Remembering that 1em maps to about 16px (16px = 1em), you want to work out the em size for 24px <h1> elements:
/* target (24px) ÷ context (16px) = result (in ems) */
24 ÷ 16 = 1.5em
What about those 12px paragraphs?
/* target (12px) ÷ context (16px) = result (in ems) */
12 ÷ 16 = 0.75em
Always take the context into account. Continuing with the earlier example, if you have an element inside the <h1> that needs to be 12 pixels, you use the current <h1> as the context. The context is now 24 pixels, so the context calculation is:
/* target (12px) ÷ context (24px) = result (in ems) */
12 ÷ 24 = 0.5em
Read more about fluid and responsive Layouts.