Why are button's discouraged from navigation?
After reading up on multiple documents posted in the comments, it seems that there is actually a clear factual reason buttons are not used in navigation bars.
Anchor tags
These are used when there is a page redirect or taking a user elsewhere on the website.
- If it navigates, it is a link. Use link markup with a valid hypertext reference
~Links are not buttons
Button elements
These are used when you want to doSomething() that is not redirecting the user. I.e. submitting a form / etc.
The question you need to ask yourself is:
Will this control be used to initiate an immediate action or Is the action to navigate to another page?
if the answer to your question is the first part, then you should be using a button
element. Whereas if it is the latter that you are wishing to do, then you should be using an a
element.
further Reading:
w3.org
Links are not buttons. Neither are DIVs and SPANs
When To Use The Button Element
Buttons in nav instead of anchor?
From an accessibility perspective, using both links and buttons is the semantically correct way to go. The links take you to another page (or somewhere else on the current page) and buttons perform an action. A screen reader user will understand when they hear "link" or "button" in the same <nav> that different actions will happen.
Is it more accessible to use a button or a to open/close a modal?
<button>
Change the <a href="#">
to a <button>
and put your event handler on it.
Some more context on which elements belongs where....
Does the Control Take Me to Another Page? Use an Anchor
If, when clicked, tapped, or activated by keyboard or voice (or insert novel interaction method here), the user is whisked to another URL (including an anchor on the same page), then use <a href="[URL]">
. Make sure you use the href
attribute and that it has a real URL, not a “#” (otherwise you’re probably relying on JavaScript, which is not at all necessary for a hyperlink). If an href
points to just a “#”, then you’re probably doing it wrong. If it points to a named anchor as part of your progressive enhancement efforts, then that’s totally valid.
Does the Control Change Something on the Current Page? Use a Button
If, when activated, the user is not moved from the page (or to an anchor within the page), but instead is presented with a new view (message boxes, changes in layout, etc.), then use a <button>
. While you could use an<input type="button">
, it’s more likely you’ll get into conflicts with pre-existing styles and subsequent developers (like me).
Does the Control Submit Form Fields? Use a Submit
If, when activated, information the user has entered (either by manually typing or by choosing items on the screen) is being sent back to the server, then use an <input type="submit">
. This has better live within a <form>
. If you need more styling control or have to embed more than just a simple text string, use a <button type="submit">
instead.
Keyboard Considerations
Think of keyboard users for a moment. A hyperlink can be fired by pressing the enter key. But a true button can be fired by pressing the enter key or the space bar. When a hyperlink has focus and the user presses the space bar, the page will scroll one screenful. If there isn’t more to scroll then the user just experiences nothing. Given a set of interface elements that look the same, if some work with a space bar and some don’t, you can’t expect users to have much confidence in how the page behaves.
I think it’s also worth mentioning that events triggered by a space bar only fire when the key is released, whereas using the Enter key will fire the event as soon as you press the key down (prior to releasing it).
Anchor or button
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'shref
attribute well.For quick actions (play,pause,stop,+1 like) just use button it
doesn't havehref
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>
Related Topics
Setting Transform-Origin on Svg Group Not Working in Firefox
Hide Vertical Scrollbar in ≪Select≫ Element
What Is "X-Content-Type-Options=Nosniff"
Best Approach to Real Time Http Streaming to Html5 Video Client
How to Find Unused Images and CSS Styles in a Website
Making the Main Scrollbar Always Visible
Is Type="Text/Css" Necessary in a ≪Link≫ Tag
Apply CSS Styles to an Element Depending on Its Child Elements
Why Should I Use 'Li' Instead of 'Div'
Stretch Text to Fit Width of Div
Change Cursor Type on Input Type="File"
Css ''Background-Color" Attribute Not Working on Checkbox Inside ≪Div≫
How to Position Two Elements Side by Side Using Css
How to Update Non-Jsf Components (Plain Html) With Jsf Ajax
How to Make Div Element Auto-Resize Maintaining Aspect Ratio
Turn Off Iphone/Safari Input Element Rounding
Css: Vertically Align Div When No Fixed Size of the Div Is Known