Tagged “a11y”
3 questions to evaluate design patterns and avoid unnecessary work that degrades UX (by Adam Silver)
Adam offers tips for how to proceed when we are presented with a request for a shiny new pattern which is not grounded in research but rather follows a fad.
The purpose of design is to solve actual problems. Not made up “I’m bored so I’ll come up with something new” problems.
So how can we evaluate these patterns, avoid unnecessary work and ultimately avoid patterns that degrade UX?
He recommends we should start by asking three questions:
- Does research show this pattern solves a problem?
- Are there any potential usability issues with this pattern?
- How much effort is it to build?
Just normal web things.
Heather suggests that in developers’ excitement to do cool new stuff and use cool new tools and techniques “we stopped letting people do very normal web things”. Things like:
- the ability to copy text so you can then paste it
- ensuring elements which navigate also behave like normal links by offering standard right-click and keyboard shortcut options etc. Which is to say – please use the anchor element and leave it alone to do its thing
- letting people go back using the back button
- letting people scroll with native scrollbars. Relatedly, letting people get to the links at the bottom of the page rather than having infinite scrolling results which mean that the footer is always just beyond reach!
- letting the user’s browser autocomplete form fields rather than making them type it
A blog post which uses every HTML element (by Patrick Weaver)
An interesting article which helps the author – and his readers – understand some of the lesser-used and more obscure HTML elements.
While Patrick confesses he is still learning certain things and therefore I won’t regard his implementations as gospel in the way I might an article by someone with greater HTML and accessibility expertise such as Adrian Roselli, I see this as another useful resource to help me when deciding whether or not an HTML choice is the semantic and or correct tool for a given situation.
Thanks, Patrick!
Progress over perfection: a better way to accessibility (meryl.net)
This post from earlier this year offers a similar encouraging message to Henny Swan’s recent The only accessibility specialist in the room. It contains advice that’s worth remembering when we have one of those ”what’s the point?’ moments!
Advice like:
- Get started; don't wait until everything is done and perfect
- Small steps make a big difference
- Educate, don't berate
- Think of accessibility as an ongoing journey with no finish line
Blockquotes in screen readers, by Adrian Roselli
Adrian tests how blockquotes, marked up in a variety of ways, are announced in different screen readers.
He concludes that his personal choice is as follows:
<main>
<!-- other content -->
<blockquote>
<p>A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools.</p>
<footer>— <cite>Douglas Adams, <a href="https://en.wikipedia.org/wiki/Mostly_Harmless">Mostly Harmless</a></cite></footer>
</blockquote>
<!-- other content -->
</main>
He avoids the cite
attribute completely because it creates noise in JAWS, and recommends against using figure
with figcaption
because it results in unnecessarily verbose and duplicate announcements.
In his chosen approach the footer
is used mainly as a sensible styling hook, since in the context of a main
(as opposed to as a direct child of body
) it is not regarded a landmark and is strictly presentational. The cite
element has semantic intent – it’s the element for marking up the title of a cited creative work – even if those semantics are not always exposed to users.
So there’s an action for my team at work, because our blockquote component currently uses figure
and figcaption
. Perhaps at the time of build we took advice from one of the MDN or W3C pages which Adrian has now shown weren’t ideal.
Accessibility Personas
This interesting website from the GDS accessibility team sets out seven personas, each with different access needs.
You can use these profiles to experience the web from the perspective of the personas and gain more understanding of accessibility issues.
The site explains how to set up a device or browser to give each persona its own profile simulating the persona’s condition(s) and runs the assistive technology they use to help them.
The only accessibility specialist in the room – Tetralogical blog
Henny Swan, director at Tetralogical, with some great advice for those whom accessibility responsibility often falls to.
Henny advises:
On responsibility: accessibility is everyone’s responsibility all the time, not just your responsibility all the time. Establish that you can support accessibility, but others also need to do accessibility work and make accessibility-related decisions.
On relationship-building: build relationships with decision-makers with authority to embed accessibility and practitioners ready to build up their skills.
On sustainability and scalability: look for ways to scale what you do through demonstration and documentation.
On expectations: manage expectations and be clear about what you can do. You can give advice, but teams themselves need to make informed decsions. Also – you won’t know everyting, and sometimes you need the help of expert consultancy.
On having support to hand: build a support network through community groups and mentor programmes. I’ve also taken Henny’s advice and subscribed to the WebAIM accessibility discussion list.
Goldman Sachs Design System
This Design System reference website sports a smart architecture with some interesting sections.
The components are neatly organised into categories. And I like the Foundations area which includes a Design System Concepts section serving as a glossary of property and anatomical terms, plus an Accessibility section with neat diagrams.
I think what I like best about this site/system is its organisation and naming.
The web is fundamentally designed to be accessible to all
Working as a web developer, you’ll meet colleagues who don’t realise that accessibility should be non-negotiable. So I’m bookmarking for ready access Tim Berners-Lee’s oft-quoted but still powerful statement of intent from 1997.
The power of the Web is in its universality. Access by everyone regardless of disability is an essential aspect.
This particular W3C WAI page goes on to say:
The Web is fundamentally designed to work for all people, whatever their hardware, software, language, location, or ability. When the Web meets this goal, it is accessible to people with a diverse range of hearing, movement, sight, and cognitive ability.
Thus the impact of disability is radically changed on the Web because the Web removes barriers to communication and interaction that many people face in the physical world. However, when websites, applications, technologies, or tools are badly designed, they can create barriers that exclude people from using the Web.
Accessibility is essential for developers and organizations that want to create high-quality websites and web tools, and not exclude people from using their products and services.
A UX observation regarding good design, by Adam Silver
A spicy but somewhat relatable thought from Adam Silver:
UX observation: I think there might be more devs who care about good design than there are designers. By “good” I mean works for everyone (is accessible) rather than looks nice. What do you think?
The ensuing conversation is pretty interesting. I particularly liked these contributions from Martin Hoyer:
Absolutely. Thinking about the design code-first and understanding how HTML works is so valuable. I don’t think designers should learn HTML but they shouldn’t be the first people to decide how something is built!
He goes on to describe how he thinks design should be done as follows:
In an ideal world (and I don’t think I’ve ever fully achieved this) I’d like to get some requirements (from product I guess), build a prototype in code, then collaboratively iterate on the design from there. Maybe call it a design sprint or whatever!
The new HTML search element
My work colleague Ryan recently drew my attention to the new HTML search
element. This morning I read Scott O’Hara’s excellent primer. Scott worked on implementing <search>
, and his article cleared up my questions around what it is and when we can start using it.
Firstly <search>
is not a “search input” – it’s not a replacement for any existing input
elements. Instead it’s a native HTML element to create a search
landmark, something that until now we could only achieve by applying role="search"
to another element.
Landmarks are an important semantic structure allowing screen reader users to orient themselves and jump to important areas of a web page. Existing landmark-signalling elements you might know include <header>
, <main>
, <footer>
. So you would use <search>
to wrap around a search function, thus providing additional accessibility. And it lets you do so with a native HTML element instead of re-purposing another element by adding ARIA properties, per the first rule of ARIA use. It’d look something like this:
So as Scott himself admits:
To be brutally honest, this is not the most important element that’s ever been added to the HTML specification. It is however a nice little accessibility win.
Do I have a use for this?
If you have a search function or search page and currently miss the opportunity to offer a search landmark you could do so and improve the user experience.
Can I use the <search>
element today?
As Scott mentions, it’s not yet available in browsers (although it likely will arrive soon). So if you added <search>
(just as I’ve typed it there) to a page, it wouldn’t currently create a search landmark. So you could wait for a while before using the element. Alternatively, because HTML’s design is intentionally geared toward a progressive enhancement mindset, you could take Jeremy Keith’s approach and safely use the following today:
Jeremy knows that when browsers encounter an HTML element they don’t know, they don’t break but rather treat it as an anonymous element and carry on. So he includes <search>
to start adopting the new element today, but bolts on role=search
temporarily to manually provide the landmark until browsers understand search
. He’ll then remove the role=search
part once support for search
is widespread.
Displaying tables on narrow screens
Responsive design for tables is tricky. Sure, you can just make the table’s container horizontally scrollable but that’s more a developer convenience than a great user experience. And if you instead try to do something more clever, you can run into challenges as I did in the past. Still, we should strive to design good narrow screen user experiences for tables, alongside feasible technical solutions to achieve them.
In terms of UI design, I was interested to read Erik Kennedy’s recent newsletter on The best way to display tables on mobile. Erik lists three different approaches, which are (in reverse order of his preference):
- Hide the least important columns
- Cards with rows of Label-Value pairs
- More radical “remix” as a “Mobile List”
Another article worth checking is Andrew Coyle’s The Responsive Table. He describes the following approaches:
- Horizontal overflow table (inc. fixed first column)
- Transitional table
- Priority responsive table
For the transitional table, Andrew links to Charlie Cathcart’s Responsive & Accessible Data Table codepen. It looks similar (perhaps better looking but not quite as accessible) to Adrian Roselli’s Responsive Accessible Table.
No Style Design System
Adam Silver’s collection of accessible form-related components – a companion to his book Form Design Patterns – is a brilliant reference.
In there you’ll find Autocomplete, date fields, validation and lots of other tricky components and patterns.
Use the dialog element (reasonably), by Scott O’Hara
Here’s an important update on native modal dialogues. TL;DR – it’s now OK to use dialog
.
Last year I posted that Safari now supported the HTML dialog
element meaning that we were within touching distance of being able to adopt it with confidence. My caveat was:
However first I think we’d need to make an informed decision regarding our satisfaction with support, based on the updated advice in Scott O’Hara’s article Having an Open Dialog.
(Accessibility expert Scott O’Hara has been diligently testing the dialog
element for years.)
However the happy day has arrived. The other day Scott posted Use the dialog element (reasonably). It includes this advice:
I personally think it’s time to move away from using custom dialogs, and to use the
dialog
element instead.
That’s an important green-light!
And this of course means that we can stop DIYing modal dialogues from div
s plus super-complicated scripting and custom ARIA, and instead let a native HTML element do most of the heavy lifting for us.
From a Design System perspective, I’d previously suggested to my team that when we revisit our Modal component we should err toward a good custom dialogue library first, however I’m now likely to recommend we go for native dialog
instead. Which is great!
A Designer’s Guide to Documenting Accessibility & User Interactions (by Stephanie Walter)
My teammate Colin just shared this brilliant designers’ guide to documenting accessibility and user interactions. It’s really thorough and includes some pretty clever annotation techniques.
I agree with Stephanie that unless you ask the questions and document the answers regarding how a design will translate to an accessible reality then it can fall short at lots of points from the start to the implementation. This called to mind a similar perspective from Sophie Beaumont on how the BBC shift left regarding accessibility.
This type of annotation and discussion also feels like another healthy way for designers and engineers to talk to (and learn from) each other more.
I really like Stephanie’s conclusion that you won’t always have time for all of the techniques she mentions, so pick your battles.
The anatomy of visually-hidden - TPGi
This article is not about when or why you would use visually-hidden content. There’s a number of excellent articles that discuss these questions in detail, notably Scott O’Hara’s Inclusively Hidden. But most of them don’t go into much detail about the specific CSS involved — why do we use this particular pattern, with these specific properties? So today I’m going to dissect it, looking at each of the properties in turn, why it’s there, and why it isn’t something else.
Relevant to How to hide elements on a web page.
I also liked this nugget:
it’s often called
.sr-only
(screen reader only, but that’s not a good name, because visually-hidden content is not just for screen readers).
Should I use the HTML title attribute?
People have used the HTML title attribute to achieve a native “tooltip” effect for many years. However accessibility experts have recommended that we should avoid this practice, and here I summarise my research on the topic.
Renowned accessibility solutions provider The Paciello Group recommend the title attribute should almost always be avoided. It causes problems for lots of different usage contexts (keyboard, touch device, screen readers). The only place where I can see that it is still helpful is on iframe
. It was beneficial on form inputs in cases where a visible text label would be redundant and we want to provide our control with a programmatically associated label, however we now have aria
attributes which do a better job.
So on anything other than iframe
the title
attribute is undesirable. To back this up, at work my team recently received the following accessibility feedback from Tetralogical when they reviewed one of our table
s.
The Edit and Delete links use the
title
attribute to provide additional context for each link. Thetitle
attribute can be unreliable (for example, in testing VoiceOver announces the title in French). Provide additional context using thearia-describedby
attribute to reference the name or reference value of the item.
Nordhealth’s Design System
There’s so much to admire in Nord Health’s Design System and specifically its reference website.
I love the way it looks and is organised.
There’s a fantastic, practical accessibility checklist.
They document their naming conventions and the rationale behind them.
They were a trailblazer in adopting web components and I love the docs explaining why.
We’ve chosen to use Web Components because there is a strong requirement for Nord to be used in many different contexts and with varying technologies — from static HTML pages to server-rendered apps, through to single page applications authored with frameworks such as React and Vue. Web Components work great for Nord, because they:
- Are tech-agnostic instead of tech-specific
- Future proof our system with Web Standards
- Allow us to use any framework or no framework at all
- Provide great encapsulation for styles and functionality
Lastly their components look great and show a really high-level of front-end and accessibility literacy.
Full disclosure
Whether I’m thinking about inclusive hiding, hamburger menus or web components one UI pattern I keep revisiting is the disclosure widget. Perhaps it’s because you can use this small pattern to bring together so many other wider aspects of good web development. So for future reference, here’s a braindump of my knowledge and resources on the subject.
A disclosure widget is for collapsing and expanding something. You might alternately describe that as hiding and showing something. The reason we collapse content is to save space. The thinking goes that users have a finite amount of screen estate (and attention) so we might want to reduce the space taken up by secondary content, or finer details, or repeated content so as to push the page’s key messages to the fore and save the user some scrolling. With a disclosure widget we collapse detailed content into a smaller snippet that acts as a button the user can activate to expand the full details (and collapse them again).
Adrian Roselli’s article Disclosure Widgets is a great primer on the available native and custom ARIA options, how to implement them and where each might be appropriate. Adrian’s article helpfully offers that a disclosure widget (the custom ARIA flavour) can be used as a base in order to achieve some other common UI requirements so long as you’re aware there are extra considerations and handle those carefully. Examples include:
- link and disclosure widget navigation
- table with expando rows
- accordion
- hamburger navigation
- highly custom
select
alternatives whenlistbox
is innapropriate because it needs to include items that do not have theoption
role - a toggle-tip
Something Adrian addresses (and I’ve previously written about) is the question around for which collapse/expand use cases we can safely use the native details
element. There’s a lot to mention but since I’d prefer to present a simple heuristic let’s go meta here and use a details
:
Use details
for basic narrative content and panels but otherwise use a DIY disclosure
It’s either a bad idea or at the very least “challenging” to use a native `details` for:
- a hamburger menu
- an accordion
In terms of styling terms it’s tricky to use a `details` for:
- a custom appearance
- animation
The above styling issues are perhaps not insurmountable. It depends on what level of customisation you need.
Note to self: add more detail and links to this section when I get the chance.
I’ve also noticed that Adrian has a handy pen combining code for numerous disclosure widget variations.
Heydon Pickering’s Collapsible sections on Inclusive Components is excellent, and includes consideration of progressive enhancement and an excellent web component version. It’s also oriented toward multiple adjacent sections (an accordion although it doesn’t use that term) and includes fantastic advice regarding:
- appropriate markup including screen reader considerations
- how best to programmatically switch state (such as open/closed) within a web component
- how to make that state accessible via an HTML attribute on the web component (e.g.
<toggle-section open=true>
) - how that attribute is then accessible outside the component, for example to a button and script that collapses and expands all sections simultaneously
There’s my DIY Disclosure widget demo on Codepen. I first created it to use as an example in a talk on Hiding elements on the web, but since then its implementation has taken a few twists and turns. In its latest incarnation I’ve taken some inspiration from the way Manuel Matuzovic’s navigation tutorial uses a template
in the markup to prepare the “hamburger toggle” button.
I’ve also been reflecting on how the hidden
attribute’s boolean nature is ideal for a toggle button in theory – it’s semantic and therefore programattically conveys state – but how hiding with CSS can be more flexible, chiefly because hidden
(like CSS’s display
) is not animatible. If you hide with CSS, you could opt to use visibility: hidden
(perhaps augmented with position
so to avoid taking up space while hidden) which similarly hides from everyone in terms of accessibilty.
As it happens, the first web component I created was a disclosure widget. It could definitely be improved by some tweaks and additions along the lines of Heydon Pickering’s web component mentioned above. I’ll try to do that soon.
Troubleshooting
For some disclosure widget use cases (such as a custom link menu often called a Dropdown) there are a few events that typically should collapse the expanded widget. One is the escape key. Another is when the user moves focus outside the widget. One possible scenario is that the user might activate the trigger button, assess the expanded options and subsequently decide none are suitable and move elsewhere. The act of clicking/tapping elsewhere should collapse the widget. However there’s a challenge. In order for the widget to be able to fire unfocus
so that an event listener can act upon that, it would have to be focused in the first place. And in Safari – unlike other browsers – buttons do not automatically receive focus when activated. (I think Firefox used to be the same but was updated.) The workaround is to set focus manually via focus()
in your click event listener for the trigger button.
Choosing a date - we want to know your use cases (a discussion re. gov.uk design system)
We want to find out if adding a 'date picker' component to the Design System is a good idea.
We're currently looking for: examples of date pickers in services: screenshots, prototypes, links to live services; use cases: explanations of why a 'date picker' was used in a service instead of a 'date input', or something else; research: how well 'date pickers' tested with users to complete different tasks.
This discussion thread will be really helpful for everyone attempting to create an accessible Date Picker.
How to build an accesssible autocomplete
At work there are plans afoot to reconcile various differing Autocomplete implementations into a single, reusable component. So far there’s been a written audit presenting all instances and how they differ in functional and technical respects. There’s also been design work to identify visual commonalities and avoid future inconsistencies. I’d now like to add another perspective: an investigation into which HTML materials and (if necessary) ARIA supplements are appropriate to ensure we build something accessible and resilient.
My experience is that to achieve the right result, HTML semantics and related concerns can’t just follow and bend to spec and visual design goals, but rather must influence the setting of those goals.
I’ll flesh out my findings in due course, but for now here are the key resources I’ve identified and plan to dig deep into.
Adrian Roselli’s article Stop Using ‘Drop-down’. To summarise the options of interest:
- ARIA Listbox lets you create a DIY thing that has the same roles and semantics as a
<select>
but where you have greater stylistic control. There are different ways to implement a Listbox. Datalist
is the native HTML version of a combo box. A combo box is essentially a<select>
with a text field.Datalist
is announced by screen readers in different ways but as far as I can gather these are quirky rather than terrible. I found a nice Twitter thread on DataList which not only shows off its function but also includes a promising accessibility-related comment from Patrick H Lauke of Tetralogical. The drawback, becauseDatalist
is native HTML, is that its options are not stylelable.- ARIA Combobox is a pattern that combines ARIA
combobox
,textbox
andlistbox
roles, and the benefit it brings is to allow a level of custom design that you couldn’t achieve withDatalist
. Autocomplete
(not to be confused with the HTMLautocomplete
attribute) describes a control which provides users with suggestions that may not be available in the DOM already… for example when you fetch options via Ajax in reponse to what the user types.
With regard to Autocomplete, Adrian points to Adam Silver’s Building an accessible autocomplete control.
And for advice on whether or not to go with a native select or a custom control, and how best to implement listbox and combobox if that’s your choice, Adrian points to the following resources from Sarah Higley:
<select>
your poison part 2 (see the Roll your own section at bottom)- Recommended Combobox Patterns pen
I also see that GOV.UK have marked a possible Autocomplete component as one of their next priorities to review. Their Autocomplete discussion thread includes examples and research and will be really helpful.
The ARIA presentation role
I’ve never properly understood when you would need to use the ARIA presentation
role. This is perhaps in part because it is often used inappropriately, for example in situations where aria-hidden
would be more appropriate. However I think the penny has finally dropped.
It’s fairly nuanced stuff so I’ll forgive myself this time!
You might use role=presentation
in JavaScript which progressively enhances a basic JS-independent HTML foundation into a more advanced JS-dependent experience. In such cases you might want to reuse the baseline HTML but remove semantics which are no longer appropriate.
As an example, Inclusive Components Tabbed Interfaces starts with a Table of Contents marked up as an unordered list of links. However in enhanced mode the links take on a new role as tabs in a tablist
so role=presentation
is applied to their containing <li>
elements so that the tab list is announced appropriately and not as a plain list.
Thoughts on HTML over the wire solutions
Max Böck just tweeted his excitement about htmx:
htmx (and similar "HTML over the wire" approaches) could someday replace Javascript SPAs. Cool to see a real-world case study on that, and with promising results
There’s similar excitement at my place of work (and among the Rails community in general) about Turbo. It promises:
the speed of an SPA without having to write any JS
These new approaches are attractive because they let us create user interfaces that update the current page sans reload – usually communicating with the server to get swap-in content or update the database – but by writing HTML rather than JavaScript. Developers have long wished for HTML alone to handle common interactive patterns so a set of simple, declarative conventions really appeals. Writing less JavaScript feels good for performance and lightening maintenance burden. Furthermore the Single Page App (SPA) approach via JS frameworks like React and Vue is heavier and more complicated than most situations call for.
However I have some concerns.
I’m concerned about the “no javascript” language being used, for example in articles titled Hotwire: reactive Rails with no JavaScript. Let’s be clear about what Turbo and htmx are in simple material terms. As Reddit user nnuri puts it in do Hotwire and htmx have a commitment to accessibility? the approach is based on:
a JavaScript library in the client's browser that manipulates the DOM.
Your UI that uses htmx or Turbo is dependent on that JS library. And JS is the most brittle part of the stack. So you need to think about resilience and access. The htmx docs has a section on progressive enhancement but I’m not convinced it’s part of the design.
Secondly if you have client-side JS that changes content and state, that brings added accessibility responsibilities. When the content or state of a page is changed, you need to convey this programatically. We normally need to handle this in JavaScript. Do these solutions cover the requirements of accessible JS components, or even let you customise them to do add the necessary state changes yourself? For example when replacing HTML you need to add aria-live (see also Léonie Watson on accessible forms with ARIA live regions).
Another concern relates to user expectations. Just because you can do something doesn’t mean you should. For example, links should not be used to do the job of a button
. If you do, they need role=button
however this is inadvisable because you then need to recreate (and will likely miss) the other features of a button, and will also likely confuse people due to mismatches between perceived affordance and actual functionality. Additionally, as Jeremy Keith has written, links should not delete things.
In general I feel the message of the new HTML over the wire solutions is very weighted toward developer experience but doesn’t make user experience considerations and implications clear. Due to unanswered questions regarding accessibility I worry that firstly they’re not natively mature in their understanding and approach on that front, and secondly that their framing of benefits is likely to make accessibility ignored due to engineers thinking that they can totally rely on the library.
I’d be really pleased if my concerns could be allayed because in general I like the approach.
Update 30/1//22
I decided to revisit a book I read back in 2007 – Jeremy Keith’s Bulletproof Ajax. I had forgotten this, but it actually contains a section titled “Ajax and accessibility”. It acknowledged that reconciling the two is challenging and despite listing ideas for mitigating issues, it admitted that the situation was not great. However since 2007 – specifically since around 2014 – WAI-ARIA has been a completed W3C recommendation and provides a means of making web pages more accessible, particularly when dealing with dynamic content.
I don’t often have cause to use more than a few go-to ARIA attributes, however here’s my understanding of how you might approach making Ajax-driven content changes accessible by using ARIA.
To do: write this section.
References:
Accessibility drives aesthetics by Alex Chen (on UX Collective)
This article is a couple of years old but just popped up on my radar again. UX Designer Alex Chen asserts that arguments which pit accessibility against aesthetics create a dangerous false equivalence… and I agree.
The article claims that if we are “too accessible” we will meet the needs of the minority but end up hurting those of the majority. This creates a false equivalence between having legitimate access needs and having a preference for a certain aesthetic.
Alex goes on to praise examples where accessibility is used to drive aesthetics – such as the Eames leg splint and GOV.UK’s design system – as opposed to considering the two ideals opposites or that one needs sacrificed for the other.
Should I use a button or a link?
I’ve written previously about the important differences between buttons and links. While reviewing some “component refresh” design mocks at work yesterday I noticed the designs were a bit unclear in this regard so I sent the designers a little decision-tree, which I’m noting here for future reference.
It’s important both for our users and for us as practitioners to distinguish between links (the <a>
element) and the <button>
element. The reason I push this is because they’re fundamentally different functionally, which has important usability implications. Users expect to use mouse, keyboard, browser back-button and assistive tech differently for links than they do for <button>
s. And if they can’t visually distinguish one from the other, they’ll try things they expect to work then get confused when they don’t work.
I think this is an area where design and materials can’t be considered separately and need a joined-up approach.
Here’s a flow I hope is helpful.
Ask: does it…
- take the user to another page? Then it’ll be a link – the
<a>
(anchor) element. - cause something to change on the current page, or submit a form? Then it’ll be a button – i.e. the
<button>
element.
If it’s a link (<a>
):
- it should be underlined so people know it’s a link
- it should have a hover state, for example stay underlined but change colour
- in cases where it’s a CTA you might choose to design it to look button-like and remove some standard link affordances. Just be aware you’re only “calling” it a button. In real user-experienced terms, it’s still a link.
- it does not natively have a disabled state. We shouldn’t be disabling links.
If it’s a button (<button>
):
- it should look like a button, i.e. like a pill or rectangle
- It should not look like a link – that’d confuse users into thinking it takes them to another page.
- So it shouldn’t be underlined by default or on hover. It should have some other hover state.
Testing the decision tree
Let’s take the example of a control for launching a modal dialogue.
The obvious choice is a button, because the control causes something to change on the current page. In this case it causes a dialogue to appear on the current page.
Some might argue that it could be a link. This is usually influenced by the fact that dialogues are often (perhaps inadvisably) used as a kind of “fake page”. And to get someone to a “page” we use a link, right? Advocates of the link option might also have progressive enhancement in mind. If they present a link either to a named fragment further down the page or to a separate page, that offers a resilient baseline experience regardless of whether or not JavaScript is available. The idea is that they also have JavaScript to enhance the link when the user’s environment supports it, perhaps adding role=button
.
However a button
is the more accessible and user-friendly approach for launching the modal.
Better accessible names | hidde.blog
Accessible names are used by assistive technologies to refer to elements on a web page. Hidde tells us how to word them so that they are more useful.
Because of how we use accessible names, we want to keep them functional and avoid naming controls after what they look like. Ideally, you do this in the imperative form, that makes it easiest to quickly grasp what a thing is going to do.
My summary of Hidde’s top tips is:
- Name after function rather than form (“Open navigation” over “Hamburger”)
- Put the most unique part first as this makes it more easy to distinguish between elements (so “Midnight Marauders - Album” rather than “Album - Midnight Marauders”)
- Be concise – keep a name to the most important 1-3 words
- No roles as part of the name (for example don’t include the word ‘button’ or
nav
. The browser already handles this part so it’d be redundant and annoying) - Start names with a capital letter and don't end with a full stop, because a name is not a sentence
- Avoid ARIA if you can just use good element text content
How to Fix Common iOS Accessibility Issues | Deque
Although I don’t work on native apps, I’ve recently been wondering about how accessibility considerations for them compare to those for websites. So this is a timely and useful reference.
iOS provides a lot of accessibility behavior for free, so it’s a great start to making a mobile application accessible. Unfortunately, accessibility is more complicated than the iOS behavior can address, and using only default behavior can actually cause the app to have additional issues.
Tabs: truth, fiction and practical measures
My colleague Anda and I just had a good conversation about tabs, and specifically the company’s tabs component. I’ve mentioned before that our tabs are unconventional and potentially confusing, and Anda was interested to hear more.
What’s the purpose of a tabbed interface?
A tabbed interface is a space-saving tool for collapsing parallel content into panels, with one panel visible at a time but all accessible on-demand. While switching between tab panels the user is kept within the same wider context i.e. the same page, rather than being moved around.
Conventional tabbed interfaces
Here are some great examples of tabs components.
- Inclusive Components – Tabbed Interfaces
- Tabs component in GOV.UK Design System
- ARIA Tabs by Adrian Roselli
Tabs are a device intended to improve content density. They should deliver a same-page experience. Activating a tab reveals its corresponding tab panel. Ideally the approach employs progressive enhancement, starting as a basic Table of Contents. There’s quite a lot of advanced semantics, state and interactivity under the hood.
Faux tabs
But in our Design System at work, ours are currently just the “tabs” with no tab panels, and each “tab” generally points to another page rather than somewhere on the same page. In other words it’s a navigation menu made to look like a tabbed interface.
I’m not happy with this from an affordance point of view. Naming and presenting something as one thing but then having it function differently leads to usability problems and communication breakdowns. As the Inclusive Components Tabbed Interfaces page says:
making the set of links in site navigation appear like a set of tabs is deceptive: A user should expect the keyboard behaviors of a tabbed interface, as well as focus remaining on a tab in the current page. A link pointing to a different page will load that page and move focus to its document (body) element.
Confused language causes problems
One real-life problem with our tabs is that they have been engineered as if they are conventional tabs, however since the actual use case is often navigation the semantics are inappropriate.
We currently give each “tab” the ARIA tab
role, defined as follows:
The ARIA
tab
role indicates an interactive element inside atablist
that, when activated, displays its associatedtabpanel
.
But our tabs have no corresponding tabpanel
; they don’t use JavaScript for a single-page experience balancing semantics, interactivity and state as is conventional. They’re just navigation links. And this mismatch of tabs-oriented ARIA within a non-tabs use case will do more harm than good. It’s an accessibility fail.
A stop-gap solution
If content for one or more tabpanel
is provided, apply the complicated ARIA attributes for proper tabs. If not, don’t. This means we allow component consumers to either create i) a real tabbed interface, or ii) “a nav menu that looks like tabs” (but without any inappropriate ARIA attributes). I don’t agree with the latter as a design approach, but that’s a conversation for another day!
Tabs in the future
Some clever people involved with Open UI are using web components to explore how a useful tabs
element could work if it were an HTML element. Check out the Tabvengers’ spicy-sections component. Again, this is based on the conventional expectation of tabs as a same-page experience for arranging content, rather than as a navigation menu. And I think it’d make sense to stay on the same path as the rest of the web.
Editable table cells
Yesterday the Design System team received a tentative enquiry regarding making table cells editable. I’m not yet sure whether or not this is a good idea – experience and spidey sense tell me it’s not – but regardless I decided to start exploring so as to base my answer on facts and avoid being overly cautious.
In my mind’s eye, there are two ways to achieve this:
- on clicking the cell, the cell content is presented in an (editable) form input; or
- apply the
contenteditable
attribute
In both cases you get into slightly gnarlier territory when you start considering the need for a submit button and how to position it.
I don’t have anything further to add at the moment other than to say that if I had to spike this out, I’d probably start by following Scott O’Hara’s article Using JavaScript & contenteditable.
I’d probably also tweet Scott and ask if he can say anything more on his closing statement which was:
I have more thoughts on the accessibility of contenteditable elements, but that will also have to be a topic for another day…
Update 27-09-22: I’ve also remembered that (if I were to pursue Option 1: input within cell) Adrian Roselli has an article on Accessibly including inputs in tables.
Building the main navigation for a website (on web.dev)
learn about semantic HTML, accessibility, and how using ARIA attributes can sometimes do more harm than good.
Alongside all the sound accessibility and hiding-related advice, I also found Manuel’s approach to progressive enhancement interesting. Rather than i) include a hamburger button
directly in the DOM and set its initial state to hidden
; or ii) create the button
element with JavaScript, he instead nests the button
in a template element then clones that element with JavaScript. He later tweeted his rationale for this approach:
If JS doesn't work, the markup inside the template won't be rendered on screen and it's more convenient to prepare the markup upfront instead of using document.createElement().
The ability to prepare complex, JS-dependent component markup upfront in declarative HTML rather than recreating it in JavaScript is a compelling argument for his approach. Especially so if you don’t work in JS framework-based systems therefore your components are not written in JavaScript.
Use CSS :has to set root-level styles based on a button’s state
Great tip here from Jhey. He advises using a button
with ARIA and a little JavaScript for your dark-mode toggle. And to apply the dark styles, use a CSS selector which targets the :root
parent of the button when in “pressed” state and sets a root-level custom property to “on”.
:root:has([aria-pressed=true]) {
--dark:1;
}
Seriously clever stuff!
And aside from the CSS, I really like the way Jhey advocates using a button
rather than a form element such as a checkbox for this kind of interface, much like Léonie did recently.
We use too many damn modals (modalz modalz modalz dot com)
At our fortnightly Accessibility Forum at work, we just had a great discussion about modal dialogues. We started by discussing whether focus should be completely trapped within the modal or if the user should at least have access to the browser toolbar (we decided on the former). We then moved onto a general discussion on the pros and cons of modals, which led me to share MODALZ MODALZ MODALZ with the team.
Adrian Egger’s website presents some interesting suggestions, which I’ll summarise below:
Have you considered using the following alternatives to modals?
- Non-modal dialogs (e.g. toasts): for non-critical interactions that don’t block the user, use these rather than modals
- New page: lead the user to a different page to isolate the interaction without losing access to functionality such as navigation.
- Go inline: present your content inline to be less disruptive.
- Expanding elements: Use expanding elements such as accordions, toolbars, tooltips, or sliding sidebars (or other modeless elements).
- “Undo” patterns: instead of confirmation modals, consider using inline “Undo” option to speed up the user’s interactions.
When all else fails here’s how to get modals right:
Do:
- Make it easy to close: make it simple to get rid of ‐ by escape key, clicking outside the modal window, and a clearly labelled close button.
- Single purpose: limit the interaction to one, straightforward task.
- Keep it short: be brief and concise in your content
- Accessibility: this is fairly self-explanatory — if you can’t make it accessible, don’t use a modal.
Do not:
- Modal inception: avoid opening a modal from a modal.
- Fullscreen modals: you might as well navigate to a new page.
- Multi-step modals: never create a multi-step modal. That way madness lies.
- Self-spawning modals: never present modals unless prompted by the user.
- Marketing modals: seriously, nobody wants that sh*t — especially not your newsletter.
Modals are so hard to do well and present so many possible issues that I think before diving into designing/building one, it’s worth questioning if a modal is really appropriate for your use case.
Putting a full stop on truncation
At work we’ve recently been shown a couple of design proposals where truncation was presented as a solution to the perceived problem of long and unwieldy content, for example a long description in a table cell. However following good discussions, as a wider team we’re now leaning towards avoiding truncation as an approach. Truncation can present accessibility issues and as Karen McGrane says truncation is not a good content strategy. I reckon we should just let long content wrap, and design for that to look OK.
And when natural wrapping doesn’t cut it – like when you’re tackling very long words in confined spaces – reach for overflow-wrap: break-word
as suggested in Ahmad Shadeed’s excellent Handling Short And Long Content In CSS.
Inclusive user research: recruiting participants (by Ela Gorla on Tetralogical’s blog)
Tetralogical are doing a great series of articles on running inclusive research. Their latest is about recruiting participants and covers whether you should recruit people with disabilities as part of your testing and if so who, and how many, and how to recruit them.
Previous articles addressed moderating usability testing sessions with people with disabilities, and analysing findings from inclusive user research.
Custom multi-checkbox and multi-radio controls
Our Design System team has recently received “new component requests” for some custom filtering controls. These look like custom-styled <select>
s however their “options” appear more like checkboxes and radio buttons. I think the inspiration was Carbon Design System’s Dropdown component and the idea is to bring consistency to filtering controls in forms. Although it’s not yet time to fully explore this and make a yay/nay decision on the request, I’ve been doing some initial thinking.
(Note: this post is kinda a journey and work-in-progress. I’ll return to complete it and tidy up. For now it serves as a handy log of my research.)
When this was first mooted without guide designs, I assumed we’d be making a custom select. Filament Group have previously shown how to style one of those, although that only affects the “trigger” part. CSS can’t yet style the options. That then led me to check in on the progress of Open UI’s selectmenu element which does support styling the options however it appears that it’s far from road-ready.
However then I saw the designs and realised that while the outside looks like a select, the options look like a group of checkboxes or (kinda) like radio buttons, rather than typical <select>
options. And of course the checkboxes and radio buttons themselves are custom-styled.
This led me to reading the following resources.
- Under-engineered multi-selects
- Under-engineered select menus
- Under-engineered custom radio buttons and checkboxen
- Inclusively Hiding & Styling Checkboxes and Radio Buttons
Léonie Watson’s post Perceived affordances and the functionality mismatch is also looming large in the back of my mind.
Simple input[type=range] styling, by Ana Tudor
Ana demonstrates how to achieve a range slider effect accessibly, using web standards and without needing to reach for libraries.
As Ana’s tweet explains, this offers a number of features and benefits:
- can drag thumb with JS disabled
- receives focus
- keyboard navigation
- clicking track moves thumb there and changes slider value
- seen as slider in Accessibility panel
- no library needed, so less code in total
Perceived affordances and the functionality mismatch (by Léonie Watson)
Léonie tackles the prickly subject of “element re-purposing” in web development. This post follows a fantastic Twitter exchange started by Lea Verou regarding whether the common visual design request for “adjacent but mututally exclusive buttons” should be built as radio buttons or using <button>
elements.
Using one element or set of elements (usually because of their functionality) and styling them to look like something else is a common pattern […but…] it creates a mismatch between the actions people expect they can take and the ones they actually can.
Relatedly, Lea has also gathered her post-discussion thoughts and decisions into a blog post What is the best way to mark up an exclusive button group? and shared a new button-group
web component!
Meanwhile, Léonie already has a theme-toggle web component on her personal website which demonstrates the use of buttons and aria-pressed
.
Thank you so much, Lea and Léonie.
Update July 19/7/22
I just had a twitter conversation with Adrian Roselli where I suggested that the reasons for developers considering radio inputs over buttons for Lea’s use case might be more nuanced than simply misunderstanding HTML. I’m not sure we agreed on that one in the end, however Adrian shared some helpful heuristics when choosing betweeen JS-powered buttons and forms:
A checkbox, radio button, select menu are meant to gather information. The submit button sends the form (whether get, post, or an AJAX call). A button (non-submit) causes a change on the page, such as toggling a control, showing or hiding something, etc. Different context/use.
I think it would help to think of form fields as for forms. Forms that users intentionally submit (no matter if processed client- or server-side). Forms that gather info. Buttons that have states (expanded, pressed, etc) are for manipulation of the current view.
Takeaways:
- Pick the HTML solution that is generally intended for your use case.
- Use a form if you’re gathering information but if you’re not, don’t. There will be exceptions like “filter forms” but that’s an edge case and most forms are not like that.
- Forms are ideally things that users intentionally submit, via a submit button. This helps rule out “clever forms” as an option.
- Use a button to cause a change on, or manipulate, the current page.
Refactoring a modal dialogue in 2022
My team will soon be refactoring our modal dialogue component. Ours has a few deficiencies, needs better developer experience and documentation, is not built to our Design System component standards, and could use a resilience boost from some progressive enhancement.
For a long time the best – meaning accessible, framework-agnostic, feature-packed – modal implementations were custom. Specifically:
However with recent browser advances (especially from Safari), there’s an argument that the time has now come that we no longer need custom solutions and can go native. So we might reach for the native <dialog>
HTML element.
However first I think we’d need to make an informed decision regarding our satisfaction with support, based on the updated advice in Scott O’Hara’s article Having an Open Dialog.
Additionally we should definitely be keeping one eye on proposals around the exciting new togglepopup
and popup
attributes which promise the holy grail of entirely HTML-powered modal dialogues with no JavaScript dependency.
A better birthday input, by Vitaly Friedman
I recently signed up to Vitaly from Smashing Mag’s Smart Interface Design Patterns newsletter. This latest edition regarding “date of birth” inputs was interesting, and well timed as my work colleagues and I are about to revisit our form patterns. It’s a nice explainer on why we should approach UI for dates the user knows differently from UI for dates the user will choose.
Vitaly recommends that when asking the user for a very specific date that they already know without needing to consult a calendar, drop-downs and calendar look-ups are unnecessary. And avoiding them is probably ideal, because <input type=date>
and <select>
based interfaces have some usability and accessibility kinks, as do many date-picker libraries.
It’s better to rely on three simple, adjacent text input fields with a label above each field. See GOV.UK’s Date input component for a great example.
Date pickers should only be required when you’re asking for a date that the user will choose (say, booking a holiday or appointment) rather than one they’ll know. Vitaly doesn’t recommend a date picker, but I reckon the date-picker web component from the clever folks behind the Duet Design System could be a good option.
Oh, and this also reminds me that I need to get the finger out and pick up a copy of Adam Silver’s Form Design Patterns.
Tables and pseudo-tables: lessons and tactics
At work I have to think about complex HTML tables a lot. The challenge with doing tables well is that 99% of online table tutorials use fairly simple examples… whereas in reality design and product teams often want to squeeze in lots more. It’s really hard to balance those needs against accessibility, systemisation, styling and responsiveness.
Heads up: I’ve published this post early while it’s still a work in progress because it’s better for me to have it available for reference than languishing in drafts and forgotten. Apologies if you read it in a temporarily rough state.
Following a lot of work on tables I’ve recently gained additional insight into the possibilities and constraints, thanks to an accessibility review by Tetralogical and some great articles by Adrian Roselli.
Here are my new rules of thumb.
Avoid complex recreations of tables with alternate elements
In addition to developing a component wrapping the HTML table
element to handle simple data tables, I recently created an alternate component for “tables with bells and whistles”. It used a combination of the HTML description list element plus CSS Grid plus some display: contents
in lieu of the currently poorly supported subgrid. This approach allowed recreating a table-like appearance but facilitating much more responsive layout flexibility, amongst other benefits.
Unfortunately this resulted in an accessibiliy fail around using the description list in this way. Popular combinations of browsers and assistive technologies do not support description lists sufficiently to convey the intended crucial relationships between the faux table headers and faux table cells.
Note: I think it’s OK to use the description list element in general – just not for such an unconventional and complex use case.
ARIA Grid role: an alternative in theory (if not in practice)
I noted that Github handle their “repository directory indexes” using the ARIA grid role. Their HTML is like this (I’ve abbreviated it a touch):
<div role="grid" aria-labelledby="files" class="…">
<div class="sr-only" role="row">
<div role="columnheader">Type</div>
<div role="columnheader">Name</div>
<div role="columnheader" class="d-none d-md-block">Latest commit message</div>
<div role="columnheader">Commit time</div>
</div>
<!-- interesting 'fake' row here -->
<div role="row" class="…">
<div role="rowheader" class="…">
<a rel="nofollow" title="Go to parent directory" class="…" href="…"><span class="…" style="…">. .</span></a>
</div>
<div role="gridcell" class="…"></div>
<div role="gridcell"></div>
</div>
<!-- first real row -->
<div role="row" class="Box-row Box-row--focus-gray py-2 d-flex position-relative js-navigation-item navigation-focus">
<div role="gridcell" class="…"><svg …></svg></div>
<div role="rowheader" class="…">
<span class="…"><a class="…" href="…">my-file-name.md</a></span>
</div>
<div role="gridcell" class="…">
<span class="…"><a href="…">The commit message</a></span>
</div>
<div role="gridcell" class="…">
<time-ago datetime="2021-06-17T16:45:42Z">11 months ago</time-ago>
</div>
</div>
<!-- more rows go here -->
</div>
I like the idea of looking at alternatives to tables but don’t think I’d take this approach right now. Where there are lots of focusable elements it turns those multiple tab-stops into one (the grid is a single widget) which is perhaps useful for some cases, but I’ve yet to encounter them. It’d also require you to do manual focus management within the widget.
It’s an interesting approach though, and one I’ll keep in the back of my mind.
You can achieve “bells and whistles” within a table accessibly
Here are some handy techniques – done accesibly – courtesy of Adrian Roselli:
- Accessibly including inputs in tables
- Under-engineered responsive tables
- Responsive accessible tables – this more complex approach employs JavaScript to i) apply appropriate ARIA roles to existing table HTML, and ii) create clever alternate labelling using pseudo elements. It uses CSS to change the
display
of the table and its children to create a small-screen-friendly layout. The JS-applied roles serve to maintain the necessary semantics that would otherwise be lost when applying the radical CSS changes. - Charlie Cathcart’s responsive table is similar to the above although perhaps less comprehensive. However it might have other interesting aspects.
- Clip long, overflowing content
- Expandable rows
- Fixed headers
References
- Grids pt1: To grid or not to grid by Sarah Higley
- ARIA Grid as an anti-pattern by Adrian Roselli
Improved focus indicators for keyboard navigation (on GitHub’s blog)
GitHub have recently done some good work on improving keyboard navigation for (and general usability of) their focusable elements such as links, buttons and form controls by improving focus indication. And then they wrote a short-but-sweet article about it, then tweeted to share that and their work is getting lots of positive recognition from all the right people. Nice job all round, GitHub!
Incidentally, that article they wrote really is very short. Maybe they’ll add to it later. The animated gif they include is very descriptive, mind you. And I noticed that they added the following alt
text to it:
Animated gif of a customer using their keyboard to navigate a pull request, interactive UI elements receive a blue focus outline to show current location on the page. Key presses are shown in the bottom center of the image.
That feels like a good non-visual alternative description to me.
Improving alternative text for images
Some colleagues at work have recently been asking interesting questions about “good/appropriate alternative text for images”. I definitely reckon it’s a topic worth revisiting because it feels like the landscape has changed a bit on this front over the years.
I think the web design industry has traditionally been:
- lacking knowledge of how to write good alternative text.
- too quick to decide which images are “purely decorative”, or accurately described by a matter-of-fact short label when maybe they actually should convey their inherent tone and emotion to all users rather than only those with no visual impairments.
But as inclusion-centric practioners we can probably do better. In his blog post Writing great alt text Jake Archibald breaks down the considerations. I reckon it’d be useful for us to dissect this post and try to boil it down to some practical rules-of-thumb for our teams.
But also, I’ve just noticed a couple of interesting developments at the big players. Firstly, Twitter have upped their image alt
game and are encouraging their users to try doing so, too.
And hot on the heels of Twitter’s announcement, I now see in Slack an Edit file details option for adding image descriptions. It’s great that Twitter and Slack are doing this… and also serves as a reminder that tools such as Slack and Twitter are consumed on the web and so accessible best practices apply when you’re writing content on them, too!
Skip to Content: Online Accessibility Insights from Léonie Watson
Here’s a lovely, short (13 min) interview from an accessibility expert with a really positive outlook—highly recommended.
Q: What’s just one thing that every single person can do in the progression toward an accessible internet?
A: When you’re talking to colleagues, peers… promote the notion that accessibility is just part of what we do because we’re good at our job. It’s not extraordinary, it’s not unusual, it’s not something you can drop because you’re pushing for launch.
My talk, “Hiding elements on the web” for FreeAgent’s tech blog
I recorded a talk on “Hiding elements on the web” for @freeagent’s tech blog. It’s a tricky #FrontEnd & #a11y topic so I try to cover some good practices and responsible choices. Hope it helps someone. (Also it’s my first video. Lots of room to improve!)
---What open-source design systems are built with web components?
Alex Page, a Design System engineer at Spotify, has just asked:
What open-source design systems are built with web components? Anyone exploring this space? Curious to learn what is working and what is challenging. #designsystems #webcomponents
And there are lots of interesting examples in the replies.
I plan to read up on some of the stories behind these systems.
I really like Web Components but given that I don’t take a “JavaScript all the things” approach to development and design system components, I’ve been reluctant to consider that web components should be used for every component in a system. They would certainly offer a lovely, HTML-based interface for component consumers and offer interoperability benefits such as Figma integration. But if we shift all the business logic that we currently manage on the server to client-side JavaScript then:
- the user pays the price of downloading that additional code;
- you’re writing client-side JavaScript even for those of your components that aren’t interactive; and
- you’re making everything a custom element (which as Jim Neilsen has previously written brings HTML semantics and accessibility challenges).
However maybe we can keep the JavaScript for our Web Component-based components really lightweight? I don’t know. For now I’m interested to just watch and learn.
GOV.UK introduce an experimental block link component
Here’s an interesting development in the block link saga: GOV.UK have introduced one (named .chevron-card
) on their Homepage, citing how it’ll improve accessibility by increasing mobile touch targets. It’s not yet been added to their Design System while they’re monitoring it to see if it is successful. They’ve chosen the approach which starts with a standard, single, non-wrapping anchor then “stretches” it across the whole card via some pseudo elements and absolute positioning magic. I’m slightly surprised at this choice because it breaks the user’s ability to select text within the link. Really interested to see how it pans out!
Lovely write-up, & great rationale re. larger mobile tap targets! I’ve wrestled with “block links” & found that each approach has issues so it’s v. interesting that you chose the route that impacts text selection. Is that the lesser of the evils? Keen to hear how it pans out!
— Laurence Hughes (@fuzzylogicx) December 13, 2021
Collected web accessibility guidelines, tips and tests
At work, I’m sometimes asked accessibility questions or to provide guidelines. I’m with Anna Cook in considering myself an accessibility advocate rather than an expert however I have picked up lots of tips and knowledge over many years of developing websites. So I thought it’d be useful to gather some general web accessibility tips and tests in one place as a useful reference.
Caveats and notes:
- this is a living document which I’ll expand over time;
- I’m standing on the shoulders of real experts and I list my references at the foot of the article; and
- if I’ve got anything wrong, please let me know!
Table of contents
- If you only had 5 minutes
- Content structure
- Semantic HTML and ARIA
- Favour native over custom components except where they have known issues
- Make custom components convey state accessibly
- Forms
- Links and buttons
- Ensure keyboard support
- Content resizing
- Better link text
- Supporting high contrast mode
- Skip links
- Navigation and menus
- Modal dialogues
If you only had 5 minutes
If someone had a web page and only had 5 minutes to find and tackle the lowest hanging fruit accessibility-wise, I’d probably echo Jeremy Keith’s advice to ensure that the page covers the following:
- uses heading elements sensibly
- uses landmarks (representing roles like
banner
,navigation
,main
,contentinfo
) - marks up forms sensibly (for example using labels and appropriate buttons)
- provides images with decent text alternatives
(Note: headings and landmarks are used by screen reader users to get a feel for the page then jump to areas of interest.)
Spending just 5 minutes would be bad, of course, and you shouldn’t do that. The point is that if pushed, the above give good bang-for-your-buck.
Content structure
The page’s content should be well structured as this makes it easier to understand for all, especially people with reading and cognitive disabilities.
It should consist of short sections of content preceded by clear headings. Use the appropriate heading level for the place in the page. Don’t use an inappropriate heading level to achieve a given appearance such as a smaller size. Instead use the appropriate heading element then use CSS to achieve your desired style.
It should employ lists where appropriate. It should place the most important content at the beginning of the page or section to give it prominence.
Check your page for any long passages of text with no structure. Ensure that sufficient prominence is given to the most important information and calls to action.
Semantic HTML and ARIA
While there are generic HTML elements like div
and span
, there are many more HTML elements that perform a specific role and convey that role to browers and other technologies. Choosing and using semantic HTML elements appropriately is a very good practice.
Also, using semantic HTML elements is preferable to bolting on semantics via attributes since the semantics are conveyed natively avoiding redundancy and duplication. As Bruce Lawson says, “Built-in beats bolt-on, bigly”.
Apply ARIA carefully. No ARIA is better than bad ARIA.
Landmarks
Create a small number of landmarks using the appropriate HTML elements.
For some landmark-generating elements it’s appropriate to bolster them with a label or accessible name. For example with nav
and aside
, i) there’s a decent chance there might be multiple on the page; and ii) each instance creates a landmark even when it’s nested within a deeper HTML element. So it’s helpful to distinguish each different landmark of the same type by using sensible accessible names otherwise you’d get multiple navigation menus all represented by the same “navigation” in the Landmarks menu. In the case of the section
element it needs an acessible name in order for it to act as a region
landmark. For all of these you can use aria-labelledby
set to the id
of an inner heading, or use aria-label
.
Note that when using multiple <header>
(or footer
) elements on a page, where one and one only is a direct child of body
while the others are used within article
or similar elements, there’s perhaps less need to add custom accessible names. That’s because only a direct child of body
will be treated as a landmark and the others won’t, therefore they won’t be butting against each other in a screen reader’s Landmarks menu and need distinguished.
Correct use of aria-label and aria-labelledby
Use the aria-label
or aria-labelledby
attributes (only when necessary) on interactive elements – buttons, links, form controls – and on landmark regions. Don’t use them on <div>
s, <span>
s, or other elements representing static/noninteractive text-level semantics, such as <p>
, <strong>
, <em>
, and so forth, unless those elements’ roles have been overridden with roles that expect accessible names.
Favour native over custom components except where they have known issues
Native components require very little work, are familiar to users, and are generally accessible by default. Custom components can be built to appear and behave as designers want, but require much more effort to build and are challenging to make accessible.
There are exceptions. Since the native options are flawed across browsers, accessibility experts recommend using custom solutions for:
- form error field messages
- focus indicator styles
Make custom components convey state accessibly
Now that you’re building a custom component you don’t get accessibility out of the box. Whether it’s a Like button or a disclosure widget, you can’t rely on a visual change alone to convey a UI change to all users. You’ll need to use the right element (note – it often starts with a button
) and then use ARIA to convey states such as pressed or expanded to screen reader users.
Forms
Because in the industry form fields are often handled with JavaScript and not submitted, people sometimes question whether form fields should live inside a form (<form>
). My answer is yes, and here’s why.
Using the form element improves usability and accessibility
Using a <form>
provides additional semantics allowing additional accessibility. It helps assistive devices like screen readers better understand the content of the page and gives the person using them more meaningful information.
By putting form fields inside a form we also ensure we match user expectations. We support the functionality (such as the different ways of submitting a form) that users expect when presented with form fields.
If you’re thinking “but what about form fields that don’t look like form fields?” then you’ve entered the problem territory of “deceptive user interfaces” – the situation where perceived affordances don’t match actual functionality, which causes confusion for some people. This is to be avoided. We shouldn’t use form fields (nor a <form>
) when they are not appropriate. A checkbox, radio button, or select menu is meant to gather information. So if your goal is instead to let the user manipulate the current view, use a button
rather than checkboxes or radio buttons.
References:
- Why use a form element when submitting fields with JavaScript
- Lea Verou and Leonie Watson’s discussion regarding Toggles
- My conversation about forms with accessibility expert Adrian Roselli
Using the form element simplifies your JavaScript for event handling
Using the form
element can also make it easier for you to meet user expectations in your JS-powered experience. This is because it gives you a single element (form
) and event combination that allows listening to multiple interactions. With a form element you can add a listener for the submit()
event. This event fires automatically in response to the various ways users expect to submit a form, including pressing enter inside a field.
Anchors and buttons
To let the user navigate to a page or page section, or download a file, use an anchor element.
To let the user trigger an action such as copying to clipboard, launching a modal or submitting a form, use a button element.
Anchors should include an href
attribute otherwise the browser will treat it like a non-interactive element. This means the link will not be included in the expected focus order and will not present a pointer to mouse users like it should. These days there is no remaining use case for an anchor without an href
. We no longer need named anchors to create link-target locations within the page because we can use the id
attribute (on any element) for that. And if you want an interactive element that does not link somewhere, you should use button
.
Do not remove the focus outline from links and buttons in CSS, unless it’s to provide a better version.
Ensure you always give links and buttons an accessible name, even when they use icons rather than text. This might be through visually hidden text or perhaps using an ARIA-related attribute.
Ensure keyboard support
Web pages need to support those who navigate the page by keyboard.
Use the tab key to navigate your page and ensure that you can reach all actionable controls such as links, buttons and form controls. Press the enter key or space bar to activate each control.
If during your test any actionable control is skipped, receives focus in an illogical order, or you cannot see where the focus is at any time, then keyboard support is not properly implemented.
Content resizing
Try zooming your page up to 400%. In Chrome, Zoom is available from the kebab menu at the top-right, or by holding down command with plus or minus.
Content must resize and be available and legible. Everything should reflow.
Relative font settings and responsive design techniques are helpful in effectively handling this requirement.
Relatedly, setting font-sizes in px
should be avoided because although a user can override the “fixed-ness” with zoom, it breaks the user’s ability to choose a larger or smaller default font size (which users often prefer over having to zoom every single page).
Better link text
Blind and visually impaired users use a screen reader to browse web pages, and screen readers provide user-friendly access to all the links on the page via a Links menu. When links are encountered in that context, link text like “Click here” and “Read more” are useless.
Check your web page to ensure that links clearly describe the content they link to when read out of context.
Better link text also improves the flow and clarity of your content and so improves the experience for everyone.
Supporting high contrast mode
Some people find it easier to read content when it’s in a particular colour against a specific background colour. Operating systems provide options to allow users to configure this to their preference. Websites must support support the user’s ability to apply this.
On a Windows computer go to Settings > Ease of access and turn on High contrast mode. On macOS go to System preferences > Accessibility settings > Display and select “Invert colours”.
Having changed the contrast, check that your web page’s content is fully visible and understandable, that images are still visible and that buttons are still discernible.
Skip links
Websites should provide a “Skip to content” link because this provides an important accessibility aid to keyboard users and those who use specialised input devices. For these users, having to step through (typically via the tab key) all of the navigation links on every page would be tiring and frustrating. Providing a skip link allows them to bypass the navigation and skip to the page’s main content.
To test that a website contains a skip link, visit a page then press the tab key and the skip link should appear. Then activate it using the enter key and check that focus moves to the main content area. Press tab again to ensure that focus moves to the first actionable element in the main content.
Navigation and menus
When developing a collapsible menu, place your menu <button>
within your <nav>
element and hide the inner list rather than hiding the <nav>
element itself. That way, we are not obscuring from Assistive Technologies the fact that a navigation still exists. ATs can still access the nav via landmark navigation. This is important because landmark discovery is one of the fundamental ways AT users scan, determine and navigate a site’s structure.
Modal dialogues
You probably don’t want to set the modal’s heading as an <h1>
. It likely displays content that exists on the page (which already has an <h1>
) at a lower level of the document hierarchy.
References
- Using HTML landmark roles to improve accessibility MDN article. And Adrian R’s suggestions for additions
- Navigation (landmark) role, on MDN
- Tetralogical’s Quick Accessibility Tests YouTube playlist
- Basic accessibility mistakes I often see in audits by Chris Ferdinandi
- Sara Soueidan’s video tutorial Practical tips for building more accessible front-ends
- Adrian Roselli’s Responsive type and zoom
- Heydon Pickering’s tweet about buttons in navs and Scott O’Hara’s follow up article Landmark Discoverability
- Tetralogical’s Foundations: native versus custom components
- Ben Myers on where to use aria labelling attributes
Collapsible sections, on Inclusive Components
It’s a few years old now, but this tutorial from Heydon Pickering on how to create an accessible, progressively enhanced user interface comprised of multiple collapsible and expandable sections is fantastic. It covers using the appropriate HTML elements (buttons) and ARIA attributes, how best to handle icons (minimal inline SVG), turning it into a web component and plenty more besides.
Buttons and links: definitions, differences and tips
On the web buttons and links are fundamentally different materials. However some design and development practices have led to them becoming conceptually “bundled together” and misunderstood. Practitioners can fall into the trap of seeing the surface-level commonality that “you click the thing, then something happens” and mistakenly thinking the two elements are interchangeable. Some might even consider them as a single “button component” without considering the distinctions underneath. However this mentality causes our users problems and is harmful for effective web development. In this post I’ll address why buttons and links are different and exist separately, and when to use each.
Problematic patterns
Modern website designs commonly apply the appearance of a button to a link. For isolated calls to action this can make sense however as a design pattern it is often overused and under-cooked, which can cause confusion to developers implementing the designs.
Relatedly, it’s now common for Design Systems to have a Button component which includes button-styled links that are referred to simply as buttons. Unless documented carefully this can lead to internal language and comprehension issues.
Meanwhile developers have historically used faux links (<a href="#">
) or worse, a DIY clickable div
, as a trigger for JavaScript-powered functionality where they should instead use native buttons.
These patterns in combination have given rise to a collective muddle over buttons and links. We need to get back to basics and talk about foundational HTML.
Buttons and anchors in HTML
There are two HTML elements of interest here.
Hyperlinks are created using the HTML anchor element (<a>
). Buttons (by which I mean real buttons rather than links styled to appear as buttons) are implemented with the HTML button element (<button>
).
Although a slight oversimplification, I think David MacDonald’s heuristic works well:
If it GOES someWHERE use a link
If it DOES someTHING use a button
A link…
- goes somewhere (i.e. navigates to another place)
- normally links to another document (i.e. page) on the current website or on another website
- can alternatively link to a different section of the same page
- historically and by default appears underlined
- when hovered or focused offers visual feedback from the browser’s status bar
- uses the “pointing hand” mouse pointer
- results in browser making an HTTP
GET
request by default. It’s intended to get a page or resource rather than to change something - offers specific right-click options to mouse users (open in new tab, copy URL, etc)
- typically results in an address which can be bookmarked
- can be activated by pressing the return key
- is announced by screen readers as “Link”
- is available to screen reader users within an overall Links list
A button…
- does something (i.e. performs an action, such as “Add”, “Update” or "Show")
- can be used as
<button type=submit>
within a form to submit the form. This is a modern replacement for<input type=submit />
and much better as it’s easier to style, allows nested HTML and supports CSS pseudo-elements - can be used as
<button type=button>
to trigger JavaScript. This type of button is different to the one used for submitting a<form>
. It can be used for any type of functionality that happens in-place rather than taking the user somewhere, such as expanding and collapsing content, or performing a calculation. - historically and by default appears in a pill or rounded rectangle
- uses the normal mouse pointer arrow
- can be activated by pressing return or space.
- implictly gets the ARIA button role.
- can be extended with further ARIA button-related states like
aria-pressed
- is announced by screen readers as “Button”
- unlike a link is not available to screen reader users within a dedicated list
Our responsibilities
It’s our job as designers and developers to use the appropriate purpose-built element for each situation, to present it in a way that respects conventions so that users know what it is, and to then meet their expectations of it.
Tips
- Visually distinguish button-styled call-to-action links from regular buttons, perhaps with a more pill-like appearance and a right-pointing arrow
- Avoid a proliferation of call-to-action links by linking content itself (for example a news teaser’s headline). Not only does this reduce “link or button?” confusion but it also saves space, and provides more accessible link text.
- Consider having separate Design System components for Button and ButtonLink to reinforce important differences.
- For triggering JavaScript-powered interactions I’ll typically use a
button
. However in disclosure patterns where the trigger and target element are far apart in the DOM it can make sense to use a link as the trigger. - For buttons which are reliant on JavaScript, it’s best to use them within a strategy of progressive enhancement and not render them on the server but rather with client-side JavaScript. That way, if the client-side JavaScript is unsupported or fails, the user won’t be presented with a broken button.
Update: 23 November 2024
Perhaps a better heuristic than David MacDonald’s mentioned above, is:
Links are for a simple connection to a resource; buttons are for actions.
What I prefer about including a resource is that the “goes somewhere” definition of a link breaks down for anchors that instruct the linked resource to download (via the download
attribute) rather than render in the browser, but this doesn’t. I also like the inclusion of simple because some buttons (like the submit button of a search form) might finish by taking you to a resource (the search results page) but that’s a complex action not a simple connection; you’re searching a database using your choice of search query.
References
- Get safe, by Jeremy Keith
- Buttons vs. Links, by Eric Eggert
- The Button Cheat Sheet, by Manuel Matuzović
- A complete guide to links and buttons on CSS-Tricks
- The Links vs Buttons Showdown, by Marcy Sutton
Broken Copy, on a11y-101.com
Here’s an accessibility tip that’s new to me. When the content of a heading, anchor, or other semantic HTML element contains smaller “chunks” of span
and em
(etc), the VoiceOver screen reader on Mac and iOS annoyingly fails to announce the content as a single phrase and instead repeats the parent element’s role for each inner element. We can fix that by adding an inner “wrapper” element inside our parent and giving it role=text
.
Make sure not to add this role directly to your parent element since it will override its original role causing it to lose its intended semantics.
The text
role is not yet in the official ARIA spec but is supported by Safari.
(via @Seraphae and friends on Twitter)
The accessibility of conditionally revealed questions (on GOV.UK)
Here’s something to keep in mind when designing and developing forms. GOV.UK’s accessibility team found last year that there are some accessibility issues with the “conditional reveal” pattern, i.e. when selecting a particular radio button causes more inputs to be revealed.
The full background story is really interesting but the main headline seems to be: Keep it simple.
- Don’t reveal any more than a single input, otherwise the revealed section should not be in a show-and-hide but rather in its own form in the next step of the process.
- Conditionally show questions only (i.e. another form input such as Email address)—do not show or hide anything that’s not a question.
Doing otherwise causes some users confusion making it difficult for them to complete the form.
See also the Conditionally revealing a related question section on the Radios component on the GDS Design System
Accessibility Testing (on adactio.com)
In this journal entry, Jeremy Keith argues that when it comes to accessibility testing it’s not just about finding issues—it’s about finding the issues at the right time.
Here’s my summary:
- Accessibility Audits performed by experts and real Assistive Technology users are good!
- But try to get the most out of them by having them focus on the things that you can’t easily do yourself.
- We ourselves can handle things like colour contrast. It can be checked at the design stage before a line of code is written.
- Likewise HTML structure such as ensuring accessible form labels, ensuring images have useful
alt
values, using landmarks likemain
andnav
, heading structure etc. These are not tricky to find and fix ourselves and they have a big accessibility impact. - As well as fixing those issues ourselves we should also put in place new processes, checks and automation if possible to stop them recurring
- As for custom interactive elements (tabs, carousels, navigation, dropdowns): these are specific to our site and complicated/error-prone by nature, so those are the things we should be aiming to have professional Accessibility Audits focus on in order to get best value for money.
Accessible Color Generator
There are many colour contrast checking tools but I like this one from Erik Kennedy (of Learn UI Design) a lot. It features an intuitive UI using simple, human language that mirrors the task I’m there to achieve, and it’s great that if your target colour doesn’t have sufficient contrast to meet accessibility guidelines it will intelligently suggest alternatives that do.
I’m sure everyone has their favourite tools; I just find this one really quick to use!
Should I use the HTML5 section element and if so, where?
Unlike other HTML5 elements such as header
, footer
and nav
, it’s never been particularly clear to me when is appropriate to use section
. This is due in large part to many experts having expressed that it doesn’t quite work as intended.
I like HTMHell’s rule-of-thumb regarding section
:
If you’re not sure whether to use a
<section>
, it’s probably best to avoid it.
They go on to recommend that it’s much more important to create a sound document outline. That phrase can be confusing because of the related history of the browser document outline algorithm (or lack thereof) but I think what the author means here is to use and nest headings logically because that alone will give you a “document outline” and also helps AT users scan and skip around the page.
Relatedly: don’t let the original intended use of section
tempt you to put multiple H1s on a page in the vain hope that browsers and assistive technology will interpret their nesting level to handle hierarchy appropriately. That would rely on on a document outline algorithm but no browser implements document outlining.
One sensible application of section
is to provide additional information to screen reader users about the semantic difference between two adjoining content areas, when that distinction is otherwise only being made visually with CSS.
Here’s an example. Smashing Magazine’s blog articles begin with a quick summary, followed by a horizontal line separating the summary from the article proper. But the separator is purely decorative, so if the summary were wrapped in a div
then a screen reader user wouldn’t know where it ends and the article begins. However by instead wrapping the summary in <section aria-label="quick summary">
:
- our wrapper has the built-in ARIA role of
region
. Aregion
is a type of generic landmark element, and as a landmark a screen reader user will find it listed in a summary of the page and can navigate to it easily. - by giving it an accessible name (here via
aria-label
) it will be announced by a screen reader, with “Quick summary region” before and “Quick summary region end” after.
Update 07/11/22
Adrian Roselli’s twitter thread on section is gold. Here’s what I’ve gleaned from it:
The reason you would use a section
element for accessibility purposes is to create a region
landmark. If you are using headings properly, in most cases your content is already well-structured and will not require a region landmark. If you do need a section, note that from an accessibility perspective using the section
tag alone is meaningless without providing an accessible name. To provide this, ensure your section has a heading and connect the section
to that using aria-labelledby
.
You can use section
without the above measures and it will not harm users. But be aware it’s aiding your developer experience only, because it’s not helping users. And it may also mislead you and others into thinking you are providing semantics and accessibility which in reality you are not.
References:
- Accessibility of the section element, by Scott O’Hara
- Why you should choose HTML5
article
oversection
, by Bruce Lawson
Inclusive language around buttons
@Amy_Hupe recently posed a great question on Twitter regarding inclusive language for buttons:
What's an inclusive way to describe what you do to a (digital) button, given it might be pressed with a mouse click, a screen tap, a key on a keyboard, and so on? I've tended to use "select" but wondering if that's right?
There are a lot of good suggestions and my current feeling is that:
- it depends. What’s right for one context may not be for another; and
- there are a few good ones.
My favourites are:
- use;
- “click or tap”; and maybe
- press (which may work as a common abstraction).
I also offerered this alternative/remix:
Could another way to do this / work around the awkwardness be via the pattern “Do thing X by using the Y button”? i.e. describe the action/result, making the button itself less important so you can just use “using” as your verb. So… “Submit the form using the “Submit” button”.
“via” is another word/pattern that’d similarly allow less need to worry about physical stuff. So “Launch a preview via the “Preview” button”. Same idea as “using”.
And I liked Craig Abbot’s observation:
it’s actually a bit weird to describe the physical interactions anyway. It should be intuitive. If a button says continue, it’s pretty obvious you need to interact with it. If you need to explain the UI usually there’s a bigger problem.
I’m not such a fan of these suggestions:
- select; and
- activate
Changing visual order with CSS
When considering using Flexbox or CSS Grid to change the visual order of elements, remember that “with great power comes great responsibility”.
Flexbox and CSS Grid have given us new powers to shuffle the visual order of elements on a web page such that it is different to the element order in the source code.
However many smart developers have rightly pointed out that although this is really convenient and can help in conquering gnarly design and responsive challenges, it’s often not a good idea. Rachel Andrew in particular has regularly offered the following advice:
Don’t fix source problems with Grid or Flexbox.
See Rachel’s talk Grid, content re-ordering and accessibility for more detail.
So, what’s the problem?
Essentially we cause people problems when we create a disconnect between tabbing order and visual order.
Let’s dig into the detail.
People browse web pages in different ways
We know that a web page’s visitors are likely to have a range of different abilities. While some experience the full extent of our visual design, others are visually-impaired or blind. Others still have motor impairments. The web was intended to be accessible and therefore web pages should cater appropriately to this range of user needs.
Relatedly we also know that people will use one or more of the following methods to move around a web page:
- a thumb and fingers;
- a mouse (or trackpad) and keyboard;
- a keyboard alone.
There are probably other methods I’m forgetting, but those are the most common.
In order to cater to people who navigate a web page using a keyboard without a mouse (a.k.a. keyboard users), we must ensure that the page is tab-friendly. We want the page’s interactive elements to be navigable and focusable by pressing the Tab key. Those elements should be focusable one by one in the same order as they are defined in the HTML document.
Often, achieving tab-friendliness requires little or no additional development effort because the browser gives us so much of the necessary behaviour natively. Interactive HTML elements like anchors (links) and form controls are focusable by default. And for any custom interactions where we want to make a normally non-focusable element (such as a div
) focusable (thus giving it a keyboard tab-stop) we can apply the tabindex attribute, setting its tabindex="0"
.
A simple, well-formed web page will natively offer a natural and predictable tabbing order.
With CSS Grid and Flexbox we now have new CSS options such as order
, flex-direction: row-reverse
and grid-auto-flow
which let us reorder elements on the page. This can be really handy for situations where a design spec calls for Element 1 to appear above Element 2 on narrow viewports but to its right on wider viewports. Using these new CSS properties we might let the elements follow the source order on narrow viewports but change their order within a media query for wider viewports.
However this means we are now messing with the natural order of things. And if we move focusable elements around such that their visual order is different from their source order this creates a disconnect between tabbing order and visual order.
The disconnect is unlikely to be apparent to sighted people on a tablet/phone or on a desktop setup and navigating with their mouse, because they are not using tab to navigate. Blind users using a screen reader will be similarly unaffected because they don’t experience the visual order.
We might assume that all keyboard (only) users are also blind, using a screen reader, and not perceiving visual order. However keyboard users also include sighted people who have trouble operating a pointing device such as a mouse or trackball, or whose mouse is currently not working, or who simply prefer to use a keyboard where possible.
For the sighted person who navigates by keyboard our change of order would be confusing. When you use tab and expect that to follow convention and set focus on one element but it actually sets focus on another, you’ll likely assume that something is broken.
Rachel Andrew argues that creating this kind of disconnect is to be avoided. Léonie Watson suggests that in simple examples such a disconnect may only be mildly awkward, however in complex interfaces it could make things horribly unusable.
Is it ever OK to change visual order with CSS?
At work I recently reviewed a PR where the visual order of a Flexbox layout was being updated via order: -1
in a media query for wide viewports. Although it was a really elegant solution on paper, I advised caution in light of the pitfalls mentioned above.
However a colleague rightly pointed out that the elements being reordered were two div
s. In this case and any others where the elements (and their children) are non-focusable and we’re not messing with the likes of navigation links or form elements, I think we are safe.
The Future
We’ve recently been given a few new CSS layout powers only to subsequently be advised not to use them.
How do we move forward?
Rachel Andrew argues that this problem needs addressed at a CSS level; that developers should be able to set the tab and reading order to follow the visual rather than source order under certain circumstances.
Until that becomes a CSS reality we should continue to be judicious in our usage to ensure we don’t break user expectations. We can also use tools like the Source Order Viewer in Chrome DevTools (DevTools > Elements > Accessibility) to check our work.
In Praise of the Unambiguous Click Menu (on CSS-Tricks)
Mark Root-Wiley explains why navigation menus that appear on click rather than hover are better.
I like the fact that it calls out that:
When you first make this change, it’s true that some visitors might still expect hover menus. They may even say they prefer them if you ask.
But then goes on to provide some rationale (ammunition?) from various big guns on why click menus are better.
From the US Web Design System:
Avoid using hover to expand dropdown lists. Hover is difficult for some users and won’t work on touch screens. Dropdowns should expand on click or with keyboard navigation.
From popular frontend framework Bootstrap:
What it really boils down to is user intent. The purpose of a hover state is to indicate something is clickable (underlined text). The purpose of a click is to actually do something, to take an explicit action. Opening a dropdown is an explicit action and should only happen on click.
(via @jamesmockett)
Use Mac Zoom to show the text a screen reader gets
I picked up a good accessibility testing tip from my work colleague Max today.
On a Mac, if you open System > Accessibility > Zoom, you can enable “hover text”. This allows you to hold down command (cmd) and then whatever is under the mouse will be shown. This shows the same text that a screen reader sees so it’s good for checking if bits of the page respond to a screen reader.
Accessible interactions (on Adactio)
Jeremy Keith takes us through his thought process regarding the choice of link or button
when planning accessible interactive disclosure elements.
A button
is generally a solid choice as it’s built for general interactivity and carries the expectation that when activated, something somewhere happens. However in some cases a link might be appropriate, for example when the trigger and target content are relatively far apart in the DOM and we feel the need move the user to the target / give it focus.
For a typical disclosure pattern where some content is shown/hidden by an adjacent trigger, a button
suits perfectly. The DOM elements are right next to each other and flow into each other so there’s no need to move or focus anything.
However in the case of a log-in link in a navigation menu which—when enhanced by JavaScript—opens a log-in form inside a modal dialogue, a link might be better. In this case you might use an anchor with a fragment identifier (<a href="#login-modal">Log in</a>
) pointing to a login-form far away at the bottom of the page. This simple baseline will work if JavaScript is unavailable or fails, however when JavaScript is available we can intercept the link’s default behaviour and enhance things. Furthermore because the expectation with links is that you’ll go somewhere and modal dialogues are kinda like faux pages, the link feels appropriate.
While not explicit in the article, another thing I take from this is that by structuring your no-JavaScript experience well, this will help you make appropriate decisions when considering the with-JavaScript experience. There’s a kind of virtuous circle there.
Assistiv Labs
A tool for testing how accessible your experience is on various assistive technologies – perhaps “like BrowserStack but for screen readers”?
Assistiv Labs remotely connects you to real assistive technologies, like NVDA, VoiceOver, and TalkBack, using any modern web browser.
I use a Mac for development which means that when I do screen reader testing I use the Mac’s VoiceOver tool. However the majority of screen reader users are using NVDA via Firefox on a PC. Perhaps this tool might let me test on that stack without buying a PC.
Next action: sign up for a free trial and give it a go!
(via Matthew and @paddyduke)
A11y is not “extra effort for people with disabilities”
Strong agree with these sentiments regarding accessibility expressed by Max Böck and Andrey Okonetchnikov on Twitter.
From Andrey:
If you’re building UI, it’s your responsibility to make it work for everyone. Clients often tell me “we don’t care about accessibility” but in reality they do want keyboard support at the very least. So I just build my UI in a way it works without discussing it. It’s my job.
To which Max replies:
This. A11y is not “extra effort for people with disabilities”, it‘s just part of a well-crafted UI.
Creating websites with prefers-reduced-data (on polypane.app)
Even though more and more people get access to the internet every day, not all of them have fast gigabit connections or unlimited data. Using the media query prefers-reduced-data we can keep our sites accessible to everyone.
I’ve long wondered if there could be a way to tailor content to a user based on the speed of their internet connection, especially when considering features like responsive images. This looks like it might be the way to do that (although browser support is currently non-existent). It also allows us to respect the user’s wishes on how much data / battery life etc they’re willing to spare for your website.
(via @adactio)
My Screen Reader Cheatsheet
Here’s a list of useful Screen Reader commands and tips for my reference and yours. This is a work in progress and I’ll update it as I go.
VoiceOver (Mac)
Initial setup:
- Open Safari > Preferences > Advanced; then
- check the checkbox “Press tab to highlight each item on a webpage”.
Usage
- Open the page you want to test in your web browser (you might favour Safari for VoiceOver).
- Cmd-F5 to turn VoiceOver on.
- Cmd-F5 (again) to turn VoiceOver off.
Get Cmd-F5 for “toggling on and off” into your muscle memory!
Then:
- Ctrl-Option-A to have VoiceOver read the entire page.
- Ctrl to pause VoiceOver, and Ctrl again to resume.
- Find any unexpected issues by
Tabbing
Tab through items on the page using the tab key. This will move to the next focusable item (button, link, input). You can verify all interactive elements have a focus style, all interactive elements are reachable by keyboard, all off-screen or hidden elements don’t get focused when they shouldn’t and that the spoken label for each interactive element has sufficient context to understand it (“click here” and “menu” isn’t sufficient).
Navigating with the right-pointing arrow key
Navigate through all the content using Ctrl-Option-→. While this is not how most screen reader users will read the page, it doesn’t take long and lets you confirm that everything VoiceOver announces makes sense.
Using Rotor to scan and jump to specific elements
- Ctrl-Option-U to open Rotor
- Browse categories using left and right arrows. This includes the Landmarks menu.
- Down arrow to browse within the categories
- press Return to select an item
This is a great way to check if your content structure makes sense to a screen reader. Checking the headings illustrates the outline of the page. Viewing the links helps ensure they all have a name that makes sense without visual context. Checking landmarks helps ensure that the proper ARIA roles have been applied. You might find that a list of articles is not titled appropriately or that headings are not properly nested.
Tables
- Navigate to a table using Ctrl-Option-Cmd-T
- It should read a caption and give you info about the size of the table
- Ctrl-Cmd-{arrowkey} to navigate inside the table.
References
How-to: Create accessible forms - The A11Y Project
Here are five bite-sized and practical chunks of advice for creating accessible forms.
- Always label your inputs.
- Highlight input elements on focus.
- Break long forms into smaller sections/pages.
- Provide error messages (rather than just colour-based indicators)
- Avoid horizontal layout forms unless necessary.
I already apply some of these principles, but even within those I found some interesting takeaways. For example, the article advises that when labelling your inputs it’s better not to nest the input within a <label>
because some assistive technologies (such as Dragon NaturallySpeaking) don’t support it.
I particularly like the idea of using CSS to make the input which has focus more obvious than it would be by relying solely on the text cursor (or caret).
input:focus {
outline: 2px solid royalblue;
box-shadow: 1px 1px 8px 1px royalblue;
}
(via @adactio)
The Atkinson Hyperlegible Font (Braille Institute)
Braille Institute launch a new, free typeface promising greater legibility and readability for low vision readers.
What makes it different from traditional typography design is that it focuses on letterform distinction to increase character recognition, ultimately improving readability.
via @brucel
How to hide elements on a web page
In order to code modern component designs we often need to hide then reveal elements. At other times we want to provide content to one type of user but hide it from another because it’s not relevant to their mode of browsing. In all cases accessibility should be front and centre in our thoughts. Here’s my approach, heavily inspired by Scott O’Hara’s definitive guide Inclusively Hidden.
Firstly, avoid the need to hide stuff. With a bit more thought and by using existing fit-for-purpose HTML tools, we can perhaps create a single user interface and experience that works for all. That approach not only feels like a more equal experience for everyone but also removes margin for error and code maintenance overhead.
With that said, hiding is sometimes necessary and here are the most common categories:
- Hide from everyone
- Hide visually (i.e. from sighted people)
- Hide from Assistive Technologies (such as screen readers)
Hide from everyone
We usually hide an element from everyone because the hidden element forms part of a component’s interface design. Typical examples are tab panels, off-screen navigation, and modal dialogues that are initially hidden until an event occurs which should bring them into view. Initially these elements should be inaccessible to everyone but after the trigger event, they become accessible to everyone.
Implementation involves using JavaScript to toggle an HTML attribute or class on the relevant element.
For basic, non-animated show-and-hide interactions you can either:
- toggle a class which applies
display: none
in CSS; or - toggle the boolean
hidden
attribute, which has the same effect but is native to HTML5.
Both options work well but for me using the hidden
attribute feels a little simpler and more purposeful. My approach is to ensure resilience by making the content available in the first instance in case JavaScript should fail. Then, per Inclusive Components’ Tabs example, JavaScript applies both the “first hide” and all subsequent toggling.
Here’s some CSS that supports both methods. (The hidden
attribute doesn’t strictly need this but it’s handy to regard both options as high-specifity, “trump-everything-else” overrides.)
.u-hidden-from-everyone,
[hidden] {
display: none !important;
}
For cases where you are animating or sliding the hidden content into view, toggle the application of CSS visibility: hidden
because this also removes the element from the accessibility tree but unlike display
, can be animated. Note that with visibility: hidden
the physical space occupied by the element is still retained, therefore it’s best to pair it with position: absolute
or max-height: 0px; overflow: hidden
to prevent that “empty space while hidden” effect. For example:
.off-canvas-menu {
visibility: hidden;
position: absolute;
transform: translateX(-8em);
transition: 250ms ease-in;
}
[aria-expanded="true"] + off-canvas-menu {
visibility: visible;
transform: translateX(0);
transition: visibility 50ms, transform 250ms ease-out;
}
Hide visually (i.e. from sighted people)
We’ll usually want to hide something visually (only) when its purpose is solely to provide extra context to Assistive Technologies. An example would be appending additional, visually-hidden text to a “Read more” link such as “about Joe Biden” since that would be beneficial to screen reader users.
We can achieve this with a visually-hidden
class in CSS and by applying that class to our element.
.visually-hidden:not(:focus):not(:active) {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
Essentially this hides whatever it’s applied to unless it’s a focusable element currently being focused by screen reader controls or the tab key, in which case it is revealed.
Note that if adding to link text to make it more accessible, always append rather than inserting words into the middle of the existing text. That way, you avoid solving an accessibility for one group but creating another for another group (Dragon speech recognition software users).
Visually hidden until focused
There are other CSS approaches to hiding visually. One approach is to not only add position: absolute
(removing the element from the document flow) but also position it off-screen with left: -100vw
or similar. The use case for this approach might be when you want your visually hidden element to support being revealed and for that reveal to occur via a transition/animation from off-screen into the viewport. See Scott O’Hara’s off screen skip-links example.
Hide from Assistive Technologies (such as screen readers)
We sometimes hide visual elements from Assistive Technologies because they are decorative and have accompanying text, for example a “warning” icon with the text “warning” alongside. If we did not intervene then Assistive Technologies would read out “warning” twice which is redundant.
To achieve this we can apply aria-hidden="true"
to our element so that screen readers know to ignore it. In the following examples we hide the SVG icons within buttons and links, safe in the knowledge that the included “Search” text is providing each interactive element with its accessible name.
<button>
<svg aria-hidden="true" focusable="false"><!--...--></svg>
Search
</button>
<a href="/search">
<svg aria-hidden="true" focusable="false"><!--...--></svg>
Search
</a>
Reference: Contextually Marking up accessible images and SVGs
Better Alt Text
I’ve just read The A11Y Project’s page on alt
text.
As most of us know, the HTML alt
attribute is for providing “alternate text” descriptions of images to help ensure people do not miss out on information conveyed by graphics. This can help people using assistive technology such as screen readers, and in situations where images are slow or fail to load.
The article made some interesting points and even though I’ve been using the alt
attribute for years I found three common cases where I could improve how I do things.
Avoid starting with “photo of…”
Don’t begin alternative text with “photo of…” or “picture of…”. Assistive technologies already indicate the role of the element as an “image” or “graphic”. Redundancy makes for a poor user experience.
Avoid including the word “logo” in logo images
If the image is a company’s logo, the alt
should be the company’s name. Adding the word “logo” as part of the alternative text is neither necessary nor useful. (One thing I found helpful here is to think of the way I, as a sighted person, perceive Apple’s logo. I just think “Apple”, not “Apple’s logo”, so I guess the same principle applies.)
If using an image multiple times on the page, tailor the alt
text
Using an image several times in a website doesn't necessarily mean the alt attribute should be the same for each instance. For example, when using a logo in the website’s header this often doubles as a link back to the home page. In this example, the alt
would be most useful as “Apple - Homepage”. If that same logo were used in the footer of the site alongside the text “Apple, copyright 20XX”, then the logo should have an empty alt (alt="") so as to avoid creating a redundant announcement of the company’s name.
Setting an accessibility standard for a UK-based commercial website
When advocating accessible web practices for a commercial website, the question of “what does the law require us to do?” invariably arises.
The appropriate answer to that question should really be that it doesn’t matter. Regardless of the law there is a moral imperative to do the right thing unless you are OK with excluding people, making their web experiences unnecessarily painful, and generally flouting the web’s founding principles.
However as Web Usability’s article What is the law on accessibility? helpfully advises, in the UK the legal situation is as follows:
“The accessibility of a UK web site is covered by the Equality Act 2010” (which states that) “Site owners are required to make ‘reasonable adjustments’ to make their sites accessible to people with disabilities”. While “there is no legal precedent about what would constitute a ‘reasonable adjustment’”, “given that the Government has adopted the WCAG 2.1 level AA as a suitable standard for public sector sites and it is more broadly recognised as a ‘good’ approach, any site which met these guidelines would have a very strong defence against any legal action.”
So, WCAG 2.1 Level AA is the sensible accessibility standard for your commercial UK-based website to aim for.
While not aimed specifically at the UK market, deque.com’s article What to look for in an accessibility audit offers similar advice:
The most common and widely-accepted standard to test against is WCAG, a.k.a. Web Content Accessibility Guidelines. This standard created by the World Wide Web Consortium (W3C) defines technical guidelines for creating accessible web-based content.
WCAG Success Criteria are broken down into different “levels of conformance”: A (basic conformance), AA (intermediate conformance), and AAA (advanced conformance). The current standard for compliance is both WCAG 2.1 Level A and AA.
If you don’t have specific accessibility regulations that apply to your organization but want to avoid legal risk, WCAG 2.1 A and AA compliance is a reasonable standard to adopt.
Additional references
The difference between aria-label and aria-labelledby (Tink - Léonie Watson)
The
aria-label
andaria-labelledby
attributes do the same thing but in different ways. Sometimes the two attributes are confused and this has unintended results. This post describes the differences between them and how to choose the right one.
The key takeaways for me were:
- Many HTML elements have an accessible name (which we can think of as its “label”) and this can be derived from the element’s content, an attribute, or from an associated element;
- for
aria-labelledby
, use theid
of another element and that will then use that element’s text as your first element’s accessible name; - use native HTML over ARIA where possible, but when you need ARIA it’s better to reuse than duplicate so if an appropriate label already exists in the document use
aria-labelledby
; otherwise usearia-label
; - an ARIA attribute will trump any other accessible name (such as the element’s content)
- there are some elements on which these ARIA attributes do not work consistently so check these before using.
Inclusive Datepicker (by Tommy Feldt)
A human-friendly datepicker. Supports natural language manual input through Chrono.js. Fully accessible with keyboard and screen reader.
Sign-in form best practices (on web.dev)
Sam Dutton advises how to use cross-platform browser features to build sign-in forms that are secure, accessible and easy to use.
The tips of greatest interest to me were:
- on using
autocomplete="new-password"
on registration forms andautocomplete="current-password"
on sign-in forms to tap into browser password suggestion and password manager features; - on how best to provide “Show Password” functionality; and
- on using
aria-describedby
when providing guidance on password rules.
Best practice techniques for SVG Icons
Here’s how I’d handle various common SVG icon scenarios with accessibility in mind.
Just an icon
So this is an icon that’s not within a link or button and has no adjacent text. This might be, for example, an upward-pointing arrow icon in a <td>
in a “league table” where the arrow is intended to indicate a trend such as “The figure has increased” or “Moving up the table”.
The point here is that in this scenario the SVG is content rather than decoration.
<svg
role="img"
focusable="false"
aria-labelledby="arrow-title"
>
<title id="arrow-title">Balance has increased</title>
<path …>…</path
</svg>
Note: Fizz Studio’s article Reliable valid SVG accessibility suggests that the addition of aria-labelledby
pointing to an id for the <title>
(as Léonie originally recommended) is no longer necessary. That’s encouraging, but as it does no harm to keep it I think I’ll continue to include it for the moment.
The same article also offers that maybe we should not use the SVG <title>
element (and use aria-label
to provide an accessible name instead) due to the fact that it leads to a potentially undesirable tooltip, much like the HTML title
attribute does. To be honest I’m OK with this and don’t see it as a problem, and as I mention later have heard probably even more problematic things about aria-label
so will stick with <title>
.
Button (or link) with icon plus text
This is easy. Hide the icon from Assistive Technology using aria-hidden
to avoid unnecessary repetition and rely on the text as the accessible name for the button or link.
<button>
<svg aria-hidden="true" focusable="false" ><!--...--></svg>
Search
</button>
<a href="/search">
<svg aria-hidden="true" focusable="false"><!--...--></svg>
Search
</a>
Button (or link) with icon alone
In this case the design spec is for a button with no accompanying text, therefore we must add the accessible name for Assistive Technologies ourselves.
<button>
<svg focusable="false" aria-hidden="true"><!--...--></svg>
<span class="visually-hidden">Search</span>
</button>
<a href="/search">
<svg focusable="false" aria-hidden="true"><!--...--></svg>
<span class="visually-hidden">Search</span>
</a>
The reason I use text that’s visually-hidden using CSS for the accessible name rather than adding aria-label
on the button or link is because I’ve heard that the former option is more reliable. In greater detail: aria-label is announced inconsistently and not always translated.
References
- Accessible SVG Icons, by Chris Coyier;
- Tips for accessible SVG, by Léonie Watson;
- Reliable, valid SVG accessibility, by Fizz Studio;
- Accessible icon buttons, by Sara Soueidan;
- Every Layout’s Icon component; and
- How to hide elements on a web page, by my bad self.
How to create accessible subtitles (on Go Make Things)
Here’s Chris Ferdinandi, introducing the ARIA doc-subtitle
role.
He sets the scene by describing the popular design pattern where we have a title with a subtitle directly underneath, and that subtitle is set to be visually distinct via its font size being larger than the body text while remaining smaller than the main heading. Developers have typically marked up the subtitle using either another heading element, or a dedicated class. He suggests that the former is bad because headings in HTML are for conveying structure (with the inference that a subtitle is not structural) while the latter is suboptimal because it provides sighted users with additional information that visually impaired users don’t get.
A better approach is coming; the new role=doc-subtitle
will convey to screen readers that the element is a subheading.
I’m going to hold off using it for a little bit until screen reader support improves, but generally this feels like a good move.
Accessibility (on adactio.com)
Here’s Jeremy Keith, making the moral case for accessible websites and why we shouldn’t use “you can make more money by not turning people away” as an argument:
I understand how it’s useful to have the stats and numbers to hand should you need to convince a sociopath in your organisation, but when numbers are used as the justification, you’re playing the numbers game from then on. You’ll probably have to field questions like ”Well, how many screen reader users are visiting our site anyway?” (To which the correct answer is “I don’t know and I don’t care” – even if the number is 1, the website should still be accessible because it’s the right thing to do.)
(via @adactio)
Striking a Balance Between Native and Custom Select Elements (on CSS-Tricks)
We’re not going to try to replicate everything that the browser does by default with a native select element. We’re going to literally use a select element when any assistive tech is used. But when a mouse is being used, we’ll show the styled version and make it function as a select element.
This custom-styled select solution satisfies those who insist on a custom component but retains all the built-in accessibility we get from native form controls. I also really like the use of a @media (hover: hover)
media query to detect an environment with hover (such as a computer with a mouse rather than a mobile browser on a handheld device).
We’ve ruined the Web. Here’s how we fix it. (This is HCD podcast)
During the COVID situation, people have an urgent need to access critical information online. But in 2020, the average webpage is rammed full of large JavaScript files, huge images etc, and as a result is slow to load. This problem is likely to be most keenly felt by those who don’t have the luxury of fast internet – potentially the same people who need access to that critical information the most.
Here’s a brilliant discussion between Gerry McGovern and Jeremy Keith on that problem, suggesting tactics to help fix things such as performance budgets, introducing tactics at the design stage to mimic slow connections and other access constraints, optimising for return visits, progressive enhancement and more.
Loved this!
(via @adactio)
Finding participants for user research - Service Manual (GOV.UK)
It’s also important to do research with all the different kinds of people who may need your service, including those who: have disabilities or use assistive technologies; have limited digital skills or poor literacy; and may need help to use your service.
Useful advice regarding user research from GOV.uk covering how to define participant criteria, find participants for research and handle incentives.
(via @paddyduke)
Block Links: A tricky UI Problem
You have a “card” component which includes a heading, some text, an image, and a link to the full article, and it’s working great. Then along comes a UX requirement that the full card (not just the button or link) should be clickable. This is where things get complicated.
TL;DR
I was recently faced with this challenge while building a component at work and opted to implement a tailored version of Heydon Pickering’s Redundant Click Trick. This felt like the best approach, or perhaps more accurately “the lesser of three evils”. I’ll be monitoring how that performs, but in light of the knowledge and experience gained carrying out this task I’m also starting to think that – like Chris Coyier recently suggested – maybe full-card clickable regions are a bad idea.
Setting the Scene
Let’s say our starting HTML is this:
<div class="card">
<h2>Card Title</h2>
<img src="/path/to/img.jpg" />
<p>This is the body copy for the card. It it is comprised of a few sentences.</p>
<a href="/">Read more</a>
</div>
And the requirement we’ve been given is to make the whole card clickable rather than just the “Read more” link.
Option 1: Stuff everything inside an anchor
Here’s the thing – since the dawn of HTML5 we’ve been able to wrap the inline anchor (<a>
) element around block-level content such as headings, paragraphs, and <div>
s… so isn’t the answer just to do that?
<a href="/">
<div class="card">
<h2>Card Title</h2>
<img src="/path/to/img.jpg" />
<p>This is the body copy for the card. It it is comprised of a few sentences.</p>
</div>
</a>
Well, as with many HTML challenges, just because you can do something doesn’t mean you should. I always had a nagging doubt about stuffing all that disparate content inside a single anchor, and Adrian Roselli has recently confirmed that for screen reader users this approach is harmful.
Perhaps the worst thing you can do for a block link is to wrap everything in the
<a href>
… for a screen reader user the entire string is read when tabbing through controls… taking about 25 seconds to read before announcing it as a link.
Furthermore, images nested in this way are not clearly announced as they normally would be.
So if you care about the user experience for those people, this feels like a no-no.
Option 2: Stretch a standard anchor using pseudo-content
An alternate approach that’s gained traction over the last couple of years involves leaving the anchor or button in its initial position within the card (thereby avoiding the above mentioned accessibility problem) and using pseudo-content to stretch it to cover the entire card. This CSS-only trick involves setting the card to position:relative
then giving the anchor (or button) :after
pseudo-content and absolutely positioning that to the card’s four corners. This makes the whole card clickable like a button.
The problem with this approach is that any text in the card is no longer selectable.
Some might say that this is OK. Personally I feel that it is a fundamental usability requirement that text on a web page be selectable. Not being able to do so calls to mind the bad old days before web fonts where we used images for headings, and I like to think we’ve evolved from those kind of practices. Also, I feel any statement by us developers and designers that “losing the ability to select text is OK” lacks validity because we are biased; happy to justify taking away something fundamental from our users because we’re more concerned with getting a (frankly non-essential) feature over the line.
If we don’t like this compromise but are still determined to make the full card clickable, there’s one further option.
Option 3: The Redundant Click Trick
This technique, conceived by Heydon Pickering, uses JavaScript rather than CSS to make the card clickable.
Essentially we add an EventListener
for a click on the Card and when one is detected, trigger a faux click on the inner anchor or button.
One challenge inherent in this approach is that a user attempting to select text would unintentionally trigger our faux link click. However we can again use JavaScript (using the onmousedown
and onmouseup
events) to detect the length of their press to infer whether they are selecting text or clicking, then take appropriate action.
The pros of this approach are that we avoid the screen reader problems and the inability to select text.
The cons are i) that it requires a more complicated, JavaScript-based approach; and ii) that the need for a “check how long the mouse has been pressed down” part isn’t ideal.
With this approach, if Analytics tracking is part of your mix I’d make sure to check that that works as expected across browsers and devices.
Summing up
So there we go – three ways to achieve a “block link” or button. But given the compromises they involve, perhaps the question should be – is it worth it? And given the tools we currently have available, I lean towards “no”.
References
Block Links, Cards, Clickable Regions etc by Adrian Roselli.
Cards by Heydon Pickering (in Inclusive Components).
Block Links are a pain and maybe just a bad idea by Chris Coyier on CSS-Tricks.
HTML: The Inaccessible Parts (daverupert.com)
Here’s Dave Rupert, frustratedly rounding up the accessibility shortfalls in browser implementations of native HTML elements.
I’ve always abided in the idea that “HTML is accessible by default and then we come along and mess it up”. But that’s not always the case. There are some cases where even using plain ol’ HTML causes accessibility problems.
(via @jamesmockett)
Why the GOV.UK Design System team changed the input type for numbers (Technology in Government)
Using
<input type="text" inputmode="numeric" pattern="[0-9]*">
(instead of<input type="number"
) allows for a degree of separation between how the user enters data (“input mode”), what the browser expects the user input to contain (type equals number), and potentially how it tries to validate it.
An interesting post from the UK Government listing a host of usability and accessibility problems arising from using <input type="number">
.
Now that browser support for the inputmode
attribute is sufficient, they have moved to <input type="text" inputmode="numeric">
.
I trust GOV.UK’s opinion and think I’ll follow suit.
Are My Colours Accessible?
Colour contrast and the use of colour is extremely important for certain groups of people with varying levels of visional impairment. Building upon the excellent Colorable, I wanted more context around the result. When you share the outcome with your colleagues, all the results, rules and what you’re aiming for, is easily understandable for when you have those awkward conversations with designers and marketers. Accessibility doesn’t have to be ugly.
An excellent, easy to use tool for checking text-against-background contrast for accessibility and sharing your results with others.
(via @paddyduke)
The Contrast Triangle
Removing underlines from links in HTML text presents an accessibility challenge. In order for a design to be considered accessible, there is now a three-sided design contraint - or what I call "The Contrast Triangle". Your text, links and background colors must now all have sufficient contrast from each other. Links must have a contrast ratio of 3:1 from their surrounding text. By not using underlines, a design has to rely on contrast alone to achieve this.
It’s interesting that Chip says that this level of contrast is needed “when we don’t use underlines on links”.
By not using underlines, a design has to rely on contrast alone to achieve this.
So this seems to be yet another good reason to include underlines in links, i.e. if you underline your links then you don’t need to worry quite as much about a third level of contrast.
Indeed, when you toggle on the “Show underlines” option on this tool, it then removes the requirement to ensure additional contrast between hyperlinks and standard body text.
However, even if your links in flowing prose are underlined, there’s always likely to be places (Navigation, Footer, CTAs etc) where you’ve probably disabled underlines on links for design effect, so I reckon this is useful for most websites.
(via https://twitter.com/jamesmockett)
BBC GEL Inclusive Components Technical Guide
The BBC Global Experience Language (GEL) Technical Guides are a series of framework-agnostic, code-centric recommendations and examples for building GEL design patterns in websites. They illustrate how to create websites that comply with all BBC guidelines and industry best practice, giving special emphasis to accessibility.
Heydon Pickering (author of Inclusive Components and co-creator of Every Layout) has implemented and documented over 25 of the BBC's design patterns. These are sure to be loaded with best practices and clever tricks for making resilient, accessible modern UI components. (via @heydonworks)
Responsive Type and Zoom (by Adrian Roselli)
When people zoom a page, it is typically because they want the text to be bigger. When we anchor the text to the viewport size, even with a (fractional) multiplier, we can take away their ability to do that. It can be as much a barrier as disabling zoom. If a user cannot get the text to 200% of the original size, you may also be looking at a WCAG 1.4.4 Resize text (AA) problem.
I already tend to avoid dynamic, viewport-width-based fluid typography techniques in favour of making just one font-size adjustment – at a desktop breakpoint – based on the typographic theory that suggests we adjust type size according to reading distance. I learned this in Richard Rutter’s excellent book Web Typography.
While the ideas and code behind the fluid typography approach are nice, Adrian’s discovery that it can hinder users who need to zoom text only strengthens my feeling that it’s not the best way to handle responsive type.
Design Better Forms (UX Collective)
As Andrew Coyle says, “Life is short. No one wants to fill out a form.”. Here, he presents a number of form design tips to make the user experience more bearable and increase completion rates.
Making a Better Custom Select Element (24 ways)
We want a way for someone to choose an item from a list of options, but it’s more complicated than just that. We want autocomplete options. We want to put images in there, not just text. The
optgroup
element is ugly, hard to style, and not announced by screen readers. I had high hopes for thedatalist
element, but it’s no good for people with low vision who zoom or use high contrast themes.select
inputs are limited in a lot of ways. Let’s work out how to make our own while keeping all the accessibility features of the original.
Julie Grundy argues here that despite us having greater ability to style the standard select
in 2019 there are times when that element doesn’t quite meet modern expectations.
This is a lovely, full-featured and fully accessible component. It could perhaps be improved by not showing the down-arrow icon until JavaScript is loaded, but otherwise it’s great.
Julie’s code currently exists solely as a Github repo, but for ease I’ve created this editable version on Codepen.
Will I use this in place of the select
element? Not if I can help it, because after years of experience working with form elements I still trust native elements to work better cross-platform than custom alternatives. However if a design requires dropdown options to employ custom patterns such as media objects, then I’ll definitely reach for this component.
Building an accessible show/hide disclosure component with vanilla JS (Go Make Things)
A disclosure component is the formal name for the pattern where you click a button to reveal or hide content. This includes things like a “show more/show less” interaction for some descriptive text below a YouTube video, or a hamburger menu that reveals and hides when you click it.
Chris’s article provides an accessible means of showing and hiding content at the press of a button when the native HTML details
element isn’t suitable.
Who Can Use
It's a tool that brings attention and understanding to how color contrast can affect different people with visual impairments.
What’s interesting about this resource is that sheds light on the many different types of visual impairment, from Protanomaly (trouble distinguishing reds) to Achromatopsia (complete colour blindness; only being able to see shades) and how your website’s colour scheme fares for each. (via paddyduke.com)
WAVE Web Accessibility Evaluation Tool
The featured article in this week’s Accessibility Weekly newsletter was on recent improvements to the WAVE suite of accessibility testing tools.
I can’t remember using WAVE before, however just one quick test of fuzzylogic.me using their online tool revealed an accessibility issue with the linked SVG logo in the header. A great catch, now fixed, from which I learned something new. I’ll certainly be adding WAVE to my accessibility testing toolbox from here on in.
WAVE is a suite of evaluation tools that help authors make their web content more accessible to individuals with disabilities. WAVE can identify many accessibility and Web Content Accessibility Guideline (WCAG) errors, but also facilitates human evaluation of web content. Our philosophy is to focus on issues that we know impact end users, facilitate human evaluation, and to educate about web accessibility.
Why much of the internet is closed off to blind people – BBC News
Following the recent watershed Domino’s Pizza case, BBC News reports that retailers in the USA & Canada are struggling to make their websites accessible and consumers are taking them to court.
"We've even been told by businesses before that they understand, but the fact is blind people are not a very big market," Mr Danielson says. "That's what we are dealing with."
Colors – a nicer color palette for the web
Skinning your prototypes just got easier - colors.css is a collection of skin classes to use while prototyping in the browser.
They also provide ninety examples of “A11Y compliant color combos” which is really handy.
Beyond Automatic Testing (matuzo.at)
Six accessibility tests Viennese Front-end Developer Manuel Matusovic runs on every website he develops, beyond simply running a Lighthouse audit.
Includes “Test in Grayscale Mode” and “Test with no mouse to check tabbing and focus styles”.
U.S. Supreme Court Favors Digital Accessibility in Domino’s Case
Digital products which are a public accommodation must be accessible, or will be subject to a lawsuit (and probably lose).
This US Supreme Court decision on October 7, 2019 represents a pretty favourable win for digital accessibility against a big fish that was trying to shirk its responsibilities.
Webfont loading strategies
When it comes to webfonts, if you want to serve an accessible and high performance experience across device types it’s not as straightforward as just specifying your fonts in CSS then hoping for the best.
We likely have goals such as the following:
- avoid Flash of Invisible Text (FOIT). Flash of Unstyled Text (FOUT) is preferable.
- provide a good experience for users on slow connections.
- while favouring FOUT over FOIT, take care to minimise jarring reflows.
Browser support is also a factor. For example font-display: swap
seems like a great option however as Chris Ferdinandi pointed out in Why use the vanilla JS fontfaceset.load method instead of CSS font-display: swap it doesn’t have comprehensive mobile support. Since mobile users are regularly on slower connections they are likely to be hit hard by load times incurred due to custom fonts, therefore a solution which doesn’t cater to them is less attractive.
I tend to go for FOUT with a class—an approach that is reliable and good enough for most use cases. The idea is to use JavaScript to detect when a font has loaded successfully, and only then add a fonts-loaded
class to the HTML element causing CSS scoped to that class to take effect. To date I’ve handled the detection using Bram Stein’s Font Face Observer to benefit from greater browser support (it handles IE) than I’d get using the native FontFaceSet.load()
however I expect to gravitate toward the native API solution soon.
I’ve also experimented with pre-loading fonts in the <head>
in combination with font-display: swap
on this, my personal website. This was inspired by the font-loading approach Zach Leatherman took with CSS-Tricks. However due to the fonts I’m using right now I’d currently be preloading too heavy a load for slow connections (thus temporarily blocking initial page render) so I’d need to go further and introduce two-stage loading into that mix.
I’ve also found that your choice of font and font host can really influence (constrain) the flexibility and options you have for font features and loading.
font-display: swap
can only be applied on a self-hosted font or one hosted on Google Fonts (via a special querystring parameter on the font URL). So this CSS-only approach is not available with (for example) fonts hosted on Adobe Fonts or fonts.com.link rel=preload
is only available for self-hosted fonts because you need to be able to rely on the URL not changing, and you can’t rely on that for externally hosted fonts.- You might want to use the opentype features of a font but are they available in your font hosting/loading solution? Some of the fonts hosted on Google Fonts have nice OpenType features but by default these features are pruned out.
- Getting access to the source
.ttf
file is beneficial as it allows you to subset the font, including special features and characters but also cutting out any your website does not require. Google Fonts have an open license which means we don’t need to lean on their hosting but can instead download fonts in.ttf
, subset them (I use Glyphhanger) and self-host them.
This is all a work in progress and I’m still working this stuff out.
Using aria-current is a win-win situation
The HTML attribute aria-current
allows us to indicate the currently active element in a sequence. It’s not only great for accessibility but also doubles as a hook to style that element individually.
By using [aria-current]
as your CSS selector (rather than a .current
class) this also neatly binds and syncs the way you cater to the visual experience and the screen reader experience, reducing the ability for the latter to be forgotten about.
As Léonie Watson explains, according to WAI-ARIA 1.1 there are a number of useful values that the aria-current
attribute can take:
page
to indicate the current page within a navigation menu or pagination section;step
for the current step in a step-based process;date
for the current date.time
for the current time.
I’ve been using the aria-current="page"
technique on a couple of navigation menus recently and it’s working well.
Also: my thanks go to Ethan Marcotte, David Kennedy and Lindsey. Ethan recently suggested that the industry should try harder regarding accessibility and recommended subscribing to David Kennedy’s a11y Weekly newsletter. I duly subscribed (it’s great!) and one of the issues linked to Lindsey’s article An Introduction to ARIA states in which I learned about aria-current
.
Don’t set cursor: pointer on buttons
For many years I’ve been applying cursor: pointer
to buttons because it felt right and would improve the user experience.
As Florens Verschelde explains, that approach is probably best avoided. I was going against the W3C’s spec that cursor: pointer
should be reserved for links, and was adding to the usability antipattern where “everything resembles a link”.
I’ll leave button cursor behaviour as it is from here on in.
Accessible modal dialogues in 2019
I previously noted Keith J Grant’s article on the HTML dialog
element which promised a native means of handling popups and modal dialogues. I’ve not yet used dialog
in production, partly because of spotty browser support (although there is a polyfill) but also partly because—for reasons I couldn’t quite put my finger on after reading the spec—it just didn’t feel like the finished article.
Fast forward to March 2019 and Scott O’Hara has written an excellent piece describing why it’s still not ready. There are a combination of factors: lack of browser support, reliance on JavaScript; and multiple accessibility issues.
The good news is: having dug deeper into Scott’s work I see that among the many accessible components he has shared with the world is a custom, accessible modal dialogue. So next time the need arises, I think I’ll start there.
Thanks, Scott!
Using the tabindex attribute | TPG
Léonie Watson explains how the HTML tabindex attribute is used to manage keyboard focus. Of particular interest to me was a clarification of what tabindex="-1"
does (because I always forget).
tabindex="-1"
The element becomes programmatically focusable but isn’t included in the tab order. It can’t be reached by someone using the tab key to navigate through content, but it can be focused on with scripting via the focus()
method.
We might use this because we want to be able to set focus to a particular element via a script. Léonie offers the example of a list of form errors.
Alternatively we might use this because we want to prevent a normally tabbable element from being tabbable. Sara Souidean uses this technique (in combination with aria-hidden=true
) on e-commerce product teaser “media objects” in order to limit the number of duplicate links that keyboard users must tab through.
Tabindex on page targets to assist with keyboard focus
I’ve often seen tabindex="-1"
used as a companion to the id
attribute on elements of a page intended to be directly accessible via links. Examples include a main
element that should be directly accessible from a “Skip to content” link, or the headings in a blog article to support sharing direct links to page sections.
Before HTML5, creating an internal “link target” required creating an anchor element that used the name
attribute. In HTML5 this use of anchor was deprecated with authors instead encouraged to add the id
attribute to any element they wish. The reason why developers added tabindex="-1"
to their main
and h2
(etc) “targets” is because some older browsers, when responding to a link to such a resource, would move visual focus to the target element (i.e. scroll to it) but not programatically set focus to it if the target element was not focusable. Including tabindex="-1"
solved that problem.
Modern browsers move the focus correctly and so using tabindex
for this purpose is no longer necessary.
tabindex="0"
Applying tabindex="0"
to an element inserts it into the tabbing order based on its position in the source. It is not necessary to apply this to an interactive element such as a button or checkbox since they are focusable by default. You should use it sparingly (because it requires care to ensure accessibility) but you might use it on a custom element which needs to be interactive under certain circumstances such as the horizontally scrollable container in a Data Table.
tabindex="1+"
This imposes a tab order on the content that bears no resemblance to the expected tab order. It’s an antipattern. Don’t do it.
See all tags.