An anchor with href navigates to a resource; a button invokes an action in the current interface or submits a form.
HTML link versus button: navigation and actions have different contracts
Use it for a real task
The receipt ID opens another route, so it is a link. Approval submits a POST form, so it is a button. Styling can make the two look similar, but their keyboard behavior, browser context menus, and history semantics remain different.
<a href="/receipts/R-47">Open receipt R-47</a>
<form action="/receipts/approve" method="post">
<input type="hidden" name="receipt_id" value="R-47">
<button type="submit">Approve R-47</button>
</form>What the markup guarantees
The approval endpoint must validate identity, current status, and permission. A link to a mutation route makes accidental crawls and prefetches dangerous; a button without a handler does not change the page.
Cost and limits
Both are native, low-cost controls. The expensive mistake is semantic drift: custom keyboard code and broken browser behaviors appear when one is styled to imitate the other without using its contract.
Common Mistakes
- Do not use href='#' as a button substitute.
- Do not make an approval GET link.
- Give both controls descriptive text.
Connected lessons
- HTML anchors: use href for navigation and stable fragment targets
- HTML forms: choose GET for retrieval and POST for a state change
- HTML focus order: use native controls and keep DOM order usable
Related: HTML anchors: use href for navigation and stable fragment targets.
Related: HTML focus order: use native controls and keep DOM order usable.
Related: HTML button type: make every form action explicit.
Style this pattern
- CSS link decoration and states: preserve a visible navigation cue
- CSS focus-visible: keep keyboard location unmistakable
