[html] How do you make a div tag into a link

How do you make a div tag into a link. I would like my entire div to be clickable.

This question is related to html anchor

The answer is


You could use Javascript to achieve this effect. If you use a framework this sort of thing becomes quite simple. Here is an example in jQuery:

$('div#id').click(function (e) {
  // Do whatever you want
});

This solution has the distinct advantage of keeping the logic not in your markup.


So you want an element to be something it's not?

Generally speaking this isn't a good idea. If you need a link, use a link. Most of the time it's easier to just use the appropriate markup where it belongs.

That all said, sometimes you just have to break the rules. Now, the question doesn't have , so I'm going to put the disclaimer here:

You can't have a <div> act as a link without either using a link (or equivalent, such as a <form> that only contains a submit button) or using JavaScript.

From here on out, this answer is going to assume that JavaScript is allowed, and furthermore that jQuery is being used (for brevity of example).

With that all said, lets dig into what makes a link a link.


Links are generally elements that you click on so that they navigate you to a new document.

It seems simple enough. Listen for a click event and change the location:

Don't do this

_x000D_
_x000D_
$('.link').on('click', function () {_x000D_
  window.location = 'http://example.com';_x000D_
});
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<div class="link">Fake Link</div>
_x000D_
_x000D_
_x000D_

There you have it, the <div> is now a link. Wait...what's that? What about accessibility? Oh right, screen readers and users of assistive technology won't be able to click on the link, especially if they're only using the keyboard.

Fixing that's pretty simple, let's allow keyboard only users to focus the <div>, and trigger the click event when they press Enter:

Don't do this either

_x000D_
_x000D_
$('.link').on({_x000D_
  'click': function () {_x000D_
    window.location = 'http://example.com';_x000D_
  },_x000D_
  'keydown': function (e) {_x000D_
    if (e.which === 13) {_x000D_
      $(this).trigger('click');_x000D_
    }_x000D_
  }_x000D_
});
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<div class="link" tabindex="0">Fake Link</div>
_x000D_
_x000D_
_x000D_

Again, there you have it, this <div> is now a link. Wait...again? Still accessibility problems? Oh ok, so it turns out that the assistive technology doesn't know that the <div> is a link yet, so even though you can get there via keyboard, users aren't being told what to do with it.

Fortunately, there's an attribute that can be used to override an HTML element's default role, so that screen readers and the like know how to categorize customized elements, like our <div> here. The attribute is of course the [role] attribute, and it nicely tells screen readers that our <div> is a link:

Ugh, this is getting worse every minute

_x000D_
_x000D_
$('[role="link"]').on({_x000D_
  'click': function () {_x000D_
    window.location = 'http://example.com';_x000D_
  },_x000D_
  'keydown': function (e) {_x000D_
    if (e.which === 13) {_x000D_
      $(this).trigger('click');_x000D_
    }_x000D_
  }_x000D_
});
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<div role="link" tabindex="0">Fake Link</div>
_x000D_
_x000D_
_x000D_

Finally, our <div> is a lin---oh now the other devs are complaining. What now?

Ok, so the devs don't like the code. They tried to preventDefault on the event, and it just keeps working. That's easy to fix:

I warned you this was bad

_x000D_
_x000D_
$(document).on({_x000D_
  'click': function (e) {_x000D_
    if (!e.isDefaultPrevented()) {_x000D_
      window.location = 'http://example.com';_x000D_
    }_x000D_
  },_x000D_
  'keydown': function (e) {_x000D_
    if (e.which === 13 && !e.isDefaultPrevented()) {_x000D_
      $(this).trigger('click');_x000D_
    }_x000D_
  }_x000D_
}, '[role="link"]');_x000D_
_x000D_
$('[aria-disabled="true"]').on('click', function (e) {_x000D_
  e.preventDefault();_x000D_
});
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<div role="link" tabindex="0">Fake Link</div>_x000D_
<div role="link" aria-disabled="true" tabindex="0">Fake disabled link</div>
_x000D_
_x000D_
_x000D_

There we have it---THERE'S MORE? What else don't I know? Tell me everything NOW so that I can fix it!

  • Ok, so there's no way to specify target. We can fix that by updating to window.open.
  • Click events and keyboard events are ignoring Ctrl, Alt, and Shift keys. That's easy enough, just need to check those values on the event object.
  • There's no way to specify contextual data. Let's just add some [data-*] attributes, and call it a day with that one.
  • The click event isn't obeying the mouse button that's being used, middle mouse should open in a new tab, right mouse shouldn't be triggering the event. Easy enough, just add some more checks to the event listeners.
  • The styles look weird. WELL OF COURSE THE STYLES ARE WEIRD, IT'S A <DIV> NOT AN ANCHOR!

well, I'll address the first four issues, and NO MORE. I've had it with this stupid custom element garbage. I should have just used an <a> element from the beginning.

Told you so

_x000D_
_x000D_
$(document).on({_x000D_
  'click': function (e) {_x000D_
    var target,_x000D_
        href;_x000D_
    if (!e.isDefaultPrevented() && (e.which === 1 || e.which === 2)) {_x000D_
      target = $(this).data('target') || '_self';_x000D_
      href = $(this).data('href');_x000D_
      if (e.ctrlKey || e.shiftKey || e.which === 2) {_x000D_
        target = '_blank'; //close enough_x000D_
      }_x000D_
      open(href, target);_x000D_
    }_x000D_
  },_x000D_
  'keydown': function (e) {_x000D_
    if (e.which === 13 && !e.isDefaultPrevented()) {_x000D_
      $(this).trigger({_x000D_
        type: 'click',_x000D_
        ctrlKey: e.ctrlKey,_x000D_
        altKey: e.altKey,_x000D_
        shiftKey: e.shiftKey_x000D_
      });_x000D_
    }_x000D_
  }_x000D_
}, '[role="link"]');_x000D_
_x000D_
$('[aria-disabled="true"]').on('click', function (e) {_x000D_
  e.preventDefault();_x000D_
});
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<div role="link" tabindex="0" data-href="http://example.com/">Fake Link</div>_x000D_
<div role="link" tabindex="0" data-href="http://example.com/" data-target="_blank">Fake Link With Target</div>_x000D_
<div role="link" aria-disabled="true" tabindex="0" data-href="http://example.com/">Fake disabled link</div>
_x000D_
_x000D_
_x000D_

Note that stack snippets won't open popup windows because of how they're sandboxed.

That's it. That's the end of this rabbit hole. All of that craziness when you could have simply had:

<a href="http://example.com/">
    ...your markup here...
</a>

The code I posted here probably has problems. It probably has bugs that even I don't realize as of yet. Trying to duplicate what browsers give you for free is tough. There are so many nuances that are easy to overlook that it's simply not worth trying to emulate it 99% of the time.


If you have to set your anchor tag inside the div, you can also use CSS to set the anchor to fill the div via display:block.

As such:

<div style="height: 80px"><a href="#" style="display: block">Text</a></div>

Now when the user floats their cursor in that div the anchor tag will fill the div.


JS:

<div onclick="location.href='url'">content</div>

jQuery:

$("div").click(function(){
   window.location=$(this).find("a").attr("href"); return false;
});

Make sure to use cursor:pointer for these DIVs


<div style="cursor:pointer;" onclick="document.location='http://www.google.com'">Foo</div>

<div style="cursor:pointer" onclick="document.location='http://www.google.com'">Content Goes Here</div>

If you're using HTML5, as pointed in this other question, you can put your div inside a:

<a href="http://www.google.com"><div>Some content here</div></a>

Preffer this method as it makes clear in your structure that all the content is clickable, and where it's pointing.


Keep in mind that search spiders don't index JS code. So, if you put your URL inside JS code and make sure to also include it inside a traditional HTML link elsewhere on the page.

That is, if you want the linked pages to be indexed by Google, etc.


DON'T DO IT.

  • If you want a link, wrap the content in the proper <A>NCHOR</a>.
  • If you want to turn the <DIV> into a link, use "Javascript" to wrap the <DIV> inside an <A>NCHOR</A>
  • If you want to perform some action when clicking the <DIV> use the onclick event handler... and don't call it a "link".

You can make the entire DIV function as a link by adding an onclick="window.location='TARGET URL'" and by setting its style to "cursor:pointer". But it's often a bad idea to do this because search engines won't be able to follow the resulting link, readers won't be able to open in tabs or copy the link location, etc. Instead, you can create a regular anchor tag and then set its style to display:block , and then style this as you would a DIV.