Why the super rich are inevitable
The interactive widgets embedded in this article are excellent teaching tools!
The interactive widgets embedded in this article are excellent teaching tools!
This is a superb explanation of flexbox—the interactive widgets sprinkled throughout are such a great aid to learning!
A lovely website (or web book?) dedicated entirely to colour contrast, complete with interactive illustrative widgets.
A comprehensive guide for exploring and learning about the theory, science, and perception of color and contrast.
This is a story about pizza and geometry.
The interactive widget here really demonstrates the difference between showing and telling.
A fascinating interactive journey through biometrics using your face.
This is a terrific resource! A pattern library of interactive components: tabs, switches, dialogs, carousels …all the usual suspects.
Each component has an example implementation along with advice and a checklist for ensuring its accessible.
It’s so great to have these all gathered together in one place!
I like the split-screen animated format for explaining this topic.
An interesting alternative to using the full Vue library, courtesy of Vue’s creator:
petite-vue
is an alternative distribution of Vue optimized for progressive enhancement. It provides the same template syntax and reactivity mental model with standard Vue. However, it is specifically optimized for “sprinkling” small amount of interactions on an existing HTML page rendered by a server framework.
This is a great deep dive into a single component, a password toggle in this case. It shows how assumptions are challenged and different circumstances are considered in order to make it truly resilient.
A beautiful interactive visualisation of every paper published in Nature.
This is a really nice introduction to CSS transitions with interactive demos you can tinker with.
This is a truly wonderful web page! It’s an explanation from first principles of how cameras and lenses work.
At its most basic, it uses words which you can read in any browser. It also uses images so if your browser supports images, you get that enhancement. And it uses interactive JavaScript widgets so that you get that layer of richness if your browser supports the technology.
Then you realise that every post ever published on this personal site is equally in-depth and uses the same content-first progressive enhancement approach.
Well, this is rather wonderful! It’s like an interactive version of the Eames’s Powers Of Ten.
I wrote a little something recently about using ARIA attributes as selectors in CSS. For me, one of the advantages is that because ARIA attributes are generally added via JavaScript, the corresponding CSS rules won’t kick in if something goes wrong with the JavaScript:
Generally, ARIA attributes—like
aria-hidden
—are added by JavaScript at runtime (rather than being hard-coded in the HTML).
But there’s one instance where I actually put the ARIA attribute directly in the HTML that gets sent from the server: aria-live
.
If you’re not familiar with it, aria-live
is extremely useful if you’ve got any dynamic updates on your page—via Ajax, for example. Let’s say you’ve got a bit of your site where filtered results will show up. Slap an aria-live
attribute on there with a value of “polite”:
<div aria-live="polite">
...dynamic content gets inserted here
</div>
You could instead provide a value of “assertive”, but you almost certainly don’t want to do that—it can be quite rude.
Anyway, on the face it, this looks like exactly the kind of ARIA attribute that should be added with JavaScript. After all, if there’s no JavaScript, there’ll be no dynamic updates.
But I picked up a handy lesson from Ire’s excellent post on using aria-live
:
Assistive technology will initially scan the document for instances of the aria-live attribute and keep track of elements that include it. This means that, if we want to notify users of a change within an element, we need to include the attribute in the original markup.
Good to know!
Sara tweeted something recently that resonated with me:
Also, Pro Tip: Using ARIA attributes as CSS hooks ensures your component will only look (and/or function) properly if said attributes are used in the HTML, which, in turn, ensures that they will always be added (otherwise, the component will obv. be broken)
Yes! I didn’t mention it when I wrote about accessible interactions but this is my preferred way of hooking up CSS and JavaScript interactions. Here’s old Codepen where you can see it in action:
[aria-hidden='true'] {
display: none;
}
In order for the functionality to work for everyone—screen reader users or not—I have to make sure that I’m toggling the value of aria-hidden
in my JavaScript.
There’s another advantage to this technique. Generally, ARIA attributes—like aria-hidden
—are added by JavaScript at runtime (rather than being hard-coded in the HTML). If something goes wrong with the JavaScript, the aria-hidden
value isn’t set to “true”, which means that the CSS never kicks in. So the default state is for content to be displayed. There’s no assumption that the JavaScript has to work in order for the CSS to make sense.
It’s almost as though accessibility and progressive enhancement are connected somehow…
Accessibility on the web is easy. Accessibility on the web is also hard.
I think it’s one of those 80/20 situations. The most common accessibility problems turn out to be very low-hanging fruit. Take, for example, Holly Tuke’s list of the 5 most annoying website features she faces as a blind person every single day:
- Unlabelled links and buttons
- No image descriptions
- Poor use of headings
- Inaccessible web forms
- Auto-playing audio and video
None of those problems are hard to fix. That’s what I mean when I say that accessibility on the web is easy. As long as you’re providing a logical page structure with sensible headings, associating form fields with labels, and providing alt text for images, you’re at least 80% of the way there (you’re also doing way better than the majority of websites, sadly).
Ah, but that last 20% or so—that’s where things get tricky. Instead of easy-to-follow rules (“Always provide alt text”, “Always label form fields”, “Use sensible heading levels”), you enter an area of uncertainty and doubt where there are no clear answers. Different combinations of screen readers, browsers, and operating systems might yield very different results.
This is the domain of interaction design. Here be dragons. ARIA can help you …but if you overuse its power, it may cause more harm than good.
When I start to feel overwhelmed by this, I find it’s helpful to take a step back. Instead of trying to imagine all the possible permutations of screen readers and browsers, I start with a more straightforward use case: keyboard users. Keyboard users are (usually) a subset of screen reader users.
The pattern that comes up the most is to do with toggling content. I suppose you could categorise this as progressive disclosure, but I’m talking about quite a wide range of patterns:
In each case, there’s some kind of “trigger” that toggles the appearance of a “target”—some chunk of content.
The first question I ask myself is whether the trigger should be a button or a link (at the very least you can narrow it down to that shortlist—you can discount div
s, span
s, and most other elements immediately; use a trigger that’s focusable and interactive by default).
As is so often the case, the answer is “it depends”, but generally you can’t go wrong with a button. It’s an element designed for general-purpose interactivity. It carries the expectation that when it’s activated, something somewhere happens. That’s certainly true in all the examples I’ve listed above.
That said, I think that links can also make sense in certain situations. It’s related to the second question I ask myself: should the target automatically receive focus?
Again, the answer is “it depends”, but here’s the litmus test I give myself: how far away from each other are the trigger and the target?
If the target content is right after the trigger in the DOM, then a button is almost certainly the right element to use for the trigger. And you probably don’t need to automatically focus the target when the trigger is activated: the content already flows nicely.
<button>Trigger Text</button>
<div id="target">
<p>Target content.</p>
</div>
But if the target is far away from the trigger in the DOM, I often find myself using a good old-fashioned hyperlink with a fragment identifier.
<a href="#target">Trigger Text</a>
…
<div id="target">
<p>Target content.</p>
</div>
Let’s say I’ve got a “log in” link in the main navigation. But it doesn’t go to a separate page. The design shows it popping open a modal window. In this case, the markup for the log-in form might be right at the bottom of the page. This is when I think there’s a reasonable argument for using a link. If, for any reason, the JavaScript fails, the link still works. But if the JavaScript executes, then I can hijack that link and show the form in a modal window. I’ll almost certainly want to automatically focus the form when it appears.
The expectation with links (as opposed to buttons) is that you will be taken somewhere. Let’s face it, modal dialogs are like fake web pages so following through on that expectation makes sense in this context.
So I can answer my first two questions:
…by answering a different question:
It’s not a hard and fast rule, but it helps me out when I’m unsure.
At this point I can write some JavaScript to make sure that both keyboard and mouse users can interact with the interactive component. There’ll certainly be an addEventListener()
, some tabindex
action, and maybe a focus()
method.
Now I can start to think about making sure screen reader users aren’t getting left out. At the very least, I can toggle an aria-expanded
attribute on the trigger that corresponds to whether the target is being shown or not. I can also toggle an aria-hidden
attribute on the target.
When the target isn’t being shown:
aria-expanded="false"
,aria-hidden="true"
.When the target is shown:
aria-expanded="true"
,aria-hidden="false"
.There’s also an aria-controls
attribute that allows me to explicitly associate the trigger and the target:
<button aria-controls="target">Trigger Text</button>
<div id="target">
<p>Target content.</p>
</div>
But don’t assume that’s going to help you. As Heydon put it, aria-controls
is poop. Still, Léonie points out that you can still go ahead and use it. Personally, I find it a useful “hook” to use in my JavaScript so I know which target is controlled by which trigger.
Here’s some example code I wrote a while back. And here are some old Codepens I made that use this pattern: one with a button and one with a link. See the difference? In the example with a link, the target automatically receives focus. But in this situation, I’d choose the example with a button because the trigger and target are close to each other in the DOM.
At this point, I’ve probably reached the limits of what can be abstracted into a single trigger/target pattern. Depending on the specific component, there might be much more work to do. If it’s a modal dialog, for example, you’ve got to figure out where to put the focus, how to trap the focus, and figure out where the focus should return to when the modal dialog is closed.
I’ve mostly been talking about websites that have some interactive components. If you’re building a single page app, then pretty much every single interaction needs to be made accessible. Good luck with that. (Pro tip: consider not building a single page app—let the browser do what it has been designed to do.)
Anyway, I hope this little stroll through my thought process is useful. If nothing else, it shows how I attempt to cope with an accessibility landscape that looks daunting and ever-changing. Remember though, the fact that you’re even considering this stuff means you care more than most web developers. And you are not alone. There are smart people out there sharing what they learn. The A11y Project is a great hub for finding resources.
And when it comes to interactive patterns like the trigger/target examples I’ve been talking about, there’s one more question I ask myself: what would Heydon do?
This is a nifty visual interactive explainer for the language of CSS—could be very handy for Codebar students.
A useful resource for CSS grid. It’s basically the spec annoted with interactive examples.
Amber documents a very handy bit of DOM scripting when it comes to debugging focus management: document.activeElement
.
This micro libarary does DOM diffing in native JavaScript:
Reef is an anti-framework.
It does a lot less than the big guys like React and Vue. It doesn’t have a Virtual DOM. It doesn’t require you to learn a custom templating syntax. It doesn’t provide a bunch of custom methods.
Reef does just one thing: render UI.