Building a layered UI

Orde Saunders' avatarUpdated: Published: by Orde Saunders

As more devices with different input methods are used to access the web we need to build our user interfaces to work with their different needs. By building a layered interface we cater for these needs and provide a strong foundation for future devices.

HTML

The foundation of any site is the structure of the HTML but, even with a mobile first approach, all too often not enough consideration is given to this aspect of the process. Using an extensible base template to is a good idea for a number of reasons but some thought should be given to how much of the site chrome (headings, footers, menus etc.) is fixed in the template.

Look at the use cases for your site, look at user journeys, look at link tracking in analytics and conduct user testing to find out how your users actually use your site. This should inform the information hierarchy for each page which will form the linear order of the content on narrow screens - with more space you can float and re-position content to form a richer and more consistent layout but on a small screen you have to have the order right in the markup.

You should pay most attention to the items you would not normally focus on: What is the minimum you can have in the header? Is your top level menu really the most important item in your information hierarchy? Do you even need to show the menus before the content on some pages?

Layout

Layout is now probably the best understood section of building device agnostic web sites thanks to Responsive Design. What often gets lost is that Responsive Design is a layout solution - it is not a device solution. It's very tempting to look at certain screen widths and label them as devices: 320 is mobile, 768 is tablet and 1024 is desktop. Screen size to device class mapping was never that really a good assumption but as more and more form factors are coming on to the market it's becoming harmful.

When it comes to building your layout you should start with a minimal, linear, stylesheet that uses the lack of media query support as the first media query as I outline in my post on progressively enhanced CSS.

Interface

As different screen sizes require different layout requirements, different interface methods require different interface requirements.

A frequent question about responsive design is what class does a tablet fall into? With a screen width of 320px it is reasonably safe to assume that the device is a mobile with a touch screen but with a screen width of 1024px the device could be a desktop, TV or tablet all of which have different interface methods (mouse, remote control, finger) which have different interface requirements.

Whilst not perfect, these can be broken down into three main classes:

Touch

The touch interface should be the baseline for the UI as it gives us the best baseline for enhancement - it is easier to build up from the UI built for touch than to adapt a more traditional pointer interface to be suitable for touch, particularly as touch devices tend to translate touch events to pointer events anyway.

Touch targets

The first key to a touch UI is targets that are easy to pick out with a finger, given the variety of device pixel densities don't get too hung up on exact physical sizes but - as ever - make sure you test on a representative sample of devices to ensure the experience is acceptable.

Hover states

The second key to a touch interface is to avoid hover states, everything should be driven from touch/ click events. Whilst many devices will trigger the hover state on a touch event it's not universal and the biggest problem with hover states comes when you overload items so they have different actions on hover and click - on touch devices the two events are indistinguishable.

Keyboard

When navigating using the keyboard the important thing to remember is that it is sequential, you move from one element to the next in a set order and you need to know where you are in the sequence when navigating.

Tabindex

By default browsers will move through focusable elements in the order in which they appear in the source but this can be overrided by use of the tabindex property. Setting an individual tab order for each element would very quickly become tedious so it's easier to use the same tab order for items within a section as the browser will move through them in source order. Similar to BASIC line numbering it's best to start in blocks of 10 to allow later expansion - as shown in the example below.

  <a href="#">Title</a>
  <ol>
    <li tabindex="10">Item 1</li>
    <li tabindex="10">Item 2</li>
    <li tabindex="10">Item 3</li>
  </ol>
  <button>Click me!</button>
  <ol>
    <li tabindex="20">Item 4</li>
    <li tabindex="20">Item 5</li>
    <li tabindex="20">Item 6</li>
  </ol>
  <a href="#">Footer</a>

Navigating this using the keyboard would start at "Item 1" (first item with a defined tabindex, lowest defined tabindex value, first item in mark up with lowest tabindex), move through "Item 2" and "Item 3" before moving on to "Item 4" (as it is the first item with the next lowest defined tabindex), it will then move through "Item 5" and "Item 6" before returning to the "Title" link (as it is the first item in the mark up that doesn't have a tabindex), the "Click me!" button and finally the "Footer" link.

Focus

When navigating sequentially it is important to give clear feedback showing the current position. This can be easily achieved with the CSS :focus pseudo-class to define a clear visual indicator such as a contrasting outline:

*:focus {
  outline: 1px solid orange;
}

The drawback of this is that it will show a highly visible outline on items when navigating using other methods which can be distracting. If we set this as the default we can enhance the experience using JavaScript.

<!DOCTYPE html>
<html>
  <head>
    <script>
// This assumes we are using a modern browser.
// You'll need to cut the mustard to use this reliably.
document.querySelector('html').classList.add('js');
    </script>
    <style>
*:focus {
  outline: 1px solid orange;
}
.js *:focus {
  outline-width: 0px;
}
.keyboard *:focus {
  outline-width: 1px;
}
    </style>
  </head>
  <body>
  <script>
var addKeyboardHook = function () {
  document.querySelector('html').classList.add('keyboard');
  document.removeEventListener('keydown', addKeyboardHook);
};
document.addEventListener('keydown', addKeyboardHook);
  </script>
  </body>
</html>

In this example we set up the obvious focus outline then use a class hook added by JavaScript to hide it. We then listen for a keydown event to add in another class hook that will make the outline visible again. This approach is heavy handed in that it takes any keydown event to re-show the outline, if you're dealing with forms where users are going to be typing you can filter the keydown to only activate the class hook for keys that will be used for navigation - such as tab and arrows.

I have used this technique on a number of projects and it has been singled out for praise by accessibility consultants during their reviews.

Pointer

The mouse pointer offers the finest level of control, down to individual pixels, and allows for a hover or mouseover state that is clearly distinct from a click or activation state. As the majority of interactions on the web have historically been mouse driven this has lead to frequent use of hover states in interfaces for a number of different tasks such as menus and tooltips. Whilst this is clearly a useful interaction to harness it is no longer possible to rely solely on this for core functionality and it should be viewed as enhancement.

Update 2015-01-14: Devices that traditionally relied on a pointer are increasingly adding touch screens which are often undetectable so the only safe assumption is that all screens are touch screens and hover states may never be triggered.

Summary

  • Start with valid semantic and accessible mark up.
  • Use responsive design for layout.
  • Build the default UI for touch and keyboard interaction.
  • Use feature detection to fine tune the UI.