Further reading: Seriously, Don't Use Icon Fonts (article by Tyler Sticka)
<ul>
and <ol>
I can't make a list (heh!) of problematic HTML and not include lists in there.
I'm not going to say “don't use lists”; lists are very useful in many scenarios. But developers have a tendency to overuse lists, often just to remove list styles anyway. Sometimes we may even slap an ARIA role on it (thus overriding the list semantics), or worse, add non-<li>
children for styling purposes or otherwise (thus producing invalid markup). In all of these scenarios, we are losing any benefit provided by list elements, and potentially introducing new issues.
Safari has noticed this overuse of lists, dubbing it "list-itis", and has started removing list semantics in certain cases; lists that are outside a nav
and are styled with list-style: none
are not considered to be lists by Safari. While this change was surely done with good intentions, it has the unfortunate effect of making even legitimately styled lists purely presentational.
In addition to all of this, ordered lists have their own oddities. Browsers consider the item numbers to be "presentational", so when selecting and copying a list, the numbers are not included in the plain-text clipboard entry. This breaks user expectations, especially when the numbers are important, as in the case of legal documents.
Impact: Low to medium. I think it's totally fine to let Safari/VoiceOver do its thing; in fact, their users are likely used to it and may even expect an almost list-free web. The clipboard issue with ordered lists can be quite serious, but there are workarounds.
What to use instead: If you really need to preserve list semantics, role="list"
can be added to <ul>
. If you're already using a different role, then plain <div>
s should work fine. <dl>
is another potential alternative for key-value pairs.
<ul role="list">
<li>…</li>
<li>…</li>
<li>…</li>
</ul>
If the list item numbers are important, consider using unordered lists where the numbers are part of the text content.
Further reading: "Fixing" Lists (article by Scott O'Hara), Twitter thread by Apple's James Craig, and "I Blame the W3C's HTML Standard for Ordered Lists" (article by Sibylla Bostoniensis).
title
attributeThe title
attribute is the one that frustrates me the most, particularly because of its long history. It is so bad that the HTML spec explicitly warns against using it. And yet I've seen this attribute used in almost every codebase I've worked with.
Some of the many issues with title
include:
title
content.title
content.title
content should be part of the element's accessible name or description (or neither).title
content on all elements.Impact: High. By relying on this attribute, you are making the intentional choice of leaving out a large percentage of your users.
What to use instead: In many cases, including the text as part of the element's content can suffice; this text could be visually-hidden if necessary. In other cases, aria-labelledby
or aria-describedby
will work better than title
. One exception is iframes, which need to be labeled using title
.
In almost all cases, a custom tooltip, in addition to the techniques described above, would also work better than title
. However, tooltips come with their own set of problems, so an even better solution would be to redesign the interface to avoid needing tooltips altogether. For example, you could always show the text or use a disclosure pattern.
Further reading: The Trials and Tribulations of the Title Attribute (article by Scott O'Hara), and Using the HTML title attribute (article by Steve Faulkner).
<datalist>
At first, the datalist
element sounds like a promising alternative to custom comboboxes. The more you use it though, the more disappointed you'll find yourself.
color-scheme
.Impact: Medium to high. At best, this element can be useful as an optional hint for input fields that would still be perfectly usable without the added help from autocompleting options.
What to use instead: <select>
or a custom combobox. 🤷
Further reading: Under-Engineered Comboboxen? (article by Adrian Roselli)
<input placeholder>
Placeholder text is intended to help the user by providing a hint when an input is empty. In practice, it often ends up doing the opposite.
Placeholder text is usually prone to color contrast issues. If you try fixing color contrast, it may end up looking indistinguishable from real input values. If you put important information in it (like password requirements, or god forbid, the label itself), the input value will hide this important information as soon as the user starts typing.
Impact: Medium to high. At best, it may be ignored. At worst, it may frustrate your users and impact your revenue.
What to use instead: Nothing? A prominently visible label may be sufficient. If you do need hint text, consider placing it outside the input, and associating it using aria-describedby
.
<label for="phone">Phone number</label>
<input id="phone" aria-describedby="phone-hint" />
<div id="phone-hint">Example: 123-456-7890</div>
Further reading: Don't Use The Placeholder Attribute (article by Eric Bailey)
<input type=number>
Let's cut to the chase: number inputs will increment/decrement when using scroll wheel or gesture or arrow keys, making it extremely prone to accidents. Yikes!
And that's in addition to its other accessibility, consistency, and styling issues.
Impact: High. The scrolling issue alone is enough to make this a dealbreaker, as users could enter the wrong number without even realizing.
What to use instead: <input inputmode="numeric" pattern="[0-9]*">
. The inputmode
attribute helps show a nicer keyboard on touchscreen devices, and the pattern
attribute helps with validation.
Further reading: Why the GOV.UK Design System team changed the input type for numbers
<input type=date>
Native date pickers have many browser inconsistencies, with some parts of them being inaccessible.
In all environments, the date format is shown as placeholder text which, as we've already established above, is problematic. The browser determines the date format, and it may choose something strange (like the US date format), leading to unnecessary confusion.
Impact: High. These inconsistencies are not just minor differences, they introduce real barriers to access.
What to use instead: Honestly, use simple text inputs, or even selects in some cases.
You can also use separate inputs for date/month/year and group them with a fieldset. This fieldset could even be styled to look like one contiguous form field. If you choose to hide the input labels though, I would also suggest showing the date format outside the inputs (as part of the legend or below the inputs).
Custom date pickers are notoriously hard to get right, so if you choose to one, it should be optional and in addition to the text inputs.
Further reading watching: What makes an accessible date picker? Is it even possible? (talk by Russ Weakley)
<menu>
Just don't. Whatever you expect this element does… it probably doesn't. The <menu>
element was originally intended to be a "context menu" but it never got anywhere, and now it is replaced by <ul>
.
Impact: Low. <menu>
is simply remapped to <ul>
.
What to use instead: Because the term “menu” is so overloaded, it depends on what you're trying to accomplish. Some alternatives include:
<ul>
(or role="list"
) when you have a list.role="menu"
when you have a desktop-like menu.role="listbox"
when you have something resembling a custom <select>
.<dialog>
or role="dialog"
when you have a generic popover (perhaps with a role="list"
inside).Do note that some of these roles require custom JavaScript interactions to be wired up.
Further reading: Be Careful Using 'Menu' (article by Adrian Roselli)
<button disabled>
Disabled buttons are strangely overused, perhaps due to their familiarity. Two common scenarios for disabled buttons include:
However, the disabled
attribute does more than just prevent clicks. It also prevents hover and focus capabilities. This has many negative ramifications. Disabled buttons cannot show tooltips (which may be important for explaining why the button is disabled). Keyboard users cannot Tab to disabled buttons. If a button suddenly becomes disabled (e.g. when submitting a form), focus could get lost and create a confusing experience. Additionally, disabled buttons are exempt from color contrast requirements, increasing the likelihood that it will have poor contrast.
Impact: High. Disabled buttons selectively serve a small percentage of your user-base (and not very well either).
What to use instead: Use aria-disabled="true"
and manually disable clicks. If possible though, consider reworking the design to avoid needing disabled buttons altogether.
Further reading: Making Disabled Buttons More Inclusive (article by Sandrina Pereira)
<video>
The native video player still has many accessibility and usability issues. For keyboard users, focus is a recurring issue across browsers, because not all controls can be reached, and the controls disappear once the video starts playing. For screen reader users, the experience is lacking in some areas, especially for more "advanced" features like picture-in-picture mode.
I highly recommend checking out Adrian's article below for a deep-dive on support across various browsers and screen-reader pairings.
Impact: Medium to high.
What to use instead: Unsure. Maybe a custom video player, if it's built with accessibility in mind. Regardless of what you use, please include captions and a transcript, and provide a way to download the video for offline viewing in the user's player of choice. Oh and please for the love of your users, do not use autoplay
.
Further reading: Browser Video Players Review (article by Adrian Roselli)
tel:
, mailto:
)Links on the web can have a non-http protocol like mailto:
or tel:
. These protocols are commonly used as a supposed way to help the users (or spammers) send an email or dial a number. However, this makes a very bold assumption is that the user is visiting the webpage on the same device that will be used to send the email or dial a number and wants to use the default application to do so. This can lead to frustration when the user is just looking for a way to copy the number or dial it from a different device. To make it worse, the actual address/number often gets hidden underneath the link, instead displaying something useless like "Email me".
Impact: Low to medium. It's confusing and annoying, but not the end of world I suppose. Users will (reluctantly) find workarounds.
What to use instead: Just show the actual email address or phone number. It is trivial to copy or manually transfer it over to the desired device. Additionally, many devices will automatically display a prompt when selecting text that can be recognized as an email/number.
Further reading: tel:me.about.it. (article by Brian Kardell)
In closing, I just want to reiterate that accessibility is not as simple as "just use HTML". Even with best intentions and pristine HTML source, we may end up with inaccessible UIs if we don't do our due diligence.
I'm sure this list will look different (hopefully shorter) 10 years from now. As more people start to take interest in these things, it will create more awareness. It will push standards bodies and browser vendors to improve the platform and get us closer to a more "accessible by default" web. You can personally help move the needle by opening new bugs or by commenting on existing ones:
Mayank is a design engineer who cares deeply about accessibility and inclusivity. They enjoy working with modern web technologies to solve complex problems. In their free time, they run their mouth on their personal blog.
Website/Blog: mayank.co