Responsive page design made easy

There is a perception that designing responsive webpages can be complex. But it doesn't have to be. The @media CSS selector will dynamically restyle your pages and it's easy to use.

Some time back I wrote an item on a simple and bullet-proof way to create robust multi-column page layouts. I have revisited and adapted that solution to create a multi-column layout that also dynamically responds to different viewport configurations. You may be surprised to find just how simple it is.

Try looking at the responsive page example and narrowing your browser below 800 pixel wide to see how the header links reformat and also how the content reflows. Now narrow your browser below 400 pixels and check again, or better still, have a look at it on your phone if you aren't already (try portrait then landscape).

The @media CSS selector is at the core of this solution. It enables CSS to adapt the layout for handheld screens or screens below a specified width.

 The original multi-column solution had responsive design already in mind. Each column of content was placed in its own container element that were themselves enclosed by a page element. Something like this;


    <!--Create containers for the page contents -->
<div id="pagearea"> <div id="Left">...[item links]...</div> <div id="Main">...[articles]...</div> <div id="Right">...[widgets, etc]...</div> </div>

Some CSS styling selectors were added into the head of the page that set the Header to the full width of the viewport and then set the percentage width settings for the Left, Main and Right divs to add up to 100 percent of the viewport width and float them side-by-side on the page area, like this;


    <style type="text/css">
/* set column alignments */
#Left, #Main, #Right { float: left; }
#Footer { clear: both; }

/* set column relative widths */
#Header { width: 100%; } #Main { width: 55%; }
#Left { width: 25%; } #Right { width: 20%; }
... </style>

Using percentage widths goes some way to making the page dynamically responsive because each column will resize to fit into the available width of the viewport rather than scrolling off the side of the browser window.

In order to create a page that is responsive to different viewport settings I have added a new @media selector to my CSS styling  -

    /* Restyle devices less than 800px wide */
@media only screen and (max-width: 800px) {

/* Reset the column widths */
#Main { width: 100%; } #Left { width: 60%; } #Right { width: 40%; }

/* Reset header style */
#Header h1 { font-size: 2.4em; }
h1 { font-size: 1.7em; }
... }

You will see that @media has been used in the example to set new width values for each major element, as well as a more appropriate headline font size for smaller devices. In particular, the Main element is set to a width of 100%, ensuring that it takes up the full size of the available space and forces other content to flow below it.

The final step in this solution is to notify any handheld device that the web page is responsive and is capable of optimising itself, so that the device doesn't try and shrink the entire page to fit onto the screen the way it does with non-optimised pages. This is currently achieved by adding the following meta tag into the head of your document;


<!-- Tell the browser that this content is responsive --> 
<meta name="viewport"
content="width=device-width, initial-scale=1">

Those changes to your stylesheet and one to the header of your page are all that is needed to create a fully responsive page. No Bootstrap in sight. Of course, you will quickly find ways to make your pages more sophisticated. Take a look at the page code to work out how the header navigation is restyled.

FYI: The 'viewport' meta tag syntax is far from cast in stone and is likely to be replaced by an @viewport CSS property in the near future. Do not be tempted with fancy variants of the above tag. There is no agreed standard for this notation at the present time and the more clever your viewport instruction, the more likely it is to be misinterpreted or ignored by different browsers.