Chapter 6. Dealing with state

The majority of web applications need to deal with states.

First let's just crystallise what we mean by 'states'. Consider some examples:

All these eventualities require state changes to be communicated in the DOM, so that any styles changes necessary can be applied in the front-end of the application too.

The web application itself, rarely actually requires any changes to the DOM to keep track of state. Client-side JavaScript applications for example, usually have internal means of dealing with state and tracking it. Therefore, until now, making changes to the DOM has been purely to affect aesthetic change via CSS (styling purposes).

How ECSS used to handle state change

Back in Chapter 3, I related how much I liked the SMACSS approach of communicating state. For example:

.has-MiniCartActive {}

Indicates that on, or somewhere below this node, the 'Mini Cart' is active.

Another example:

.is-ShowingValue {}

This would communicate that the Component or one within it is showing some value (that was previously hidden).

Historically, that was how I communicated state when applying ECSS. I used a micro-namespaced class, in addition to any existing classes on the node to communicate this state. For example:

A node using these classes in the DOM might look like this:

<button class="co-Button is-Selected">Old Skool Button</button>

Switching to WAI-ARIA

However, if this information has to go in the DOM purely for styling hooks, it may as well lift a little more weight while it's there.

These same styling hooks can actually be placed in the DOM as WAI-ARIA states. The States and Properties section of WAI-ARIA describes the W3C's standardised manner in which to communicate states and properties to assistive technology within an application. In the opening section of the abstract description for WAI-ARIA, it contains this:

These semantics are designed to allow an author to properly convey user interface behaviors (sic) and structural information to assistive technologies in document-level markup

While the specification is aimed at helping communicate state and properties to users with disability (via assistive technology) it serves the need of a web application project architecture beautifully. Adopting this approach results in what is (perhaps cringingly) referred to as a 'Win Win' situation. We get to improve the accessibility of our web application, while also gaining a clearly defined, well considered lexicon for communicating the states we need in our application logic. Here's the prior example re-written with aria to communicate state:

<button class="co-Button" aria-selected="true">Old Skool Button</button>

Class handles the aesthetics of the button. The aria-* attribute communicates the state (if any) of that node or its descendants.

In JavaScript application land, the only change needed is shifting from classList amendments for state changes to setAttribute amendments. For example, to set our button attribute:

button.setAttribute("aria-selected", "true");

ARIA attributes as CSS selectors

In our preferred CSS syntax, writing that change within a single set of braces would look like this:

.co-Button {
    background-color: $color-button-passive;
    &[aria-selected="true"] {
        background-color: $color-button-selected;
    }
}

We use the ampersand (&) as a parent selector and the attribute selector to leverage the enhanced specificity having the aria attribute on the node provides. Then we can just style the changes as needed.

States and properties, redone with ARIA

Section 6.5.1. of the WAI-ARIA specification describes 'Widget Attributes', these contain many of the common states needed when working with a web application and rapidly changing data.

Here are the examples given at the beginning of this chapter re-written using ARIA:

There are plenty more and the specification is, by W3C specification standards, easy to understand.

If ARIA can't be used

If, for whatever reason, you aren't able to use aria-* attributes to communicate state in a site or application. I now tend to lean towards naming selectors without using the micro-namespace to designate state. For example, instead of:

I would instead recommend using a variant version of the selector like this:

<button class="co-Button co-Button-selected">Old Skool Button</button>

This keeps the context of the module in tact and merely indicates a variant of this same class is being applied.

Summary

Using WAI-ARIA states to communicate changes in the DOM provides styling hooks that are as useful and easy to use as HTML classes. Although purely preference, I'm also a fan of the fact that an entirely different selector is used to communicate state in the style sheets; it is simpler to spot within a rule.

None of those prior factors really get you anything new. What using WAI-ARIA states will do, virtually for free, is start to provide a better means of communicating your web applications state to users of assistive technology. If money talks, consider also that by using WAI-ARIA you are widening your product up to a greater number of users (see the additional info below).

As such, using WAI-ARIA states and properties, is the recommended means of communicating state in projects adopting a ECSS methodology.