It all started with a tweet by Steve Faulkner.
what are the reasons why developers and frameworks don't use real HTML controls? instead <div class="button"> ??
— Steve Faulkner (@stevefaulkner) November 12, 2013
By that time I had asked myself this question several times inspecting the ways gmail was coded. It also sort of combined in my head with another question. Why do people use
href="#" or even more crap-like:
I saw a suggestion somewhere that
buttons do things while anchors go to places. Which is kinda nice and logical, I think. In most cases… Later on Chris Coyier came up with an excellent article on the topic. His idea that
if a button doesn’t have a meaningful also holds true and can identify the true buttons and links. The only things that I disagreed on were his examples of true links.
href, it’s a
So here I go with some more real-life examples in addition to Chris’s.
I will try to compare each example against both ideas:
buttons do things while anchors go to places and
if a button doesn’t have a meaningful . Additionally, we’ll see if we can have access to the content if we have only keyboard.
href, it’s a
As an example of an accordion I will take an F.A.Q. section that opens the answer when a user clicks a question. A typical markup for this will be a description list.
<dl> <dt>Question 1</dt> <dd>Answer 1</dd> <dt>Question 2</dt> <dd>Answer 2</dd> <dt>Question 3</dt> <dd>Answer 3</dd> </dl>
To correct the issue of keyboard navigation we may add the
tabindex attribute. It does not need to have a different value for every single question. It may be the same, for instance
keyCode of the bar that was pressed we can achieve what we want.
buttons do things, and we do “open” an answer, right?
<dl> <dt><button type="button">Question 1</button></dt> <dd>Answer 1</dd> <dt><button type="button">Question 2</button></dt> <dd>Answer 2</dd> <dt><button type="button">Question 3</button></dt> <dd>Answer 3</dd> </dl>
What do we have here? A native ability to navigate between the questions via keyboard. Requires no
keypress event handlers because pressing the space bar or the enter bar triggers the
1.2. Can a question have a meaningful
Sure. In this case the initial html should be something like this:
<dl> <dt><a href="#answer1" tabindex="1">Question 1</a></dt> <dd id="answer1">Answer 1</dd> <dt><a href="#answer2" tabindex="1">Question 2</a></dt> <dd id="answer2">Answer 2</dd> <dt><a href="#answer3" tabindex="1">Question 3</a></dt> <dd id="answer3">Answer 3</dd> </dl>
What is important to notice is that anchor tags trigger the
click event only when pressing the enter button, and not the space (unlike
<button>s do). If you want to include pressing this button (as you should) you will need to modify the script a bit.
As an additional bonus of this method goes the ability to provide a direct link to a specific answer, which is great if we have a big number of questions.
A slight technical variation of this will be to include the
id attribute to the anchor element itself. Thus the question will be visible to the user too. Although it will be of almost no use as the answers are hidden by default. So it will be wise to check our URL for a hash value on page load and if it corresponds to one of the questions we will make its answer open.
I don’t get it at all, how shall I code?
I come to the conclusion that the first and the third variants are perfectly valid and semantic. The second variant does not improve semantics and does not break it. It actually does nothing to semantics whatsoever. It only improves the accessibility of our content.
In the end it comes down to what functionality you need (are ready) to provide. In my opinion the last variant (adding additional anchor tags, attributes,
keyCode and hash checks) has everything you need.
Although again it may look like we “switch tabs” and do not link to them, the
<a> brings more benefits than the
<button>. I won’t go into much detail about this as it is very similar to my previous example.
In the end, let me provide a couple of examples where
<button> tags are preferable, to my mind.
- next/prev buttons in either a carousel, or in a popup photo gallery.
- Buttons that control the behavior of a carousel or a gallery (like “start the automatic rotation”).
- “X” that closes a popup, or any other button that somehow modifies it (e.g. a “full-screen” button)
- “Copy to clipboard” button
- “increase the font-size” button
- any “Cancel” button
- “Load some more posts” button
- “Hide/minify the comments” button
and so on.
…see the pattern? We cannot even say “Copy to clipboard” link, or “Hide the comments” link. As they are no links.
It looks like my examples work for Chris’s statement that if we can conjure up a meaningful
href we will have both semantics and functionality even if it looks like we “do things”.