Brandon Rosage

Jan 4, 2012

Deliver content-first HTML without sacrificing a navigation-first layout

One of the best design patterns, in my opinion, to come from the past four years of user interface design on mobile devices is the shift toward displaying content first and navigation second. Having so much less screen real estate than on the desktop has been fantastic for interfaces designed for reading and consuming; though it’s brought tremendous focus to utility apps, too.

But if it’s important in the design of your web product to build a responsive website that doesn’t rely on alternative URLs or subdomains to serve up an entirely new interface, it can be challenging to offer intuitive navigation to desktop users (where it’s displayed at the top of the page) while pushing that navigation to the bottom of the screen for small-screen users.

The brilliant speakers at this summer’s An Event Apart tour, like Luke Wroblewski, Jeremy Keith, Jeffrey Zeldman and Eric Meyer, synthesized some terrific approaches to this problem using nothing but CSS. No browser sniffing, no server-side code.

Smart semantic HTML is, again, rewarded.

There are a few approaches with CSS that address the need to re-order sibling elements. As I tackled this issue in Ushahidi’s SwiftRiver and Crowdmap user interfaces, I begrudgingly settled on the more bulletproof CSS 2.1 solution, ignoring a more elegant CSS3-only solution.

CSS3’s smart solution

Let’s assume I have two primary elements in my document’s body: Content and navigation. My HTML might look like this:

<body>
<div class="content">
<p>My content.</p>
</div>
<nav>
<ul>
<li>Navigation item 1</li>
<li>Navigation item 1</li>
</ul>
</nav>
</body>

By writing our markup first for small-screen devices, we don’t need to do anything out of the ordinary with our CSS here. Content will display first and our navigation will be available after that.

But for larger screens, where we want navigation to appear first, we could target the larger viewport with a CSS media query and insert the following CSS3 properties to reverse their display order:

@media screen and (min-width: 615px) {
    body {
        display: box;
        box-orient: vertical;
        box-direction: reverse;
    }
}

An old school, better-supported solution

The method I used on the control panels for Ushahidi Core and Crowdmap isn’t as intuitive as CSS3’s “box-” properties. But more browsers support it.

Assume the same HTML markup and media query, but leverage different display values and the caption-side property:

@media screen and (min-width: 615px) {
    body {
        display: table;
        caption-side: top;
    }
    nav {
        display: table-caption;
    }
}

The problem this solved on Crowdmap and Ushahidi Core was the need to:

  • Write HTML markup that listed a report’s full story and comments before its metadata (e.g. date, categories).
  • Display a report’s metadata before its full story and comments on large screens.

Crowdmap’s control panel displaying a report’s full story and comments first on a small-screen device

Crowdmap report on iPhone

Crowdmap’s control panel displaying a report’s metadata before its full story and comments on a large-screen device

Crowdmap report on desktop

Jeremy Keith put together a great write-up on these methods, as well as some use cases for leveraging the same CSS properties to display the elements horizontally.

So simple. So powerful.