Horizontal Flow:
The Magic of Row-Based Design

Introduction

In the beginning, there were neither layouts nor Web Design. Tables held only rows and columns of data. Lines of text did span the screen. And #c0c0c0 was the face of the Web.

And Netscape said, "Let table cells support background colors. And let them also hold images." And lo, Web Design was born. And Microsoft saw that it was good. And Microsoft said, "let table cells also support background images." And Web Design rejoiced, and created innumerable sites with diverse and creative layouts.

It came to pass, that the W3C said, "Let there be standards. And let tables return to holding rows and columns of data. And let there be CSS so that the face of the Web need not be #c0c0c0."

But again, it was not so. Web Design cried out, saying, "Alas! If user agents could follow your decrees, I would treat table cells thus, but they cannot."

And Netscape said, "Huh?" And Microsoft said, "Duh?" And the days were dark for Web Design.

And lo, it came to pass that after the days of Netscape the Fourth were ended, Web Design sought to create layouts without tables. And lo, she did find The Holy Grail. And she rejoiced.

And the Web exploded with merchants and people of every tongue and nation. And Microsoft supplanted Netscape and lent aid to Web Design. And Firefox, Opera, Safari and Chrome appeared and gave great aid.

And it came to pass, that when all appeared well, Web Design sat by the waters of Uniformity and wept, saying, "My sites, my sites! Why look ye all alike, O my sites?"

The Fall of
the Grid

What Web Design lamented was that her new, compliant sites were all based on the column as the preeminent structure: whether two, three, or more, the vertical orientation remained the same. Once the "holy grail" of creating versatile multi-column layouts was developed, further innovations (fluid layouts, em-based layouts) generally remained tied to columnar arrangement.

This had the strange effect of making the "row" (the horizontal arrangement of items or information) completely subordinate to the column's vertical flow, whereas in table-based layouts, rows had been the foundation, holding the cells that created the effect of columns. Currently, in a large percentage of sites, the only "rows" across the page are the header, horizontal navigation (if present), and footer. The area between the header and footer often functions as a mere container for tall columns, with no horizontal flow to speak of.

This greatly compromised the power of the grid to create interesting layouts. As columns became the main devices for ordering the main content, a dreary sameness developed in many div-based sites. For example, count the columns at MSN, Yahoo, CNN, Amazon.com (all three-column layouts), the Los Angeles Times (four columns), or almost any blog (usually two or three columns).

Now columns often do make sense: for instance, in a blog or any other simple site with one kind of content, a side navigation shows itself as peripheral to the main content and concisely presents a menu of choices. However, in sites with large and varied amounts of information or selections, users may become frustrated with having to scroll up-and-down repeatedly to find what they're looking for.

Advantages
of the row

Besides the fact that rows add another dimension (literally) to layout possiblities, there are additional advantages to arranging content in rows as well as columns:

Readers use
rows intuitively

All the languages of the world are typically written on horizontal lines (including contemporary Chinese and Japanese). Hence, a horizontal flow of information feels more natural than repeated vertical scanning, and mirrors the act of reading itself. For instance, when reading tables of data, we generally look first to the row we want, and secondly scan across the cells in that row for more specific data. It's no coincidence that in HTML tables, table rows hold the cells, not the little-used col and colgroup tags.

Rows naturally
present info
hierarchically

Where are you? Look at the header, of course. What's important here? That's in the top row. What's next? That's in the next row. What's less important? Move down a row. What's just there for reference only? Check the bottom rows. Row-based designs can easily present information hierarchically, with featured information at the top and secondary information further down.

Rows fit the
screen better
than columns

The "fold" (bottom of the screen) is the bane of reading on the Web. We're all used to it, but we all know that scrolling sucks. Column-based designs can only avoid excessive scrolling by either making content pages artificially short, or by ensuring that only one column requires scrolling and that other columns have "supplemental" content only, such as ads, links, etc.

Also consider that the shape of the screen is changing. Laptop displays commonly have widescreen aspect ratios of 16:10 or 16:9, and many desktop monitors are leaving the squarish aspect ratios of 4:3 or 5:4. According to Net Applications, in December 2008 widescreen aspect ratios accounted for over 39% percent of all Web viewing, up by half from 26% just a year before. This trend will likely continue, as laptops have recently started outselling desktops, and more users are switching to widescreen displays for video and easier multitasking.

Rows are easier
to create
than columns

There are very few even-height columns on the Web, except in tables. We routinely cheat by using background colors and images to make them appear even. Less often, we use JavaScript or counter-intuitive CSS techniques to force a genuine match in height. On the other hand, rows align perfectly by nature, always expanding to the full available width. Any block element enables perfect horizontal alignment for any other blocks it contains. However, it's sometimes possible to have a visual row that is purely presentation without any corresponding HTML element.

Row-based
designs in
action

ABC's site is a prime example of the power of row-based design. After the header and navigation, the first row presents the primary featured content, the second row, some less-prominently featured content, and so on with the remaining rows down to the footer. The result is as visually pleasing as it is visually simple.

At CarMax.com, the layout very effectively uses rows to lead the reader to primary content at the top, down to supplementary material at the bottom. However, things were not always this happy at CarMax. Look at the "before" screenshots at designer Andy Rutledge's site to see how crowded and confusing it used to be. At the bottom of the page he presents his proposal for a redesign, using more graphics and hierarchical rows. It looks very much as if someone at CarMax took his advice to heart. (And not surprisingly, Rutledge's own site also exemplifies the power of the row.)

Apple's site holds a mountain of information, but has a famously simple home page to present it. And what do we see there? Rows. Even the busier interior pages such the Mac page and the Download index page use rows, subdivided into columns, to bring order to their wealth of material.

Annenberg Media combines the row with the "accordion" effect for a great no-scroll user interface.

Building rows

For a visual row to be perceived, there must be at least two items within it—items "in a row." What those items are depends wholly upon the needs of the site, whether they are images of products, snippets of articles, additional navigation, or anything else. If they are divs, they may function as columns within the row. But no matter what their nature, the problem of attractive horizontal arrangement is the chief problem of beginning to think in terms of rows. Here are a very few of many, many possible solutions.

In the following examples the basic HTML is unchanged. The central section is a single div that contains only plain paragraphs with no classes or ids, and no presentational divs or tables in the markup. All alterations to it are solely done through JavaScript with the jQuery library. For ease of reading the source code, relevant CSS is embedded in the head section; the unchanging part of the CSS is a linked file. The scripts are likewise embedded for the same reason.

Floating items
of equal-height

A classic example is an array of image thumbnails in an image gallery, but here I present paragraphs with a fixed height and "overflow: hidden." As long as all the floated elements have the same height, a simple "float: left" in the CSS will cause them to automatically align in rows, even without "row" elements in the HTML to align them.

Browser support: All major browsers.
View the demo.

Automatically
sort items of
varying height
into rows with
JavaScript
(two columns/row)

This doesn't require any sophisticated programming; with a JavaScript library, such as the jQuery I use here, only a few lines are necessary to create self-organizing rows.

	$(function() {
		$('#demoarea p:even').addClass('even');
	});

This short script assigns a class ("even") to every other paragraph in #demoarea, beginning with the first (since the first is indexed as 0). After floating the paragraphs with appropriate widths, we can simply style the "even" class with a "clear: left" to create automatic self-sorting rows with two items each.

	#demoarea p {
		width: 270px;
		padding: 10px;	
		margin:0 0 10px 10px;
		float: left;
		background: #aeb;
	}
	#demoarea p.even {
		clear: left;
		margin-left: 0;
		background: #abe;
	}

Browser support: All major browsers. JavaScript enabled.
View the demo.

Automatically
sort items of
varying height
into rows with
JavaScript
(any number of
columns/row)

Expanding this to any number of items is almost as easy. The main issue is that if the content has differing heights, Internet Explorer (surprise!) may clump items together. The solution is to group the items with divs acting as "rows". However, we still don't need to touch the HTML for this:

    $(function() {
    	$("#demoarea > p").each(function(){ 
    	var n = $('#demoarea > p').index($(this));
    		if (n % 4 == 0) {		
    		  $('p').eq(n).addClass('firstCol');
    		}
    		if (n % 4 == 1) {
    		  $('p').eq(n).addClass('secondCol');
    		}
    		if (n % 4 == 2) {
    		  $('p').eq(n).addClass('thirdCol');
    		}
    		if (n % 4 == 3) {
    		  $('p').eq(n).addClass('fourthCol');
    		}		
    	});
    	$('#demoarea p').slice(0,4).wrapAll('<div></div>');	
    	$('#demoarea p').slice(4,8).wrapAll('<div></div>');
    	$('#demoarea p').slice(8,12).wrapAll('<div></div>');
    });

The first part of the script assigns a class to each paragraph's position in the row, and we'll give a "clear: left" again to those occuring first in the row. The other classes are technically not necessary, but assigning them allows "columns" to be treated individually even though the HTML is nothing but twelve stacked paragraphs.

The second part of the script uses the slice() and wrapAll() jQuery methods to parse the location of the opening and closing div tags, creating framing rows. Note the unexpected syntax: each slice closes with an index value one higher than expected, for instance "slice(0,4)" instead of "slice(0,3)".

Nothing changes in the CSS, except for the width and adding additional colors to the new classes.

Browser support: All major browsers, JavaScript enabled.
View the demo.

Use CSS3
table display
properties
(single row)

Here we stop floating items and use one of the most useful CSS3 properties: "display: table-cell." Although table display properties are not supported by either IE6 or IE7, they are supported by IE8, and are well-implemented in all other popular browsers. The only obstacle to immediate use is IE, which can be treated with an alternate stylesheet. The advantage of using CSS table display properties is tremendous: without adding so much as a class or a div, the paragraphs are told to present themselves as if they were cells in a table, instantly aligning themselves perfectly, with just one line of CSS. This is arguably the most logical and simple method of presenting content side-by-side, and makes even our customary trickery with floats appear as hacks by comparison. Here's the CSS:

    #demoarea	{
    	width: 600px;
    	padding: 10px;
    	display: table;
    	border-collapse: separate;
    	border-spacing: 10px;
    }
    #demoarea p {
    	width: 120px;
    	padding: 10px;
    	background: #ddd;
    	display: table-cell;
    }

Strictly speaking, the "display: table" on #demoarea is not necessary for the alignment of the paragraphs into grid "cells." Due to CSS's ablity to create anonymous elements, "display: table-cell" is enough when only one "row" is concerned. However, using "display: table" on the outer element enables us to separate the paragraphs with the familiar border-collapse property and to specify the amount of space between them with border-spacing, creating attractive grid effects. Since there is no element between the div displaying as a "table" and the paragraphs displaying as "table cells," a pseudo element displaying as a "table row" is created "anonymously" in accord with the W3C specs.

Note: This talk about "tables" and layouts may sound fishy or even heretical to standards-oriented designers used to hearing about the evils of using tables for layout. The difference here is that no tables are involved at all. None are in the code, and none are generated. But the CSS table display properties allow semantic (X)HTML elements to present themselves in a table-like manner, resolving virtually all of the layout difficulities that arose when layout tables were rightly abandoned.

Browser support: Firefox, Safari, Chrome, Opera, IE8.
View the demo.

Use CSS3
table display
properties
(any number of rows)

To create multiple rows using the table-cell display property, it will be necessary to have a block element containing the set of paragraphs in each row, much as in demo3. We can use the jQuery wrap() method again, and if we don't care about assigning classes to color the cells, it can be this simple:

    $(function() {
    	$('#demoarea p').slice(0,4).wrapAll('<div></div>');	
    	$('#demoarea p').slice(4,8).wrapAll('<div></div>');
    	$('#demoarea p').slice(8,12).wrapAll('<div></div>');
    });

Note that now that there are JavaScript-generated elements between the "table" #demoarea div and the paragraphs, the "row" elements cannot be created anonymously and we need to have a "display: table-row" declaration in the CSS:

   #demoarea {
    	width: 600px;
    	padding: 10px;
    	display: table;
    	border-collapse: separate;
    	border-spacing: 10px;
    }
    #demoarea div {
    	display: table-row;
    }
    #demoarea p {
    	width: 120px;
    	padding: 10px;
    	background: #ddd;
    	display: table-cell;
    }

Browser support: Firefox, Safari, Chrome, Opera, IE8.
View the demo.

Again, these are but a few of the possibilities. Your favorite method of arranging columns will generally work for arranging anything else side-by-side as well. One particularly promising approach is the CSS3 multi-column module, designed explicitly to create newspaper-style columns, which can fit any row or container of any height. I omitted it here because no current browser supports its properties as written, without proprietary prefixes.

Conclusion:
Recovering
The power of
the grid

The horizontal factor has been too long overlooked in most modern layouts. With its ease of scanning, built-in feeling of hierarchy, and ability to be subdivided into presentational cells and columns, the row can be a key ingredient in the practical and aesthetic organization of information on a Web page.

And a voice cried out to Web Design, saying, "Fair daughter, why weepest thou?" And Web Design looked up, and beheld the face of Creativity, together with the spirits of Order, Balance, and Harmony.

And Creativity said: "Behold, all these things are yours: (X)HTML, CSS, JavaScript and its libraries. You lack nothing that you need. Go, use them wisely and with my inspiration, and bring ease of use and beauty to the Web. And Web Design smiled for the gladness in her heart, and did as Creativity commanded.