Hubert Wang

I am
Hubert Wang

Wechat Official Account
Find fun things here!

Inclusive Front-End Design Patterns - Reading Notes

We might not realize it, but as developers, we build inaccessible websites all the time. It’s not for the lack of care or talent though — it’s a matter of doing things the wrong way. In this book, we explore how we can craft accessible interfaces without extra effort — and what front-end design patterns can be used to create inclusive experiences.

The following contents are digested from Heydon Pickering's book: Inclusive Design Patterns.


In any case, thinking about the structure of data and trying to arrive at an optimal solution is designing and there’s not an Adobe license or copy of Sketch in sight. In fact, it’s really a kind of inclusive design: here, the right solution is one which is inclusive of different kinds of addresses. We’d like to be able to deal with consistent, uniform addresses, but that’s not reality. Instead, we make allowances.

Replace “structure of data” with “interface” and swap “addresses” for “people” in the previous paragraph, and you’ve got inclusive interface design in a nutshell.

For example, to design a button on web: The graphic designer has no idea of how to put that button on a web page or to make it do anything. The designer who codes will set background image to div element and use JS to control the click event. What's wrong with these two methods?

  1. Users who zoom their web pages to ease reading will get degraded and blurry button.
  2. Users who switch off image loading in mobile browser for bandwidth saving will not see the button.
  3. Users who choose to navigate and operate web pages with a keyboard cannot focus or operate on <div> element, unlike the purpose-built <button> element.
  4. Users who have severe vision impairments hence using a syntheic voice aids their comprehension are left entirely bereft.
  5. <div> element is semantically inert, offering noo information non-visually that it is, indeed, a button.
  6. A button with information in a background image is unavailable to assistive technologies, eg. untranslatable into different languages.

The inclusive designer anticipates these problems, because experience tells them that people differ, well, in lots of different ways. Far from being daunted or frustrated, they know that by exploiting standard conventions they can achieve more by doing less. In other words, they know when to design and when to employ what is already designed — a simple HTML button element, provided as standard by the HTML specification. Resizable, translatable, focusable, interoperable, stylable, restylable, maintainable, mutable, simple.



There are a handful of document-level best practices we should stick to. The aim here is not to go in search of the ultimate boilerplate but to configure a parent web page for an inclusive interface.

The Doctype

Whether your web page is an old-school static resource or a single-page app, it is unavoidably a document. The clue is in the “DOC” part which should appear in the first line of code: <!DOCTYPE html>.

Without a doctype declared, the browser simply doesn’t know how to interpret the content and can regress into a non-compliant and incompatible mode, often called quirks mode.

The lang Attribute

The <html> element’s lang attribute tells browser which language it is written in. <html lang="en" <!-- language set to English -->

It also helps browsers choose and render system fonts with the appropriate character sets. Eg. lang="zh-Hans" will invoke the rendering of simplified Chinese font.

It is possible to switch languages within a page using the lang attribute on child elements within the <body>. Eg.:

<blockquote lang="fr">
    <p>Ceci n’est pas une pipe</p>
    <p><cite>René Magritte</cite></p>

In CSS, selecting any sections declared as French using the :lang pseudo-class, applying a font well suited to the French character set, thereby improving legibility:

:lang(fr) {
    font-family: French Font, fallback, sans-serif;

Responsive Design

Allow pinch-to-zoom with viewport in <meta> tag.

<!-- dont use this -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">

<!-- use this -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">

The reason of allowing pinch-to-zoom can be found in Adrian Roselli's Don't Disable Zoom

When zoom is enabled, avoid using positioned elements, especially with position: fixed. When content is enlarged, any element stuck to a certain area is liable to become blind spots.

Font Size

It's true that a great number of users will operate full-page zoom using Cmd (or Ctrl) and +, but modern browsers and operating systems still support text-only resizing. To make sure font-size, padding and margin all resize proportionately, each should be set using the relative units rem, em or ch. (Commented by Hubert: Kind of disagree with this, cause setting margin and padding by rem, em, or ch will make page layout hard to controll. Imagine that when margin, padding, and font-size all enlarged, the box will become thin, making the whole layout crash.)

Media query and setting font-size by percentage are the convention of making page responsive:

p {
    margin: 1.5rem 0;
    font-size: 1rem;
    line-height: 1.5;

@media (max-width: 60em) {
    html {
        font-size: 80%;

Be careful when you want to ensure the media query triggers at the correct point relative to user-defined font size: the rem unit causes problem in Safari, as PX, EM or REM Media Queries? by Zell Liew.

Progressive Enhancement

Patterns in this book are founded on well-formed and semantic HTML structures, enhanced by CSS and JavaScript. Where possible, integrated JavaScript widgets degrade into well-structured static content or interactive form elements, meaning users without JavaScript or CSS — temporarily or otherwise — can traverse and use content.

In a progressively enhanced setup, scripts should be inserted at the end of the document, just before the closing </body> tag. This allows the main DOM content to be rendered before the scripts are executed.

Managing Web Font Assets

Web fonts are typically large assets which should be treated as an enhancement. In particular, FOIT (flash of invisible text) should be avoided: if the font resource is indefinitely stalled (it happens!), users of some devices and browsers will be stuck with a page that has no visible text. That’s pretty uninclusive of users on temperamental networks.

The trick is to load the page then the font, using the onload event as a watershed. For this to work, the fonts will have to be base64-encoded and embedded into the style sheet in question. In Keith Clark’s example, <link> has an onload handler which switches the media type from none to all. If JavaScript is entirely unavailable, the CSS is loaded regardless using <noscript>.

<link rel="stylesheet" href="fonts.css" media="none" onload="if(media!='all')media='all'">
<noscript><link rel="stylesheet" href="fonts.css"></noscript>

The base64-encoded font would be included inside an @font-face declaration block:

@font-face {
    font-family: Merriweather;
    font-style: normal;
    font-weight: 400;
    src: local('Merriweather'), url('data:application/x-font-woff;charset=utf-8;base64...');

A more comprehensive way of overcoming FOIT is offered by Bram Stein7 and requires a small JavaScript dependency. Font Face Observer allows you to watch and wait on the completion of a font resource loading using a simple promise-based interface:

var observer = new FontFaceObserver('MyWebSerif');

observer.check().then(function() {
    document.documentElement.className += "fonts-loaded";

It’s simple to then supply the font in your CSS, using the .fonts-loaded class selector shown above:

html {
    /* system font with fallback */
    font-family: MySystemSerif, serif;

html.fonts-loaded {
    /* web font with fallbacks */
    font-family: MyWebSerif, MySystemSerif, serif;

In defeating FOIT, you have to accept a lesser evil called FOUT (flash of unstyled text). This is a rather unjust moniker since all fonts are styled and intrinsically larger or smaller than the other, causing lines to wrap in different places.

The best strategy to mitigate this is to set fallback fonts which are similar to the web font.

Subsetting Fonts

When including fonts using Google Fonts8, you can append a text parameter to the URI listing just the characters you need.

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

If you are serving your own fonts, you can first subset them using Font Squirrel’s generator, then set fallback fonts in case of character not supported.

body {
    font-family: SubsettedWebFont, ExtensiveSystemFont, sans-serif;

The <main> Element

Some parts of web pages, like navigation regions, should appear consistently between pages of the sites. Others will contribute to the modular, often dynamic content that makes up unique pages. In conventional web page anatomy, this content is designated to a main content area.

<main id="main">
    <!-- this page’s unique content -->

The concept of main content is not a new one, but it is only recently that we’ve been afforded a tool to inclusively separate it from surrounding page apparatus like headers, navigation regions and footers. The <main> element defines a region recognized and communicated by screen readers. (Commented by Hubert: such as the reading mode of Safari browser on iPhone.)

Since <main> is designed to contain the salient content of a page, it can make the writing of a print style sheet easier. If your navigation, header, footer and sidebar (<aside>) regions are correctly made the siblings of <main>, you can target them quite easily with CSS:

@media print {
    body > *:not(main) {
        display: none;

Skip Links

A skip link appears above all other content on the page and points to the main content area. But who’s it for? Conventional wisdom says screen reader users but, as I’ve already covered, they have other means to reach the <main> element. The principal beneficiaries of skip links are sighted keyboard users.

[href="#main"] {
    position: absolute;
    top: 0;
    right: 100%; /* moves off screen */

[href="#main"]:focus {
    right: auto;

Putting The Page Together

<!DOCTYPE html>
<!-- the main language of the page declared -->
<html lang="en">
        <meta charset="utf-8">

        <!-- a viewport declaration which does not disable zooming -->
        <meta name="viewport" content="width=device-width, initial-scale=1.0">

        <!-- a non-blocking base64 encoded font resource -->
        <link rel="stylesheet" href="fonts.css" media="none" onload="if(media!='all')media='all'">
        <noscript><link rel="stylesheet" href="fonts.css"></noscript>

        <!-- a non-blocking stylesheet -->
        <link rel="stylesheet" href="main.css" media="none" onload="if(media!='all')media='all'">
        <noscript><link rel="stylesheet" href="main.css"></noscript>

        <!-- a descriptive label for the page -->
        <title>Inclusive Design Template | Heydon’s Site</title>
        <!-- a handy skip link for keyboard users -->
        <a href="#main">skip to main content</a>

        <!-- logo / page navigation etc. goes here -->

        <main id="main">
            <!-- unique content of page goes here -->

        <!-- a non-blocking javascript resource -->
        <script src="scripts.js"></script>


The Typeface

One well-supported claim is that sans serif fonts are more readable than serif ones. Nonetheless, it is entirely possible to design an excruciatingly unreadable font which is technically sans serif. As Typefaces for dyslexia states, the r and n in Arial are so close that “modern” could be read as “modem”.

By choosing a typeface that we feel the average user could read, we’d be consciously alienating a section of our users. As the excellent article “Designing for the extremes” points out, designing first for users in extreme situations helps us better serve everyone.

However, it’s important not to think about extreme cases in isolation and to target specific groups. In an experimental study carried out in Spain which investigated the readability of different fonts to dyslexic people, a typeface designed specifically for dyslexic readers performed very poorly.


MEASURE: A paragraph with 60rem wide is nicely within the range for comfort, as in Robert Bringhurst’s book The Elements of Typographic Style, he recommends a measure between 45 and 75 characters.

main {
    max-width: 60rem;

JUSTIFICATION: For good readability without JavaScript dependencies and their attendant performance issues, the default text-align value of left is preferable. This results in a ragged right-hand side to your paragraphs, but users won’t care.

LEADING(LINE-HEIGHT): Leading relates to the height of individual lines. It is the vertical measure between one line’s baseline and the next. In the W3C’s WCAG 2.0 accessibility guideline 1.4.8 Visual Presentation10, it is recommended that a generous “space-and-a-half” of leading is applied to paragraphs.

p {
    font-size: 1rem;
    line-height: 1.5;

CONTRAST: What’s less known is that very high contrast can actually diminish readability for some users. Sufferers of scotopic sensitivity syndrome (or Irlen syndrome) are sensitive to glare, and stark contrast can result in blurred text or text that appears to move around. It is advisable to slightly temper the contrast between your paragraph text and background color.

main {
    background: #eee;
p {
    color: #222;
Write a Comment
  • Wonderful beat ! I would like to apprentice while you amend your website, how could i subscribe for a weblog site? The account aided me a appropriate deal. I were tiny bit familiar of this your broadcast provided shiny transparent concept bddbcbkkeedffgda

    • H.Y.Wang reply

      @Smithf250 Hi Smithf250, Thank you for your comment! I'm happy that you like the post. I'm using Feedly to subscribe weblog and keep updated: