Picture of a computer/typewriter keyboard showing the letters e, t, i, l, l

Fluid Layout of Web Pages

How to extend the presentation of your content to suit all screen sizes, in particular small screens

Prerequisites

This tutorial assumes that the reader has basic knowledge of HTML and CSS, including CSS media types.

Introduction

The majority of authors thinks traditionally when designing Web pages. They are made for computer screens, with the dimensions 1024×768 pixels, and the ever growing number of small-screen mobile devices accessing those pages is simply ignored. However, designing for devices is not difficult. This article shows how.

Media types

The solution I will use to modify the existing style is media types. By default, screen (besides all) is the media type which is the default type honored by desktop browsers. Phone browsers like the Opera browser can display a page as a desktop browser (lets call that Desktop mode), but this option makes reading web pages cumbersome as they are often designed for large displays. In addition, Opera honors handheld in so-called Mobile mode.

Opera desktop can pretend to be a phone with the functionality named Small screen (in the View menu) which allows a preview of a page in Mobile mode. However, I want to stress the fact that this gives only a preview, as the final display depends e.g. on the fonts available (system settings) and the minimum font size (user settings), etc.

Phone browsers which are aware of the handheld media type will apply style from the handheld and all style sections, while those sections are ignored in Desktop mode.

There are several ways to add a handheld section to your current style.

In the first example the media attribute of the style tag is used. The style is included in the head section of an HTML/XHTML document.

<style type="text/css" media="handheld"> … </style>

In the next example the style tag is put into the head section as before, but the media declaration is part of the style itself.

<style type="text/css"> @media handheld { … } </style>

The example below shows how to incorporate style in an external file. Again, the style tag is a child of head.

<style type="text/css"> @import url(…) handheld; </style>

Finally, you can also utilize the link tag in the header:

<!-- external --> <!-- persistent style --> <link type="text/css" rel="stylesheet" media="handheld" href="…"> <!-- alternate style --> <link type="text/css" rel="alternate stylesheet" title="some title" media="handheld" href="…"> <!-- preferred style --> <link type="text/css" rel="stylesheet" title="…" media="handheld" href="…">

Using style

The reason why we can use a style sheet is the following. Consider the markup snippet:

… <head> <style type="text/css"> div {height:1em;width:300px} </style> </head> <body> <div width="200" style="width:400px"></div> <div width="200"></div> …

The div's width attribute is ignored if either a global (the style tag) or an inline (the style attribute) style is applied. Moreover, a local style overrides the global style. With our example, the first div will have a width of 400 pixels, while the second div will have a width of 300 pixels. Thus, a global style overrides attribute style, except for the style attribute. On a side note: A global style rule with !important would override local style, unless the local style contains another !important.

So far the theory. Now let's turn to practice.

Example

The best way to show how to develop a style tailored for small screens is by means of an example page, here a copy of the portal page of news.bbc.co.uk, taken on Sep. 28, 2006. This page is designed to fit on computer screens, and should according to the author be at least 770 pixels wide. Note that the copyright for this page is with the BBC.

Note also that the BBC page is slightly modified with regard to the intended educational purpose: Scripts and iframes have been removed, and the page is now — apart from images — self-contained. This page is subsequently denoted as original page.

It looks as depicted below.

The images may be displayed on this page in a scaled manner.

The look of the original page

Now let's start to extend the original page layout such that the page can be displayed on small screens — in addition to the normal (desktop) layout. We follow the principles listed:

  1. Keep as much original style as possible. This also implies to keep the page's logical content units.
  2. Make the page layout as flexible as possible, don't restrict the page to particular widths. There is a multitude of devices on the market with various displays of virtually any screen size, so keep it fluid. A typical screen size is QVGA (240×320 pixels in portrait mode), while the minimum screen width should be 120 pixels.
  3. Avoid a horizontal scrollbar. Imagine how much you would have to scroll both horizontally and vertically to navigate around on a page designed for ordinary-size computer screens with a small device screen. A scrollbar in one dimension is much more user friendly, and the de facto standard is to allow vertical scrolling.

Preparations

First we have to hook our own style into the main document.

<link rel="stylesheet" type="text/css" media="handheld" href="handheld.css">

is inserted right before the document's closing header tag </head>. This position ensures that any style rules specified before are overridden, as external style sheets are only allowed inside the head tag. media="handheld" tells the browser that the style rules given in the file handheld.css should only be applied when in Mobile mode.

The page itself should not contain any inline styles / style attributes, let alone style tags.

Now we have a look at the page's original markup and style specification. There are 2 style sections specified for this page,

<style type="text/css">

and

<style type="text/css" media="all">.

The former comes without a media attribute, so the default value all is used, which includes handheld. The latter style section formulates the same explicitly.

There is a minor obstacle in our way now before we are finished with our preparations. The document contains a @media screen, print { rule in the second style sheet:

… <style type="text/css" media="all"> /* START TOOLBAR */ @media screen, print { …

Anything inside that sheet will be ignored with the handheld media type, which is something we want to avoid to keep as much original style in handheld mode as possible. So we need to add handheld and write @media screen, print, handheld { instead.

Now we can start to write our handheld style. As the handheld style section is still empty, the Small-Screen preview looks identical to the Desktop view (try yourself by toggling Shift-F11 in Opera).

Style details

Now I will present the handheld style sheet, i.e. the file handheld.css. Each CSS rule is commented to clarify its purpose. As this style sheet is based on the two original style sheets, you may want to download the complete original page [ZIP file, ~111 KB] for easier understanding of why exactly a particular rule is in the handheld style sheet.

/* example handheld style for news.bbc.co.uk */ /* all rules are set with the !important property to override author !important settings */ /* -- generic part (all elements) -- */ * { /* make all elements static positioned elements, i.e. those with a normal flow of elements */ position: static !important; /* ensure each element has non-static dimensions: reset to default values */ width: auto !important; height: auto !important; min-width: 0 !important; min-height: 0 !important; max-height: none !important; max-width: 100% !important; /* limit the maximum width of each element */ } /* save space around document */ body { margin: 0 !important; padding: 0 !important; } /* -- page specific part -- */ /* make gradient vertically expandable (background of top BBC logo image) */ div#ift-toolbar { background-position: bottom !important; } /* space between elements (Top BBC image) */ div#ift-logo { margin-right: 1em !important; } /* remove background on #ift-wrap (background of top tabs, 'Home') */ .ift-news div#ift-wrap { background: none !important; } /* add background and make it floating (search box) */ div#ift-search { float: right !important; margin-left: .5em !important; /* extra space */ padding: 1px 0 6px 5px !important; /* make the content fit nicely inside the box */ background-image: url( "bbc_news_files/search_b.gif") !important; } /* move a delimiter to the right element (white line) */ .ift-news #ift-extra { border: 0 !important; } #ift-banner { border-bottom: 1px solid #fff !important; } /* paint area red to make it look as one unit (BBC News logo) */ div.o div.o + table tr { background-color: #900 !important; } /* remove disturbing backgroound image ('News front page') */ div.lhssqs { background-image: none !important; } /* break up table columns, only display them side by side if enough width is available ('News front page') */ td { display: inline-block !important; float: left !important; padding: 0 !important; } /* break up the column and let the content flow like text ('Africa') */ div.lhs div.o, div.lhs div.lhsb, div.lhs div.lhsl { display: inline-block !important; } /* don't display delimiter ('----') */ div.lhs div.lhsdl { display: none !important; } /* break up the column and let the content flow like text ('Related BBC sites') */ #lhsOtherSites li { display: inline-block !important; float: right !important; } /* start on a new line ('Languages') */ div.lang { clear: both !important; } /* make language strings visible again ('Chinese') */ ul#languages li { text-indent: 0 !important; margin: 0 .3em !important; float: right !important; } /* more space around element ('Last updated') */ span.lu { display: block !important; } span.ds { display: block !important; margin: 1em auto !important; } /* more space before certain headlines ('Other top stories') */ div.mvb { margin-top: 1em !important; } div.nlp { margin-top: 1em !important; } /* make background color fill entire line ('Features, views, analysis') */ div.nwfiller2 + table td { min-width: 100% !important; } /* more space before certain sections ('Video and audio news') */ dl.avmode { margin-top: 1em !important; } dl.avmode + div { margin-top: 2em !important; } dl.avmode dd { margin-top: 1.6em !important; } /* let articles begin at the left edge (below 'Video and audio news') */ td div.o > dl + div div.o table { clear: both !important; } /* more space before element ('Most popular stories now') */ div#nav1 { margin-top: 1em !important; } /* hide content which is intended to be invisible until made visible by JavaScript ('Most read') */ div#livestats1450 { display: none !important; } /* make background color fill entire line ('From On this day') */ td.gpromo + td { min-width: 100% !important; } ul#serviceBar { width: 100% !important; } /* trick to extend element height to contain floats ('BBC copyright notice') */ ul#serviceBar:after { display: block !important; content: "" !important; clear: both !important; } /* put content back on page ('BBC copyright notice') */ ul#serviceBar li.copyright a { text-indent: 0 !important; background-image: none !important; } ul#serviceBar li.copyright { padding-right: .5em !important; } /* left this text start in a new line ('Help') */ ul#footList { clear: both !important; margin: 0 !important; }

The generic part breaks up the static multiple-column layout and makes it a more flexible one. It can without any problem be applied to other pages as well. The page-specific part takes, with a few exceptions, care of layout and details of this particular page.

Results

With the handheld style sheet applied, the page looks as depicted below. The screen widths are 200, 320, and 480 pixels.

The handheld page at 200 pixels The handheld page at 320 pixels The handheld page at 480 pixels

So what you see is that the site grows high while it shrinks in width. Sometimes page elements are beside each other on a horizontal line, and they are on top of each other when there is not enough space in width available. The conclusion is that the width of a page is typically the constraint dictated by the device, and the height is flexible. A page layout should therefore never specify both width and height of an element, and width should always be flexible. This mandates for extensive use of max-width, as you usually don't want elements to become too wide either. The height of elements should not be constrained.

Possible improvements

So let's assume you don't write an additional style sheet as I have done above, but in fact you design a page from scratch. Then you should consider a very fluid/flexible page layout as I have done with the handheld style. However, you don't have to use media types and several style sheets when your page layout is very fluid. And finally, use markup which actually mirrors the logical blocks in the document, allowing those blocks to be scalable, and allowing them to have various position to each other.

Other possible improvements:

Conclusions

Avoid a static page layout, use a fluid and hence flexible layout instead. Here, I have exploited the power of cascading style sheets to make a static page more fluid and hence adapt it to suit various screen widths, especially small screens. This is one possibility when you have/want to build on an already existing style. If you write from scratch, I recommend using a single style sheet specifying a very variable page layout.