Buttons and the Baader–Meinhof phenomenon
posted on
Shortly after we got our new car, a Volkswagen T5, I noticed many people seemed to have the same car. Actually, it was everywhere.
It felt like everyone had the same car. While sales of camping vans and cars that can be used for camping in fact have increased during the pandemic, there’s another reason I saw so many of them, the Frequency illusion or Baader–Meinhof phenomenon.
The Frequency illusion, also known as the Baader–Meinhof phenomenon or frequency bias, is a cognitive bias in which, after noticing something for the first time, there is a tendency to notice it more often, leading someone to believe that it has an increased frequency of occurrence.
Shortly after I started HTMHell a similar thing happened. Every other website seemed to have inaccessible buttons. While this can be explained by the Baader–Meinhof phenomenon, there’s actually data that confirms my feeling. According to the WebAim 1 Million report, 50.1% of 1 million tested websites contained empty links and 27.2% empty buttons.
So, it was more than a feeling. We are terrible at labelling buttons. I understand that this can be confusing, because there are many different ways of getting the job done.
To help with that issue, I've collected different correct and wrong ways of labelling buttons:
How to label buttons
Text only
The all-time classic “just using visible text” works for everyone.
<button type="button">Tweet!</button>
Text and Icon
It’s absolutely fine if you want to add an image or icon to the button. Just make sure to hide it from assistive technology using aria-hidden="true"
. The text label of the button should be sufficient, we don’t need extra information.
<button type="button">
<svg aria-hidden="true" width="28" height="28">
<use href="#twitter"></use>
</svg>
Tweet!
</button>
Sometimes you want to use an icon only. First, you should be really sure that people understand the purpose of the button without text, and second, label it properly. Just because there’s no text visible on screen doesn’t mean that there doesn’t have to be text in the document.
There are different ways of creating icon-only buttons.
Icon-only using a sr-only class
You can put text inside the button and hide it visually using a custom class.
<button type="button">
<span class="sr-only">Tweet!</span>
<svg aria-hidden="true" width="28" height="28">
<use href="#twitter"></use>
</svg>
</button>
.sr-only {
border: 0;
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
left: 0;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
top: 0;
white-space: nowrap;
width: 1px;
}
Icon-only using aria-label on the button
You can add a text alternative for the icon using aria-label
on the button.
<button aria-label="Tweet!" type="button">
<svg aria-hidden="true" width="28" height="28">
<use href="#twitter"></use>
</svg>
</button>
Icon-only using aria-labelledby on the button
If the label you want to use already exists somewhere on the page, you can reference it using aria-labelledby
.
Tweet!
<h2 id="heading">Tweet!</h2>
<button aria-labelledby="heading" type="button">
<svg aria-hidden="true" width="28" height="28">
<use href="#twitter"></use>
</svg>
</button>
Icon-only using title inside the svg
The <title>
element inside the <svg>
can serve as the accessible name for the button. Unfortunately, in order for this to work properly with all screen readers and browsers, you have to label the <svg>
using aria-labelledby
explicitly.
<button type="button">
<svg aria-labelledby="title_twitter_h72d" width="28" height="28">
<title id="title_twitter_h72d">Tweet!</title>
<use href="#twitter"></use>
</svg>
</button>
Icon-only using alt attribute
If you’re using an <img>
element instead of <svg>
, then the alt
attribute serves as the accessible name of the button.
<button type="button">
<img src="/images/twitter.png" alt="Tweet!" width="28">
</button>
Icon-only using background-image
If you’re using a background image, the best option is to add visually hidden text to the button. aria-label
or aria-labelledby
would work, too.
<button type="button">
<span class="sr-only">Tweet!</span>
</button>
button {
background: url(/images/twitter.png) no-repeat center;
}
How not to label buttons
Here are some of the wrong solutions I see often. Don’t do this!
No Text
Don’t do this!
<button type="button"></button>
button {
background: url(/images/twitter.png) no-repeat center;
}
No text alternative for svg
Don’t do this!
<button type="button">
<svg width="28" height="28">
<use href="#twitter"></use>
</svg>
</button>
No text alternative for img
Don’t do this!
<button type="button">
<img src="/images/twitter.png" alt="" width="28">
</button>
or
<button type="button">
<img src="/images/twitter.png" width="28">
</button>