HOWTO · HTML
How to Make an HTML Button Act as a Link
Learn when to use an anchor styled as a button, a JavaScript button, or a form submit control for HTML navigation.
On this page
The right way to make an HTML control open a URL depends on what the control does. For navigation, use an <a> element with an href and style it to look like a button. Use <button> when the control performs an action, and use a submit button when it sends form data. Avoid putting a <button> or <input> inside an <a>: both elements are interactive, so the nesting creates conflicting semantics and keyboard behavior.
Choose an anchor or button from the intended result
Use an anchor when activation changes the current location, opens a document, downloads a file, or moves to a different page. The href gives the browser a real destination, which lets users open it in a new tab, copy its address, bookmark it, and reach it with the keyboard.
Use a <button type="button"> when activation changes the current page or starts an action, such as opening a dialog, toggling a panel, or running a script. A button is not a replacement for a link merely because it has a rectangular visual style. The element’s role should describe its behavior to assistive technology.
Style an <a> element as a button for navigation
This is the recommended solution when the reader needs a button-looking link. Keep the destination in href, use meaningful link text, and add a visible focus style. Replace /docs/ with the URL you want to open.
<a class="button-link" href="/docs/">Open the documentation</a>
.button-link {
display: inline-block;
padding: 0.65rem 1rem;
border-radius: 0.35rem;
background: #1769aa;
color: #fff;
text-decoration: none;
}
.button-link:hover {
background: #0d4f80;
}
.button-link:focus-visible {
outline: 3px solid #f5b700;
outline-offset: 2px;
}
The result looks like a button but remains a link. Users can press Enter to activate it, and the browser can expose its destination. If the link opens a new tab, say so in the link text and use rel="noopener" with target="_blank" when appropriate:
<a href="https://example.com/docs" target="_blank" rel="noopener">
Open the documentation (new tab)
</a>
Do not use href="#" or href="javascript:void(0)" to imitate a button. Those values do not describe a real destination and can cause unexpected scrolling, bookmarking, or loading behavior. If activation does not navigate, use a real button instead.
The href can be a relative path such as /docs/, an absolute HTTPS URL, a fragment such as #details, a mail address, or another URL that the browser can address. Choose the destination that matches the action and make the link label meaningful without relying on its surrounding paragraph. If a link downloads a resource, communicate that result in the label and use the download attribute only when the browser and server response support the intended download behavior. CSS changes the presentation, not the link’s native keyboard and context-menu behavior, so a styled link remains easier to reuse than a script-driven fake button.
Use a <button> with JavaScript only for a button action
Sometimes a component must remain a button because it performs other work before navigation, checks state, or opens a destination after an application action. Give the button an explicit type and attach a listener with addEventListener. window.location.assign() then performs the navigation.
<button type="button" id="docs-button">Open the documentation</button>
<script>
document.querySelector("#docs-button").addEventListener("click", () => {
window.location.assign("https://example.com/docs");
});
</script>
This example navigates when the button is activated with a pointer, Enter, or Space. It still depends on JavaScript. If the destination is ordinary navigation and no action is needed, prefer the anchor example so the link remains usable while JavaScript is disabled and retains normal browser link features. In larger applications, place the listener in your JavaScript module instead of using an inline onclick attribute.
An empty or malformed destination is a boundary case, not a useful fallback. Validate a URL before calling assign() when its value comes from user input or application state. Never use a button handler as a reason to remove a meaningful link destination.
Use a form when submitting data is the task
The original form approach is appropriate when the control submits data to a server. Put the destination in the form’s action and use a submit control. The browser sends the form fields using the selected method; this is different from a plain link navigation.
<form action="/search" method="get">
<label for="query">Search</label>
<input id="query" name="q" type="search">
<button type="submit">Search</button>
</form>
For example, submitting CSS button produces a request such as /search?q=CSS+button, subject to normal form encoding. Do not use a form only to get a button appearance when there is no data or submit operation; style an anchor instead. If several submit buttons use one form, formaction can provide a different submit destination for a particular type="submit" button.
An <input type="submit"> is also a valid form control when a project needs its older, value-based markup:
<form action="/docs/" method="get">
<input type="submit" value="Open the documentation">
</form>
The value becomes the control’s visible label. Do not wrap this input in an anchor. An <input type="button"> has no submit or navigation behavior by itself; it needs a script, so it should be used only when the application genuinely requires a button action.
Troubleshoot a button that does not open a link
- If the control navigates to a URL, inspect the markup first. It should be an
<a href="...">, even if CSS makes it look like a button. - If you use
<button>inside a form, settype="button"for a non-submitting action. Otherwise the missing type defaults to a submit button and may reload the page or send form data. - If a JavaScript button does nothing, check the browser console, the selector, and whether the script loaded. A JavaScript-disabled browser cannot run the handler.
- If keyboard users cannot tell where focus is, keep the
:focus-visiblestyle and do not remove the browser outline without an accessible replacement. - If you need an ordinary link, do not combine an anchor with a nested
<button>or<input>. One native interactive element is clearer and more reliable than two controls competing for the same click.
In short, style <a href="..."> when the outcome is navigation, use <button type="button"> for an action, and use a submit button inside a form when data must be sent. This separation gives the browser and assistive technologies the behavior they expect.