Reading List
The most recent articles from a list of feeds I subscribe to.
How accessibility trees inform assistive tech
The web is accessible by default. It was designed with features to make accessibility possible, and these have been part of the platform pretty much from the beginning. In recent times, inspectable accessibility trees have made it easier to see how things work in practice. In this post we’ll look at how “good” client-side code (HTML, CSS and JavaScript) improves the experience of users of assistive technologies, and how we can use accessibility trees to help verify our work on the user experience.
People browse differently
Assistive Technology (AT) is the umbrella term for tools that help people operate a computer in the way that suits them. Braille displays, for instance, let blind users understand what’s on their screen by conveying that information in braille format in real time. VoiceOver, a utility for Mac and iOS, converts text into speech, so that people can listen to an interface. Dragon NaturallySpeaking is a tool that lets people operate an interface by talking into a microphone.
A refreshable Braille display (Photo: Sebastien.delorme)
The idea that people can use the web in the way that works best for them is a fundamental design principle of the platform. When the web was invented to let scientists exchange documents, those scientists already had a wide variety of systems. Now, in 2019, systems vary even more. We use browsers on everything from watches to phones, tablets to TVs. There is a perennial need for web pages that are resilient and allow for user choice. These values of resilience and flexibility have always been core to our work.
AT draws on these fundamentals. Most assistive technologies need to know what happens on a user’s screen. They all must understand the user interface, so that they can convey it to the user in a way that makes sense. Many years ago, assistive technologies relied on OCR (optical character recognition) techniques to figure what was on the screen. Later they consumed markup directly from the browser. On modern operating systems the software is more advanced: accessibility APIs that are built into the platform provide guidance.
How front-end code helps
Platform-specific Accessibility APIs are slightly different depending on the platform. Generally, they know about the things that are platform-specific: the Start Menu in Windows, the Dock on the Mac, the Favorites menu in Firefox… even the address bar in Firefox. But when we use the address bar to access a website, the screen displays information that it probably has never displayed before, let alone for AT users. How can Accessibility APIs tell AT about information on websites? Well, this is where the right client-side HTML, CSS and JavaScript can help.
Whether we write plain HTML, JSX or Jinja, when someone accesses our site, the browser ultimately receives markup as the start for any interface. It turns that markup into an internal representation, called the DOM tree. The DOM tree contains objects for everything we had in our markup. In some cases, browsers also create an accessibility tree, based on the DOM tree, as a tool to better understand the needs and experiences of assistive technology users. The accessibility tree informs platform-specific Accessibility APIs, which then inform Assistive Technologies. So ultimately, our client-side code impacts the experience of assistive technology users.
HTML
With HTML, we can be specific about what things are in the page. We can define what’s what, or, in technical terms, provide semantics. For example, we can define something as a:
- checkbox or a radio button
- table of structured data
- list, ordered or unordered, or a list of definitions
- navigation or a footer area
CSS
Stylesheets can also impact the accessibility tree: layout and visibility of elements are sometimes taken into account. Elements that are set to display: none
or visibility: hidden
are taken out of the accessibility tree completely. Setting display to table
/table-cell
can also impact semantics, as Adrian Roselli explains in Tables, CSS display properties and ARIA.
If your site dynamically changes generated content in CSS (::before
and ::after
), this can also appear or disappear in accessibility trees.
And then, there are properties that can make visual layout differ from DOM order, for example order
in grid and flex items, and auto-flow: dense
in Grid Layout. When visual order is different from DOM order, it is likely also going to be different from accessibility tree order. This may confuse AT users. The Flexbox spec is quite clear: the CSS order property is “for visual, not logical reordering”.
JavaScript
JavaScript lets us change the state of our components. This is often relevant for accessibility, for instance, we can determine:
- Is the menu expanded or collapsed?
- Was the checkbox checked or not?
- Is the email address field valid or invalid?
Note that accessibility tree implementations can vary, creating discrepancies between browsers. For instance, missing values are computed to null
in some browsers, ''
(empty string) in others. Differing implementations are one of many reasons plans to develop a standard are in the works.
What’s in an accessibility tree?
Accessibility trees contain accessibility-related meta information for most of our HTML elements. The elements involved determine what that means, so we’ll look at some examples.
Generally, there are four things in an accessibility tree object:
- name: how can we refer to this thing? For instance, a link with the text ‘Read more’ will have ‘Read more’ as its name (more on how names are computed in the Accessible Name and Description Computation spec)
- description: how do we describe this element, if we want to add anything to the name? The description of a table could explain what kind of info that table offers.
- role: what kind of thing is it? For example, is it a button, a nav bar or a list of items?
- state: if any, does it have state? Think checked/unchecked for checkboxes, or collapsed/expanded for the
<summary>
element
Additionally, the accessibility tree often contains information on what can be done with an element: a link can be followed, a text input can be typed into, that kind of thing.
Inspecting the accessibility tree in Firefox
All major browsers provide ways to inspect the accessibility tree, so that we can figure out what an element’s name has computed to, or what role it has, according to the browser. For some context on how this works in Firefox, see Introducing the Accessibility Inspector in the Firefox Developer Tools by Marco Zehe.
Here’s how it works in Firefox:
- In Settings, under Default Developer Tools, ensure that the checkbox “Accessibility” is checked
- You should now see the Accessibility tab
- In the Accessibility tab, you’ll find the accessibility tree with all its objects
Other browsers
In Chrome, the Accessibility Tree information lives together with the DOM inspector and can be found under the ‘Accessibility’ tab. In Safari, it is in the Node tab in the panel next to the DOM tree, together with DOM properties.
An example
Let’s say we have a form where people can pick their favourite fruit:
<form action="">
<fieldset>
<legend>Pick a fruit </legend>
<label><input type="radio" name="fruit"> Apple</label>
<label><input type="radio" name="fruit"> Orange</label>
<label><input type="radio" name="fruit"> Banana</label>
</fieldset>
</form>
In Firefox, this creates a number of objects, including:
- An object with a role of grouping, named Pick a fruit
- Three objects with roles of label, named Apple, Orange and Banana, with action Click, and these states: selectable text, opaque, enabled, sensitive
- An object with role of radiobutton, named Apple, with action of Select and these states: focusable, checkable, opaque, enabled, sensitive
And so on. When we select ‘Apple’, checked is added to its list of states.
Note that each thing expressed in the markup gets reflected in a useful way. Because we added a legend
to the group of radio buttons, it is exposed with a name of ‘Pick a fruit’. Because we used inputs with a type of radio, they are exposed as such and have relevant states.
As mentioned earlier, we don’t just influence this through markup. CSS and JavaScript can also affect it.
With the following CSS, we would effectively take the name out of the accessibility tree, leaving the fieldset
unnamed:
legend { display: none; /* removes item from accessibility tree */ }
This is true in at least some browsers. When I tried it in Firefox, its heuristics still managed to compute the name to ‘Pick a fruit’, in Chrome and Safari it was left out completely. What this means, in terms of real humans: they would have no information as to what to do with Apple, Orange and Banana.
As mentioned earlier, we can also influence the accessibility tree with JavaScript. Here is one example:
const inputApple = document.querySelector('input[radio]');
inputApple.checked = true; // alters state of this input, also in accessibility tree
Anything you do to manipulate DOM elements, directly through DOM scripting or with your framework of choice, will update the accessibility tree.
Conclusion
To provide a great experience to users, assistive technologies present our web pages differently from how we may have intended them. Yet, what they present is based directly on the content and semantic structure that we provide. As designers and developers, we can ensure that assistive technologies understand our pages well writing good HTML, CSS and JavaScript. Inspectable accessibility trees help us verify directly in the browser if our names, roles and state make sense.
Originally posted as How accessibility trees inform assistive tech on Hidde's blog.
CSS Day 2019: some things I learned
Last week I joined over 400 web nerds at CSS Day 2019, which took place once again in the lovely Compagnietheater in Amsterdam. These are some of the things I learned.
The badges were beautiful and there were smoothies (scroll-behavior: smoothie
)! Speakers from left to right: Natalya Shelburne, Rachel Andrew, Tab Atkins, Heydon Pickering. Photos on the right by Joyce Goverde, the event’s awesome photographer
When I attended the first installment of the conference, I had not expected that there would be more. I mean, there’s only so much you can say about CSS. Of course I was wrong and more happened… every year. Last week was the 7th (!). The 2019 edition was not, as tweets may have suggested, a day for bashing JavaScript or the people who write it. Apart from the occasional tongue in cheek comment on people’s motivations to pick React (React?), this conference was full of interesting tidbits on what CSS can do now, how it is being developed (in specs and in browsers) and how we can, as CSS developers, be effective team members, able to sell CSS as the serious language that it is. With all due respect for our colleagues who write JavaScript (I and many others do both, too).
Note, I missed the first talk (the good thing about a conference nearby is: can do some daughter time in the morning). Luckily Rachel Andrew’s video and Rachel’s slides are already online, I just watched the video and it is very, very good. One great point she makes in it is that we should stop talking about CSS as if it is a hack, because if we do we reinforce the idea that CSS is weird, quirky and a series of hacks. She said this in the context of using auto
margins for alignment, which she said is simply using CSS as it is specced, not a hack.
What CSS can do now
Something you might not think about daily: when should lines break? Florian Rivoal showed how whitespace between words works on the web, and what some of the challenges are in deciding when to break a line to the next (Florian’s slides, Florian’s video). This is specifically interesting within tables, as a cell that contains a long line of content increases the whole table’s size, unless the line breaks. The same happens in Grid Layout cells, by the way. Breaking is defined in Unicode, annex 14, you can automate with auto hyphens (always set a lang
and star the Chromium bug to express interest in support) or manually influence with <wbr>
or a soft hyphen character.
Steve Schoger showed tips and tricks to make websites look better (Steve’s video). No actual CSS was shown, but it was interesting to see how small visual changes can make a big difference. Think about how to choose the right colors, create visual hierarchy and design good tables. A great tip regarding tables was: they don’t have to represent your database structure: often you can show less columns by combining or omitting some information, and make the core information easier to find. It was good to see that in many of his tips, Steve also took accessibility into account.
Heydon Pickering introduced how smart CSS can let flexbox layouts resize between linear one column things and multiple columns, without that weird in between state where the last item takes double space and therefore looks more important, and, importantly, with no media queries (Heydon’s video). They depend on window width, which is not helpful in a world where components can exist in all sorts of containers. His solution is aptly (?) named the holy albatross, and in his talk he revealed a project called Every Layout where that technique and others will be made available as custom elements, built together with Andy Bell.
How it is being developed
Line boxes have existed for ages in CSS, Elika J. Etemad a.k.a. fantasai explained, they ensure content does not overlap (fantasai’s video). But, non-overlapping content could mean a less ideal vertical rhythm, and this annoys typographers working with CSS. The definition of ‘fits within linebox’ may need to be redefined, Elika explained, there may be a switch between this old and new model for how lines are sized. What if you have a graphic or heading on a page that is not as tall as exactly X amount of lines? That would interrupt the vertical rhythm. To deal with that, CSS might get a block-step-size
property that could insert extra space above and/or below that graphic, to fill the gap between the space the graphic needs and the space the vertical rhythm offers. You would even be able to choose whether to add it as margin or padding (with block-step-insert
), and where to align it (block-step-align: auto | center | start | end
). This is all defined in CSS Rhythmic Sizing, currently open for feedback. Elika also went into linebox trimming with leading-trim-over
/leading-trim-under
, which gives better control over leading in the top and bottom of a text, to allow for alignment without magic numbers (see #3240). Interestingly, for this to work, it’s not just CSS, but also font foundries, who need to add the required metrics. Font metrics are also important for baselines (in future CSS you can set a dominant baseline with dominant-baseline
(TIL there are multiple baselines)) and drop caps. For all of these things, languages beyond English (including CJK: Chinese-Japanese-Korean), are very much taken into account by spec writers, because the web is for everyone.
Manuel Rego Casasnovas showed how CSS is developed as features inside browsers: what the steps are to follow, what kind of actual C++ code goes where in the code base and how features go from existing behind flags to stable browser features that will forever exist because backwards compatibility (Manuel’s video). One of the many interesting things I learned in this talk is that it takes hours to compile a browser.
If we had grid-skip-areas
, we could choose to autoplace grid items in all areas, except some. Then we could create the word CSS out of a grid.
Being a CSS developer
It is unlikely for a question to attract as many trolls online as: ‘is CSS a programming language?’ Lara Schenck decided to do the research and shared her results with us in a talk that was excellent in so many ways (Lara’s slides, Lara’s video). CSS fits right into one of the programming paradigms, domain-specific declarative programming languages, Lara explained. There are lots of criteria sceptics could come up with, like that programming languages should be Turing complete, suitable to write algorithms in and ‘have consequences’. She addressed these brilliantly in a sort of Socratic dialogue. Yes, you can replicate rule 110 in CSS with :checked
and :not()
, ok and a user and HTML, you can (and probably should) write CSS algorithms that are groups of declarations to produce a specific output, and yes, CSS has consequences, that can be addressed with programming methodologies. A great serious note she ended with is that a consequence of labeling CSS as “not programming” is that it renders companies unable to hire people who are good at CSS. People see it as not a skill worthy, and this is a problem, because without good CSS developers, companies lose out on well-built front-ends. To add a data point: I see this phenomenon almost everywhere I work (sadly).
Lara’s Turing machine
Natalya Shelburne talked about the mindset of people who write CSS and how it combines different mental models (Natalya’s talk). She talked how CSS developers can bridge the gap between designers and the actual application’s you’re working on. One tool that helps is design systems: it can bridge domains, enforce shared vocabularies. Another cool thing she showed was a special ribbon like menu that she deploys just on staging. It has tools to help designers understand grids and, amazingly, the boxes that exist in the CSS reality, as compared to the boxes that are in the designer’s software. What an awesome way to collaborate! Natalya also discussed technological barriers: by moving a lot of our code into React components that are written in a way that’s mostly optimised for reading the JavaScript that exists around it, highers the bar for pure CSS people to contribute. She suggested having a pure HTML/CSS version to allow designers to contribute. Rather than thinking about or sticking to certain technologies, we should think about how to enable people, Natalya said. She celebrated that there are lots of people in the web community doing great work in this space.
Wrapping up
It was really good to see some new CSS that is coming up (seriously. watch fantasai’s video) and learn about how to use existing CSS. Another recurring theme throughout the day was: as a community of CSS people, we should demand this language we love to be taken much more seriously. If not for our own sanity and valuation, then for the companies we are writing CSS code for. I urge you to watch Lara’s video and Natalya’s talk.
One call to action that a couple of speakers mentioned in talks and in the hallways: please have a say in how CSS develops, all discussions happen on GitHub, everyone should feel free to comment. Blogging about things you’d like to see or use is also encouraged.
The CSS Day organisers have once again set the bar very high for the next edition, let’s hope there will be another one in 2020!
Originally posted as CSS Day 2019: some things I learned on Hidde's blog.
Indicating focus to improve accessibility
It’s a common, but fairly easy-to-fix accessibility issue: lack of indicating focus. In this post I will explain what we mean by focus and show you how focus outlines make your site easier to use.
What is focus?
Focus indicators make the difference between day and night for people who rely on them. Let’s first look at what they are, and which people find them useful.
Focus is something that happens between the interactive elements on a page. That’s the first thing you should know. (See the focusable elements compatibility table for a more detailed and nuanced definition.) Interactive elements are elements like links, buttons and form fields: things that users can interact with.
On a page, at any given time, there is one element that has focus. If you’ve just loaded a page, it is probably the document, but once you start to click or tab, it will be one of the aforementioned interactive elements. The currently focused element can be found with document.activeElement
.
By default, browsers convey which element currently has focus by drawing an outline around that element. The defaults vary between browsers and platform. With CSS, you can override these defaults, which we’ll get to in a bit.
Who benefits
Focus outlines help users figure out where they are on a page. They show which form field is currently filled in, or which button is about to be pressed. People who use a mouse, might use their cursor for this, but not everyone uses a mouse. For instance, there are many keyboard users: a person with a baby on one arm, people with chronic diseases that prevent the use of a mouse, and of course… developers and other power users. .
Beyond keyboards, there are other tools and input devices that rely on clearly indicated focus, like switches. Focus indication also helps people who have limited attention spans or issues with short term memory, for example if they are filling out a lengthy form.
If the idea of indicating the current element in a website seems weird, consider TV interfaces. Most people use them with a remote control or game controller, and therefore rely on the interface to convey what’s currently selected.
Never remove them
Not everyone likes how focus outlines look, some find them ugly. But then that’s the case with street lights, too. They are unlikely to win design awards, but if you have to walk home in the dark, you are glad they help you see where you are.
Removing focus styles, as some websites do, is as detrimental for keyboard users as removing the mouse cursor would be for mouse users.
Nobody would override the browser’s default cursor, effectively removing the cursor altogether:
body {
cursor: none; /* you wouldn't do this */
}
So we shouldn’t do this either, which removes the browser’s default outline:
:focus {
outline: none; /* so, please don't do this */
}
Or, as Laura Carvajal put it at Fronteers 2018:
Even if you provide an alternative with something like box-shadow
, best set outline
to solid transparent
, because box-shadow
does not play well with high contrast modes.
Good focus indicators
One way to indicate focus is to rely on browser defaults. It works, but I would recommend designing your own focus outlines. This gives you maximum control over how easy they are to see, and lets you integrate them with brand colours or the style of your site. Usually, thicker outlines (from 2px onwards) are better, as they are simply easier to see.
The :focus
pseudo class takes CSS rules like any other selector, so you could style it however you like. In some cases a background color or underline could indicate that something is active.
Examples
Below are focus outlines as seen on Schiphol.nl and the City of The Hague websites. They make it easy to distinguish in a list of links which one is currently active.
Transitions
Focus outlines do not have to be boring. The outline
property can be transitioned with CSS, so why not add a subtle animation? Make it pop!
Contrast
In WCAG 2.1, focus indicators are bound to the same contrast rules as other parts of the content, as per 1.4.11: Non-text contrast. This means a contrast of 3:1 between the outlines and their background is required.
On websites that have both light and dark parts, it is quite common to have a dark and a light focus style. For example, if your focus outline is blue for parts with a white background (for instance, the main content area), you could make it white for parts with a black background (for instance, the footer).
Special cases
Focusing non-interactive elements
As mentioned earlier, focus works on interactive elements. In special cases, it makes sense to focus a non-interactive element, like a <div>
, if that element is a piece of expanded content or a modal overlay that was just opened.
Any element can be added to focus order with the tabindex
attribute in HTML. Best use it with 0
or -1
:
tabindex="0"
: element can be focused with keyboard and through JavaScripttabindex="-1"
: element can be focused through JavaScript, but cannot be tabbed to
A tabindex
with a number larger than 0 is best avoided, as this sets a preference of where the element goes in the tab order. If you set it for one element, you will have to set and maintain (!) a tabindex
value on all interactive elements on the page. See also: It rarely pays to be positive by Scott O’Hara.
Only for keyboard users
If you are a developer and the design team is unwilling to apply bold focus styles, you could propose to show them to users who need them, for instance only to keyboard users.
There are two caveats to this notion of “users who need them”:
- Not all people who rely on focus styles use a keyboard. We mentioned switches earlier, but that’s only one use case. As a general rule, keep in mind that you can’t predict all the ways your visitors choose to browse the web.
- Making focus styles keyboard-only takes away an affordance for mouse users too, as focus also indicates that something is interactive.
For these reasons, we should be careful making decisions about when and how to show focus styles. Luckily, there is a CSS property invented to help us out here: focus-visible. According to the spec, it lets us:
provide clearly identifiable focus styles which are visible when a user is likely to need to understand where focus is, and not visible in other cases
In other words: it aims to let you indicate focus only for people that need it. It is preferable to avoid such heuristics and convey focus rings to everybody, but if you have to, focus-visible is ideal. Especially if the alternative is nothing at all.
Focus styles as keyboard accessibility
A focused element that isn’t highlighted has a big impact on usability for keyboard users. You could make keyboard checks part of your development workflow to ensure that you don’t forget focus indicators. For instance, you could include “Can be used with a keyboard” in your definition of done. This is a check that most people in the team should be able to do before a new feature goes live. As we’ve seen above, focus styles don’t just benefit keyboard users, but keyboard operability is a good way to test them.
When testing, you might find that not all browsers and platforms let you tab through interactive elements by default. Here are some of the most common settings across platforms and browsers:
- macOS: under System Preferences > Keyboard > Shortcuts set ‘Full keyboard access’ to ‘All controls’
- Safari, macOS: in
Safari > Preferences
, under ‘Advanced’, check ‘Press Tab to highlight each item on a webpage’ - Chrome: in chrome://settings, under ‘Web content’, check ‘Pressing Tab on a webpage highlights links, as well as form fields’
Summing up
Hopefully this post inspires you to try out your (client’s) site with just a keyboard. Maybe it is a pleasure to use already. If not, perhaps this post convinces you or your team to address the problem and design some on-brand focus indicators. Together we make the web more friendly to users of keyboards, sticks and switches. Together we make the web work for everyone.
Focus outlines are one of many ways to design for accessibility. For more tips on design with accessibility in mind, see Accessibility Information for UI designers on MDN and Tips for designing with accessibility at the W3C.
Originally posted as Indicating focus to improve accessibility on Hidde's blog.
Hello W3C!
In June, I will start working at the W3C as a Web Front-end Accessibility Specialist in the WAI team. This also means I’m leaving Mozilla and the City of The Hague, where I currently contract. Goodbye is never easy, but I’m very excited for this next challenge.
With 1¾ years, my freelance contract at Mozilla is my longest since I started contracting. Being a contractor is never forever, but I’m still sad to leave. I learn a lot and feel I am able to contribute a lot, too. I like this balance. It is great to work with Mozilla’s Open Innovation team, and specifically the IAM Project. I feel at home. It is difficult, too, at times, as our team is distributed across the globe in an ever-changing organisation (some of that is fun, too).
The majority of my time in the last year was spent on a project codenamed DinoPark, where people can browse other people’s profiles and edit their own. This is currently in Staff-only beta. Technically it is a Vue-based front-end which talks to back-ends using GraphQL. It is even more exciting from a human perspective. It fits Mozilla’s Manifesto in many ways, for example in privacy (how it lets users control who can see their data), security (designed with security at the core) and accessibility (we tackled accessibility challenges early in the process). I like and very much align with the Mozilla stance in the web, which is well captured in the manifesto… this makes me want to continue my relationship with Mozilla as a contributor. I’m still figuring out where that could be (there’s some ideas).
I will also leave the City of The Hague, where I rewrote the existing front-end code into a component-based system, exposed as a pattern library. I also worked on the accessibility throughout this system and the web pages it powers. Working for the government is something I had wanted for a long time, because governments have lots of IT problems, and solving them right can provide incredible value to people’s lives.
I will certainly miss working with both of these teams.
But really, the web is not accessible enough, and I feel like I’ve developed a passion for helping people get it right. At work, but also through talks and workshops. I’m delighted that I’ll get to spend more time on accessibility work.
In the last 10 years, I was often the “accessibility person” on the team. In my role at W3C, I am excited to become a person who is part of an “accessibility team”. I’ll be a Web Front-end Accessibility Specialist, working on WAI-Guide, that’s mostly what I know and can share right now. I’m equally nervous and excited for what awaits me.
Originally posted as Hello W3C! on Hidde's blog.
Baking accessibility into components: how frameworks help
Complex components like date pickers, custom selects and modals can be tricky to get right. They can be tricky to make accessible. They need good internals, like sound semantics, keyboard usability and focus management. All well tested, preferably with a diverse set of real users. Once that is done, once a complex component is built to a high standard, frameworks or Web Components could help make that component very reusable.
Well, what’s new, you might think? Isn’t reusability of components the whole point of UI frameworks and Web Components? Yes, probably. But that is often pointed out as an advantage that increases developer convenience. I’ve heard that phrased as ‘if the developer has convenience, the user will, too’. Meanwhile, component framework-powered websites have a somewhat negative connotation among accessibility experts. This post tries to explore how component frameworks help. How they, too, can make the web a much better place for users, especially in terms of accessibility and usability. (Disclaimer: conclusions in this post may be trivial to declarative framework developers)
When I had to build a custom select
The longer a project goes on, the bigger the chance that someone will want a custom select to be built. I usually try and resist, because these are very hard to get right. Native selects have a lot of thought put into them. They work across platforms in a way that matches each platform (see native select behavior on Android, iOS). But sometimes there are good reasons. Really.
What I’m talking about, just to be clear, is not just a custom trigger (those are relatively easy), but also custom options within them. Everything custom!
The use case that initially triggered this piece of work, was a Mozilla project that had a component where someone could set field level privacy settings. There was a number of fields, like ‘First Name’ and ‘Last Name’, each with their own privacy setting. It was designed to have just the icon in collapsed state, and icons plus labels in the expanded state. An interface with all options spelled out for each field, would likely cause mental overhead. This is not a setting people set often, but we want it to be there, easy to find, because it is important to have control over your data privacy. With that in mind, it would make sense to show just an icon in the collapsed state.
No ARIA this time
ARIA is a fantastic initiative that essentially lets developers polyfill semantics. It involves adding attributes to an HTML element, in order to set accessibility-related meta information like the names, descriptions, roles and states of that element. It is specifically aimed at rich internet applications. Something to remember about it is that, while the ARIA suite adds new semantics to use in HTML, it is not a successor to the existing set of HTML elements. Those elements are still there and often very appropriate to use. The first rule of ARIA is not to use it.
Yep, it’s usually fine and appropriate to use existing semantic HTML elements.
The problem with the existing HTML element that is select
, is this: browsers provide no way to customise what the options look like. But a select is not so different from a group of radiobuttons, right? Either let users pick one out of many. (I’m leaving the multiple
attribute out of this, but let me just say they could map to checkboxes).
One big advantage of radiobuttons is that they are easy to customise, because you can visually hide them and then do whatever you like with their associated label
element.
This is the basic version of a custom option:
<input type="radio" id="option-1" name="option-set" />
<label for="option-1">Rotterdam</label>
With this, you can apply a visually hidden technique to the input, use the
Then, if your list of options is all done, there is one piece left: the thing that toggles the options. For this, I would suggest a button
:
<button type="button">
Choose city
</button>
If you want, you could use some ARIA to convey that this button controls your fieldset. This can be done with aria-controls
, with an ID as its value (use the ID of the element you expand):
<button
type="button"
aria-controls="custom-select">
Choose city
</button>
In Using the aria-controls attribute, Léonie Watson explains that although support is inconsistent, creating a “controls” relationship in the DOM can make a component more robust, while not getting in the way of users:
The presence of aria-controls won’t damage the User Experience (UX) for people using UA that don’t support it, but it will enormously improve the UX for those people whose browser/screen reader combinations do.
Another thing you can do to the button is set the expanded state, with aria-expanded
. This takes a boolean:
<button
type="button"
aria-controls="custom-select"
aria-expanded="false">
Choose city
</button>
The aria-expanded
needs to reflect the actual expanded state, so when the custom select is open, set it to true
, if not, set it to false
.
So… say, you’ve done all this work, and you start using these custom selects across your website. One risk of reusing through copy/paste is that the code ends up in many places, and only in some of the places, all the markup is used as intended. This could be detrimental to the user experience. Maybe we could actually benefit from an abstraction here.
When component abstractions aid accessibility
If we do the above and make it available as a declarative component, perhaps React, Vue or an actual vanilla Web Component, one benefit is state. As we’ve seen in the above example, there are some things that rely on state, like the setting of aria-expanded
. Declarative component frameworks make such settings trivial (once you’re up and speed with using the framework, that is, we’ll get into that later).
A second big advantage, is that it becomes one whole at the point of usage. Let’s say it is called custom-select
.
Whenever we want to use custom-select
, we do (pseudo code):
<custom-select options="options" />
In which options
is some JavaScript object of options.
We declare it, we say what the options are, and in the DOM, it becomes a custom select with those options. This “becoming a custom select” might worry front-end folks, but it is not some sort of magic. We have described exactly what this means, how it should be done. With which semantics, keyboard behavior, focus styles and usability. These things are very important metrics for quality, they require careful consideration. The advantage of using some sort of component abstraction is that only one person or one team has to do this thinking. Others then ‘just’ use it, without worrying about the internals.
In my case, I’ve gone for a button that toggles a fieldset, but if there is a better way, custom-select
can become whatever that better way is in the future. We need to come up with excellent internals, even be ready to improve them after a user test or accessibility. But all in all, I find this separation between internals and actual usage helpful.
A good example of a similar separation of concerns, from existing HTML, is the <video>
element. It has a couple of internals that developers don’t need to worry about at the point of usage. We just need to tell it where our video and subtitles live. It then deals with internals for us: play buttons, closed captions, even multiple video formats… all the good stuff.
I’m more and more convinced that containment of ‘the good stuff’ can make the web better for users.
Increased complexity
There is a disadvantage to this nice containment of components using a framework: it’s complex. I mean, the tooling required to ship code is, because it requires advanced knowledge of JavaScript. That potentially scares people away. Complexity could reinforce privilege and moving all of a component into JavaScipt can turn full-stack developers into gatekeepers. Heydon Pickering describes there is a problem with full stack:
if you put someone in charge of all [the full stack], it’s highly likely they are going to be much weaker in some areas than others
In his post, Heydon identifies that what I call a component’s “internals” above are often built poorly. For two reasons: because improving internals now requires knowledge of complex frameworks and because the people specialising in them get undervalued. People who are good at writing front-end code that improves accessibility, but not at advanced JavaScript, might give up, at which point the web could lose out on accessible functionality. That’s sad.
I really like working on the detailed stuff that affects users: useful keyboard navigation, sensible focus management, good semantics. But I appreciate not every developer does. I have started to think this may be a helpful separation: some people work on good internals and user experience, others on code that just uses those components and deals with data and caching and solid architecture. Both are valid things, both need love. Maybe we can use the divide for good?
Conclusion
Modern websites commonly contain complex interaction patterns that aren’t default on the web. We may dislike that or prefer simplicity, but that’s a different (and also interesting) discussion. If we are going to code these complex interactions, it makes sense to contain the result in a component. Let’s assume we’ve worked hard on very accessible and usable ‘internals’, ran user tests and are confident that they are good. Then re-usability is a great thing, because the people who reuse, don’t need to worry about the internals. Like they wouldn’t worry about the internals of a video
element when they use that. This is how I think frameworks can help make the web more accessible to users. And, ultimately, pave the way for more user convenience.
Update 31/1: In this post, I regard framework components and Web Components as one group for lack of a better word, but as Šime Vidas notes in the comments: if we make accessible components it makes more sense to do it in framework-agnostic Web Components than in a framework. To add to that, it might not only be tool-agnostic, but also more future proof.
Originally posted as Baking accessibility into components: how frameworks help on Hidde's blog.