Buttons and CTAs
The design of clickable controls must be consistent with their behaviour
- Version:
- 0.1.0
- Status:
- Published
Introduction
BBC buttons and calls-to-action differ widely in form and purpose. But they should conform to some fundamental rules. Only where these rules are observed will the user experience comfortable interaction.
The most important of these rules is that the <a>
and <button>
elements are assigned to appropriate respective tasks. That is: links should be used where navigation is elicited, and <button>
s where a non-navigational action is being invoked. For example, a 'Sign in' control would suit a <button>
because its job is to submit the sign in form. An adjacent 'Register' call-to-action—taking the user to a different form, in a different page or screen—would benefit from <a>
semantics.
This is especially helpful for assistive technology users, such as those running screen reader software. An element announced as a link that behaves as a button creates a confusing and off-putting experience. The visual design of buttons and calls-to-action should also be indicative of their behavior. Where button state changes, this change should be visually represented as well.
Recommended markup
Basic call-to-action link
In most cases, a call-to-action should be marked up as a link, since the behaviour is typically to transport the user to a new page or section[1]. Standard link markup should be used, including an href
(links omitting href
attributes are not focusable by keyboard).
A class is provided to the element as a styling hook, enabling it to be differentiated from generic links visually.
<a class="gel-cta" href="path/to/location">Enter the competition</a>
Basic button
It is imperative clickable controls not eliciting link-like behaviour are marked up as <button>
elements. Any buttons not intended for submitting forms should take type="button"
[2]. This is especially important inside a <form>
, since some user agents consider any <button>
found without an explicit type to be a form's submit button.
<button class="gel-button" type="button">Calculate tax</button>
As a rule of thumb: if a clickable control is intended for running JavaScript, it should be a <button>
with type="button"
.
Labels
Most buttons and calls-to-action should simply be labeled via their text node. Text nodes are interoperable, since they can be seen, heard via screen reader synthetic voices, and used as activation cues with voice activation software.
In most cases, controls that rely on icons alone are not recommended, even where invisible labels are provided to assistive technologies. Icon-only buttons are especially hard to activate via voice since the (hidden) textual label has to be guessed by the user.
Where an icon-only button is employed (the ubiquitous play/pause button is a good example), provide the text via a visually hidden <span>
, not aria-label
. Unfortunately, aria-label
is not picked up by popular translation services[3].
<button class="gel-button" type="button">
<!-- icon here -->
<span class="gel-sr">Play</span>
</button>
Avoid using title
attributes. These are only revealed on hover, not focus, in most browsers. Additionally, they are often suppressed by default in screen reader verbosity settings.
Icons
Where icons are provided to buttons and calls-to-action, make sure they are taken from the GEL SVG Iconography library[4]. Icons should contain text or be otherwise accessible to assistive technologies, nor should they be focusable. Hence, they should take aria-hidden="true"
and focusable="false"
. Note the classes, used for sizing and alignment.
<a class="gel-cta" href="path/to/help-page">
<span class="gel-button__label">Help</span>
<svg aria-hidden="true" focusable="false">
<use xlink:href="#help"></use>
</svg>
</a>
States
Disabled state
Standard <button>
elements can be disabled using the disabled
property/attribute. Beware that adding disabled
makes the <button>
unfocusable. This may cause confusion among some screen reader users and users exploring by Tab at a high zoom level. You can make disabled buttons focusable again by adding tabindex="0"
.
<button class="gel-button" type="button" disabled tabindex="0">Download</button>