Design System

This design system will include design guidelines and a living pattern library of frequently used components to help create effective and consistent interactions.

Foundations

Accessibility

We want to make our software available to as many people as possible. To do this we should comply with the Web Content Accessibility Guidelines at the AA level (at least). New features should be checked against these guidelines.

Content

Write clear and concise copy. This will especially help people with cognitive disabilities and non-native english speakers, but it’s helpful for everyone.

Provide alt text for all images and charts. The alt text should communicate the same message that’s conveyed visually. If an image is purely decoration, leave the alt tag blank (don’t just leave the element off) so screen readers don’t pick them up.

Ambiguous elements (like icons) should describe their purpose or action, not purely their appearance. It’s usually best to use visually hidden text for screen readers, but ideally the text doesn’t have to be hidden and icons are only used to enhance the text.

Layout

Use clear hierarchies. The layout should clearly distinguish the different areas of content.

Ensure the design is responsive and base decisions on your layout constraints as screen size changes rather than specific devices. There are too many screen sizes in use and they are always changing. This is also helpful for people who increase text size or zoom.

Touch targets should be 44 x 44 css pixels, with some exceptions like inline text links.

Semantic HTML

Well-structured HTML is essential to help make a website accessible. It’s not just pedantic, semantic HTML goes a long way to help assistive technologies. For example, spans, divs, and other default non-interactive elements should not be made into interactive elements because it can cause confusion for keyboard navigation and screen readers.

Here is an HTML elements reference to help you choose the best element.

Sometimes there isn’t a good HTML element to describe an element, so we can use roles. An example is using role="alert" on a div since there isn’t a better HTML element. Roles aren’t needed when there is a good HTML element to use. For example, <button> is better than <div role="button">.

CSS Framework

We use a css framework called Tachyons. It's a "functional" or "atomic" approach as opposed to others like modular/BEM. For complex situations that Tachyons can't cover, we use BEM. We mostly stick with the constraints Tachyons has defined (such as their scale for spacing and typography), but we have made some modifications (such as custom colors to offer higher contrast) and put together some custom components below.

Tachyons documentation for composing styles

Style

Colors

The main colors used are blue and gray. Blue should carry the main call to action for a view. The other colors are used mainly for search result categories and alerts.

Ensure there is sufficient color contrast between text and its background. You can use this tool to check your combinations.

Color should not be the sole means of communication. People with color blindness may not be able to differentiate some colors. Color Oracle is a good tool to avoid bad combinations. This also helps people with low or no vision.

$blue
$dark-blue
$washed-blue
$purple
$washed-purple
$red
$washed-red
$green
$washed-green
$black-60
$black-10
$gray-blue

Typograpy

Coming soon...

Iconography

We're using Font Awesome icon font for now. We may move to inline svg icons in the future. Some examples:

Avoid using icons as the sole means of communication. They are best when paired with a description. Screen readers will read the :before or :after css content: so the icon html class needs to be in its own element and hidden with ARIA. If the icon is only decorative, you can use:

Time
<span class="fas fa-clock" aria-hidden="true"></span>Time

If icon is essential and has no text equivalent, use visually hidden text that screen readers can see:

<button type="submit">
  <span class="visually-hidden">Search Records</span>
  <span aria-hidden="true" class="fas fa-search"></span>
</button>

Interaction

Keyboard Support

Make sure all tasks can be completed with a keyboard.
This includes:

Use obvious CSS focus styles. They are essential for keyboard navigation. You can reuse :hover state for :focus, and make sure it’s obvious on all elements because sometimes the default :focus is not obvious.

Focus and state change

We need to account for when views change without a page refresh. This is more common with the use of “single page” web applications such as those built in frameworks like React. If the focus is not moved to the relevant element when a view changes, this can be confusing for people using screen readers and keyboard navigation. Here is an article that addresses focus management and live messaging in React.

Forms

Every form field needs a <label>, even if it is hidden because it is part of a group like the optional second part of an address.

Use predetermined options instead of freeform choices when possible because this helps people who have difficulty writing.

Inputs need to clearly show if a specific format is required. Ideally the system can parse any input. A js helper / mask can be useful, but make sure to test with screen readers.

Validate inputs as soon as focus is left, or possibly sooner if you can be sure the input will be invalid.

Components

This is a small application, but we could consider using Tachyons-Components to abstract the styling and allow for overrides (more info). For now, we'll keep it simple and manually put the css classes in each element / component.

<a href="#" class="link underline hover-blue"> … <a href="#" class="blue link underline hover-blue"> …

Buttons

<button class="bg-blue white bg-animate hover-bg-dark-blue fw6 br2 pv3 ph4"> … <button class="bg-navy white bg-animate hover-bg-dark-blue fw6 br2 pv3 ph4"> … <button class="loading-btn bg-dark-blue white fw6 br2 pv3 ph4"> …

Input

There should almost always be a label visible for a field. Using only placeholders can cause confusion about what the field is for when there is data entered or a validation is triggered.

<label for="n" class="db mb1 fw6"> …
  <input id="n" type="text" class="pa3 br2 b--black-20"> …

Textarea

<label for="ducks" class="db mb1 fw6">What do you like about ducks?</label>
<textarea id="ducks" name="ducks" class="pa3 br2 bw1 b--black-20"></textarea>

Checkbox

What do you like?
<fieldset class="mb4">
  <legend class="fw6">What do you like?</legend>
  <div class="checkbox">
    <input id="chocolate" type="checkbox" name="likes" value="chocolate"/>
    <label for="chocolate">Chocolate</label>
    <input id="cherimoya" type="checkbox" name="likes" value="cherimoya"/>
    <label for="cherimoya">Cherimoya</label>
    <input id="cauliflower" type="checkbox" name="likes" value="cauliflower"/>
    <label for="cauliflower">Cauliflower</label>
  </div>
</fieldset>

Radio Buttons

What is your favorite radio?
<fieldset>
  <legend class="fw6">What is your favorite radio?</legend>
  <div class="radio">
    <input type="radio" name="radio-type" id="am" value="am"/>
    <label for="am">AM broadcasting</label>
    <input type="radio" name="radio-type" id="fm" value="fm"/>
    <label for="fm">FM broadcasting</label>
    <input type="radio" name="radio-type" id="ham" value="ham"/>
    <label for="ham">Ham radio</label>
  </div>
</fieldset>

Select

Generally, use a selectbox when there are more than four options, but fewer than twenty. A typeahead is usually a better choice when there are more than twenty options. Use radio buttons when there are 4 or fewer options. If there is a common default option, a selectbox may be ideal even when there are few options.

<label for="group" class="db mb2 fw6">Select Label</label>
<div class="relative">
  <select id="group" class="w-100 pa3 br2 bw1 b--black-20 input-reset bg-white black-60">
    <option value=""></option>
    <option value="option1">Option 1</option>
    <option value="option2">Option 2</option>
    <option value="option3">Option 3</option>
  </select>
  <div class="absolute pa3 right-0 top-0 bottom-0 pointer-events-none">
    <i aria-hidden="true" class="fas fa-angle-down"></i>
  </div>
</div>

Status Message

Accessible status message guidance from the WCAG

Success message
<div role="status">
  <div class="bg-washed-green fw6 br3 pa3"> …
Error message
<div role="alert">
  <div class="bg-washed-red fw6 br3 pa3"> …

Panel

Panel

The padding in the panel may vary, but give content room to breate on larger screens, and you will likely need to need to decrease it on smaller screens.

Use the line height classes to control the line-height of your headlines and body copy. Use the measure classes to keep the line-length of text between 45–75 characters.

<section class="bg-white shadow br3 pa3 pa4-ns cf"> …
  <p class="lh-copy measure"> …