Make a clickable link with onclick but without href=#?

Learn make a clickable link with onclick but without href=#? with practical examples, diagrams, and best practices. Covers javascript, html development techniques with visual explanations.

Creating Clickable Elements Without href="#"

Hero image for Make a clickable link with onclick but without href=#?

Learn how to implement interactive, clickable elements using JavaScript's onclick event without relying on the problematic href="#" attribute, ensuring better accessibility and user experience.

In web development, creating clickable elements is fundamental for user interaction. Traditionally, developers often use an <a> (anchor) tag with href="#" to make an element clickable, then attach a JavaScript onclick event. While this approach works, it introduces several accessibility and usability issues, such as unwanted page jumps, URL hash changes, and incorrect semantic meaning. This article explores best practices for creating clickable elements using onclick without the pitfalls of href="#", focusing on semantic HTML and JavaScript.

Why Avoid href="#" with onclick?

The href="#" attribute is designed to link to a specific fragment identifier within the current page. When combined with an onclick event that performs a different action, it creates a conflict of intent. This can lead to several undesirable side effects:

  • Page Scroll: Clicking the link often causes the page to scroll to the top, especially if no element with the ID # exists, or if the onclick handler doesn't explicitly prevent the default behavior.
  • URL Hash Change: The browser's URL will be updated with #, which can interfere with browser history and deep linking.
  • Accessibility Issues: Screen readers and other assistive technologies interpret href="#" as a navigation link, not an interactive button. This can confuse users who expect to navigate rather than trigger an action.
  • Focus Management: After clicking, the focus might jump unexpectedly, disrupting keyboard navigation.
flowchart TD
    A[User Clicks Element] --> B{Is `href="#"` present?}
    B -->|Yes| C[Browser Tries to Navigate to #]
    C --> D{Is `event.preventDefault()` called?}
    D -->|No| E[Page Scrolls/URL Changes]
    D -->|Yes| F[Default Behavior Prevented]
    B -->|No| G[No Default Navigation]
    (F, G) --> H[Execute `onclick` Handler]
    H --> I[Action Performed]

Flowchart illustrating the impact of href="#" on click events.

The best way to create a clickable element that triggers a JavaScript function without navigation is to use the most semantically appropriate HTML element and handle the click event correctly. The primary candidates are <button> and <div> (or other generic elements) with appropriate ARIA roles.

Using the <button> Element

For actions that trigger a script or manipulate the UI, the <button> element is almost always the best choice. It's inherently clickable, focusable, and keyboard-operable by default, providing excellent accessibility without extra effort. It also doesn't cause page jumps or URL changes.

<button type="button" onclick="myFunction()">
  Click Me
</button>

<script>
function myFunction() {
  alert('Button clicked!');
}
</script>

Simple button with an onclick handler.

Using <div> or Other Generic Elements

If a <button> element isn't semantically appropriate (e.g., you're making an entire card or row clickable), you can use a <div> or another generic element. However, you must add extra attributes to ensure accessibility, as these elements are not interactive by default.

<div role="button" tabindex="0" onclick="myFunction()" onkeydown="handleKeyPress(event)">
  Clickable Div
</div>

<script>
function myFunction() {
  alert('Div clicked!');
}

function handleKeyPress(event) {
  // Trigger click on Enter or Space key press
  if (event.key === 'Enter' || event.key === ' ') {
    event.preventDefault(); // Prevent default scroll for Space key
    myFunction();
  }
}
</script>

Clickable div with ARIA role and keyboard support.

Preventing Default Behavior for <a> Tags (If Necessary)

In some legacy codebases or specific scenarios, you might encounter <a> tags that are used for actions rather than navigation. If you absolutely cannot change the HTML structure, you must explicitly prevent the default navigation behavior.

<a href="#" onclick="event.preventDefault(); myFunction();">
  Clickable Link (Avoid if possible)
</a>

<script>
function myFunction() {
  alert('Link clicked, default prevented!');
}
</script>

Using event.preventDefault() with an <a> tag.