Question

What element should I use for JavaScript actions?

Actions that does something like play/pause/stop/new/open/save/print/close, etc.

<a id="play" href="#">Play</a>
<a href="#play">Play</a>
<button id="play" tabindex="0">Play</button>
<div id="play" role="button" tabindex="0">Play</div>

I see many people use anchors <a> with a href="#" but that doesn't feel very semantic, it feels like anchors are for hyperlinks that point to a resource, not for actions that does stuff. Then you have to hack it around with event.preventDefault (i.e. return false).

I rarely see people use the <button> element, but isn't it what is supposed to be used?

Was it helpful?

Solution

TLDR; you can open an anchor link in a new Tab/Window but not a button.

Here is a rule of thumb:

  • For navigation just use anchor it's alright to style it as a button and let it use it's href attribute well.

  • For quick actions (play,pause,stop,+1 like) just use button it doesn't have href for a reason!

Consider this code.

const [anchor] = document.getElementsByTagName('a')
const [button] = document.getElementsByTagName('button')

anchor.addEventListener('click', e => {
  console.log('anchor clicked')
  e.preventDefault()

}, false)

button.addEventListener('click', e => {
  console.log('button clicked')
})
a {
  text-decoration: none;
  padding: 2px;
}


button {
  background: none;
  border: none;
  font-size: 16px;
}

.btn {
  background-color: blue;
  color: white;
  display: inline-block;
  text-align: center;
}
<a class="btn" href="#">
  Anchor
</a>

<hr/>

<button class="btn" type="button">
  Button
</button>

Styling

They both look almost alike (with minimal justifications) the only problem is that you'll have to undo some stylings that come with button like border & background but with anchor you don't get the clicking popping animation that you'd get with button.

Functionality

But since the anchors <a> need <a href="some/path"> to work even if it's just #, unless you need to navigate after clicking the anchor you'll have to use e.preventDefault() in your javascript to prevent it.

OTHER TIPS

The best way to decide which element has the best semantics for a JS based user interaction is to ask what you want to happen if the JS fails (which it will.

Think progressive enhancement. Think unobtrusive JavaScript.

Should the user just go to another page? Use a link. The href will be the fallback from when the JS fails.

Should the user go to another page while sending some data or making a POST request? Use a button, put it in a form.

Is it impossible to have any kind of server fallback? Use a <button type="button"> and consider generating it from JS/DOM instead of HTML.

Then you have to hack it around with event.preventDefault

You could set the href to javascript:void(0) rather than #, which would prevent execution without having to use event.preventDefault()

But buttons are probably better for this sort of thing

This is more of a preference thing.

Personally, I prefer to either use the <button> tag or make my own.

If it makes more sense to you to use the <button> tag, use it. If it works, it's not wrong. =)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top