601

I have a <div> block with some fancy visual content that I don't want to change. I want to make it a clickable link.

I'm looking for something like <a href="…"><div> … </div></a>, but that is valid XHTML 1.1.

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
EE.
  • 6,111
  • 3
  • 18
  • 5

31 Answers31

780

Came here in the hope of finding a better solution that mine, but I don't like any of the ones on offer here. I think some of you have misunderstood the question. The OP wants to make a div full of content behave like a link. One example of this would be facebook ads - if you look, they're actually proper markup.

For me the no-nos are: javascript (shouldn't be needed just for a link, and very bad SEO/accessibility); invalid HTML.

In essence it's this:

  • Build your panel using normal CSS techniques and valid HTML.
  • Somewhere in there put a link that you want to be the default link if the user clicks on the panel (you can have other links too).
  • Inside that link, put an empty span tag (<span></span>, not <span /> - thanks @Campey)
  • give the panel position:relative
  • apply the following CSS to the empty span:

    { 
      position:absolute; 
      width:100%;
      height:100%;
      top:0;
      left: 0;
    
      z-index: 1;
    
      /* fixes overlap error in IE7/8, 
         make sure you have an empty gif */
      background-image: url('empty.gif');
    }   
    

    It will now cover the panel, and as it's inside an <A> tag, it's a clickable link

  • give any other links inside the panel position:relative and a suitable z-index (>1) to bring them in front of the default span link
thepeer
  • 8,190
  • 2
  • 18
  • 13
283

You can't make the div a link itself, but you can make an <a> tag act as a block, the same behaviour a <div> has.

a {
    display: block;
}

You can then set the width and height on it.

Claudio
  • 884
  • 1
  • 15
  • 31
Soviut
  • 88,194
  • 49
  • 192
  • 260
  • 13
    However, this doesn't make a 'div' into a link. It makes a link into a block element. It's a bit different. – jjnguy Apr 28 '09 at 03:35
  • You could make a span a block element too, but there is a reason for different HTML elements. – jjnguy Apr 28 '09 at 03:36
  • 1
    This is solution of your problem. Because you can modify div can be clicked like hyperlink, but you can't set cursor(=hand) for display in all browser(only IE support it!). –  Apr 28 '09 at 03:36
  • Using an 'a' tag for a block is like using tables for layout IMHO. – jjnguy Apr 28 '09 at 05:37
  • 3
    jjnguy: How? I dislike having lots of content in a link, but this could just as well be part of a navigation menu or something like that. An anchor element () doesn't necessarily have to be plain text, does it? In which way is it _wrong_ to make it into a block? It's semantically correct and it can be used to display it as you want. – Arve Systad Apr 28 '09 at 15:31
  • 23
    This is a perfectly valid solution to a vague question. You actually COULD simply wrap an anchor element around a div, but that would be semantically incorrect. (Block element within inline element). – Traingamer Apr 28 '09 at 18:08
  • 3
    jjnguy: This is pretty common practice. I'm not saying replace divs with links, but by the sounds of the question he just wanted a block he could click like a button or something. – Soviut Apr 29 '09 at 01:42
  • the solution is valid, no doubt, the the OP did not request this functionality.... – kumarharsh Aug 19 '12 at 20:56
  • This worked in my situation and was the best solution. I made it an inline-block and added width: 100% to stretch it across the entire enclosing div. This solved a dropdown menu problem where if the link was forced to wrap an inadvertently click simply closed the menu. – DeveloperChris May 15 '19 at 05:34
  • @Traingamer Maybe to *a* vague question, but not this one. This question specifically asks for how to make a *div* into a link. It is abundantly obvious that answers which don't even use `div`s cannot be a valid answer to this question. – Kröw Dec 20 '22 at 21:34
  • @Kröw it is incredibly vague. They didn't show any code, didn't explain why they used a div, or why they'd want to keep it a div. Nor was any reason given for wanting to wrap the div other than to make it behave like a link. They also didn't specify if they wanted to avoid javascript or not, etc. So this is very open ended which is why there are so many potential solutions provided. – Soviut Dec 21 '22 at 01:10
  • @Soviut That is not true at all. I reiterate that this question specifically asks for how to make a *div* into a link. The question title is short and sweet: `Make a div into a link`. Your curiosity as to why a div was used would be well-resolved through a comment, but providing an answer that escapes the question is something to have to scroll through for users who want an answer to exactly what the question is. If you have useful information that answers a different (albeit similar) question, it is recommended to open a new question and self-answer it, (and perhaps, reference this question). – Kröw Dec 31 '22 at 08:01
  • @Kröw Please stop cluttering up the comments with this. The question is vague and open to interpretation, otherwise there would be a single answer. For example, there's no reason given for breaking HTML semantics. Since they weren't clear about "why", offering solutions that are semantically valid is perfectly reasonable. – Soviut Dec 31 '22 at 21:03
  • @Soviut There is no purpose in you asking me to simply stop "cluttering the comments;" I would ask you the same thing because I think what you're pointing out is not correct (or if I think it is not relevant). Anyway, the question is vague and open to interpretation, but that does not mean I can talk about my favorite fútbol team in an answer. The question may be vague but it's still very clear what isn't an answer. Semantic validity doesn't make what you posted an answer. Your post is still a semantically valid answer to a *different* question. – Kröw Dec 31 '22 at 21:22
  • @Soviut Your "answer" is useful, but I strongly suggest you take the more appropriate approach of writing a new question and self-answering it when you have useful information that does not answer the existing question again in the future. (I already suggested linking the original question too. This is useful advice.) Adding a post that does not answer the question exactly does clutter up the page with answers that do not help many others with the same question. – Kröw Dec 31 '22 at 21:22
  • The problem with this solution is: when you put an `img` into an `a` rendered as `block`, the outer `a` and the inner `img` do not have the same height. – ceving Jan 30 '23 at 09:23
  • @ceving that's solved by giving the `img` a `display: block` removing whitespace characters in your HTML. However, if they were using an image, they technically don't need to do anything to the `a` since the `img` will give it block-like behaviour (despite both being inline). – Soviut Jan 30 '23 at 18:08
87

This is an ancient question, but I thought I'd answer it since everyone here has some crazy solutions. It's actually very very simple...

An anchor tag works like this -

<a href="whatever you want"> EVERYTHING IN HERE TURNS INTO A LINK </a>

Sooo...

<a href="whatever you want"> <div id="thediv" /> </a>

Although I'm not sure if this is valid. If that's the reasoning behind spoken solutions, then I apologise...

aelsheikh
  • 2,268
  • 5
  • 26
  • 41
  • 9
    It's valid HTML as long as the `
    ` doesn't contain any interactive content (other `` elements, `
    –  Apr 14 '11 at 01:23
  • 53
    Your example is not valid HTML - block element contained in an inline element - *unless* you're using HTML5, which has made an exception for links. – thepeer Sep 22 '11 at 13:27
  • 1
    This is a *bad* example, because what the `a` tag does is takes all the text in a `div` and underlines it... this can be mitigated with styling, but the top answer is better. – Dmitri Nesteruk Dec 28 '11 at 13:48
  • 2
    `a #thediv{font-weight:normal;text-decoration:none;}` is all you need style-wise. – tyjkenn Jun 17 '12 at 04:21
  • no. just simple converting div into inline would not do the job. It is bad markup, and... just read this: http://skypoetsworld.blogspot.in/2008/10/dont-ever-put-block-inside-inline.html – kumarharsh Aug 19 '12 at 20:58
  • 1
    Tried this and it worked, however it broke the element's positioning. Yes doctype is HTML5 in Chrome (some 2014 version).. – BAR Oct 30 '14 at 01:05
  • not valid xhtml - you shouldn't put block elements inside inline elements, even if you change the 'display' property with css – Velimir Tchatchevsky Nov 11 '15 at 12:23
  • Yeah I saw a CodeAcademy course has done it this way too. https://www.codecademy.com/en/courses/web-beginner-en-f8mcL/2/2?curriculum_id=50579fb998b470000202dc8b – Bohn Mar 04 '16 at 18:38
  • It is a valid answer for HTML 5, but not for HTML 4- – Tohid Mar 04 '16 at 20:43
  • made all the `

    ` tags underneath turn blue. Even when setting `a text-decoration: none`

    – MwBakker Oct 30 '22 at 11:26
75

Requires a little javascript. But, your div would be clickable.

<div onclick="location.href='http://www.example.com';" style="cursor:pointer;"></div>
jjnguy
  • 136,852
  • 53
  • 295
  • 323
50

This option doesn’t require an empty.gif as in the most upvoted answer:

HTML:

 <div class="feature">
       <a href="http://www.example.com"></a>
 </div>

CSS:

 div.feature {
        position: relative;
    }

    div.feature a {
        position: absolute;
        width: 100%;
        height: 100%;
        top: 0;
        left: 0;
        text-decoration: none; /* No underlines on the link */
        z-index: 10; /* Places the link above everything else in the div */
        background-color: #FFF; /* Fix to make div clickable in IE */
        opacity: 0; /* Fix to make div clickable in IE */
        filter: alpha(opacity=1); /* Fix to make div clickable in IE */
    }

As proposed at http://www.digitalskydesign.com/how-to-make-an-entire-div-a-link-using-css/

MagTun
  • 5,619
  • 5
  • 63
  • 104
  • 1
    Thanks! Chris Jumonville's solution is working great on both Andriod and iPhone. Example: http://gastateparks.org/specials – Loren Jan 03 '15 at 13:33
  • 1
    Shouldn't it be `div.feature > a` just in case the "everything else" part also contains a link hidden deep within? – TWiStErRob Aug 07 '16 at 19:47
  • this should be the choosen answer, works with bootstrap too – Anthony Kal Dec 29 '17 at 06:00
  • 1
    This works beautifully, very smooth, works with screen readers nicely too, HTML5 adhering, works even if you do transforms on the parent object, and inherently makes the cursor into a pointer (as you expect for a clickable object) – Steffen Cole Blake Oct 08 '21 at 23:31
25

The cleanest way would be to use jQuery with the data-tags introduced in HTML. With this solution you can create a link on every tag you want. First define the tag (e.g. div) with a data-link tag:

<div data-link="http://www.google.at/">Some content in the div which is arbitrary</div>

Now you can style the div however you want. And you have to create also the style for the "link"-alike behavior:

[data-link] {
  cursor: pointer;
}

And at last put this jQuery call to the page:

$(document).ready(function() {
  $("[data-link]").click(function() {
    window.location.href = $(this).attr("data-link");
    return false;
  });
});

With this code jQuery applys a click listener to every tag on the page which has a "data-link" attribute and redirects to the URL which is in the data-link attribute.

Noah
  • 859
  • 7
  • 17
Erhard Dinhobl
  • 1,646
  • 18
  • 34
24

This is a "valid" solution to achieving what you want.

<style type="text/css">
.myspan {
    display: block;
}
</style>
<a href="#"><span class="myspan">text</span></a>

But most-likely what you really want is to have an <a> tag displayed as a block level element.

I would not advise using JavaScript to simulate a hyperlink as that defeats the purpose of markup validation, which is ultimately to promote accessibility (publishing well-formed documents following proper semantic rules minimizes the possibility the same document will be interpreted differently by different browsers).

It would be preferable to publish a web page that does not validate, but renders and functions properly on all browsers, including ones with JavaScript disabled. Furthermore, using onclick does not provide the semantic information for a screen reader to determine that the div is functioning as a link.

Calvin
  • 4,559
  • 1
  • 25
  • 23
20

Not sure if this is valid but it worked for me.

The code :

<div style='position:relative;background-color:#000000;width:600px;height:30px;border:solid;'>
  <p style='display:inline;color:#ffffff;float:left;'> Whatever </p>     
  <a style='position:absolute;top:0px;left:0px;width:100%;height:100%;display:inline;' href ='#'></a>
</div>
azro
  • 53,056
  • 7
  • 34
  • 70
Tim
  • 217
  • 2
  • 3
10

To make thepeer's answer work in IE 7 and forward, it needs a few tweaks.

  1. IE will not honour z-index if the element is has no background-color, so the link will not overlap parts of the containig div that has content, only the blank parts. To fix this a background is added with opacity 0.

  2. For some reason IE7 and various compatibility modes completely fail when using the span in a link approach. However if the link itself is given the style it works just fine.

.blockLink  
{  
    position:absolute;  
    top:0;  
    left: 0;  
    width:100%;  
    height:100%;  
    z-index: 1;  
    background-color:#ffffff;   
    -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";  
    filter: alpha(opacity=0);  
    opacity:0;  
}
<div style="position:relative">  
    <some content>  
    <a href="somepage" class="blockLink" />  
<div>
animuson
  • 53,861
  • 28
  • 137
  • 147
9

you could also try by wrapping an anchor, then turning its height and width to be the same with its parent. This works for me perfectly.

<div id="css_ID">
    <a href="http://www.your_link.com" style="display:block; height:100%; width:100%;"></a>
</div>
wdonayredroid
  • 431
  • 4
  • 3
7

An option that hasn't been mentioned is using flex. By applying flex: 1 to the a tag, it expands to fit the container.

div {
  height: 100px;
  width: 100px;
  display: flex;
  border: 1px solid;
}

a {
  flex: 1;
}
<div>
  <a href="http://google.co.uk">Link</a>
</div>
The Codesee
  • 3,714
  • 5
  • 38
  • 78
6

This worked for me:

HTML:

<div>

  WHATEVER YOU WANT

  <a href="YOUR LINK HERE">
    <span class="span-link"></span>
  </a>

</div>

CSS:

.span-link {
  position:absolute;
  width:100%;
  height:100%;
  top:0;
  left: 0;
  z-index: 9999;
}

This adds an invisible element (the span), which covers your entire div, and is above your whole div on the z-index, so when someone clicks on that div, the click is essentially intercepted by your invisible "span" layer, which is linked.

Note: If you're already using z-indexes for other elements, just make sure the value of this z-index is higher than anything you want it to rest "on top" of.

Jeff Schwarting
  • 619
  • 8
  • 6
5

why not? use <a href="bla"> <div></div> </a> works fine in HTML5

Vamsi Pavan Mahesh
  • 240
  • 1
  • 8
  • 30
  • It won't pass HTML validation. Line item cannot store block items. – Jazi Apr 17 '15 at 13:19
  • I mean, that `
    ` is valid and `
    ` is not. You shouldn't put `display: inline;` type of items into `display: block;` items. The `` tag is inline box.
    – Jazi Apr 17 '15 at 13:36
  • Yeah, it can work, because You can do it in multiple ways (better or worse). This particular solution is not good cause the older HTML validation :). – Jazi Apr 17 '15 at 13:44
  • 1
    Does it matter that "older HTML validation" does not pass this? It is allowed now, html5 and for a reason so why not use it? I think this solution is fine (it does often require the removal of underline to the div content but still). – Todilo Aug 28 '15 at 08:20
  • @Todilo Because while `
    ` is valid and works, `
    ` is not valid and doesn't work.
    – coredumperror Apr 17 '17 at 21:40
4

This example worked for me:

<div style="position: relative; width:191px; height:83px;">
    <a href="link.php" style="display:block; width:100%; height:100%;"></a>
</div>
joan16v
  • 5,055
  • 4
  • 49
  • 49
4

This post is Old I know but I just had to fix the same issue because simply writing a normal link tag with the display set to block does not make the whole div clickable in IE. so to fix this issue far simpler than having to use JQuery.

Firstly let us understand why this happens: IE wont make an empty div clickable it only make the text/image within that div/a tag clickable.

Solution: Fill the div with a bakground image and hide it from the viewer.

How? You ask good questions, now listen up. add this backround style to the a tag

> "background:url('some_small_image_path')
> -2000px -2000px no-repeat;"

And there you have it the whole div is now clickable. This was the best way for me cause Im using it for my Photo Gallery to let the user clik on one half of the image to move left/right and then place a small image as well just for visual effects. so for me I used the left and right images as background images anyway!

Shankar Narayana Damodaran
  • 68,075
  • 43
  • 96
  • 126
Drake
  • 49
  • 1
  • Thanks! I needed to simulate an imagemap with empty anchors over an image and IE would only let you click if there was content. This fixed it. – MDCore Dec 06 '10 at 13:44
3

This is the best way to do it as used on the BBC website and the Guardian:

I found the technique here: http://codepen.io/IschaGast/pen/Qjxpxo

heres the html

<div class="highlight block-link">
      <h2>I am an example header</h2>
      <p><a href="pageone" class="block-link__overlay-link">This entire box</a> links somewhere, thanks to faux block links. I am some example text with a <a href="pagetwo">custom link</a> that sits within the block</p>

</div>

heres the CSS

/**
 * Block Link
 *
 * A Faux block-level link. Used for when you need a block-level link with
 * clickable areas within it as directly nesting a tags breaks things.
 */


.block-link {
    position: relative;
}

.block-link a {
  position: relative;
  z-index: 1;
}

.block-link .block-link__overlay-link {
    position: static;
    &:before {
      bottom: 0;
      content: "";
      left: 0;
      overflow: hidden;
      position: absolute;
      right: 0;
      top: 0;
      white-space: nowrap;
      z-index: 0;
    }
    &:hover,
    &:focus {
      &:before {
        background: rgba(255,255,0, .2);
      }
    }
}
jojojohn
  • 725
  • 2
  • 10
  • 19
3

Just have the link in the block and enhance it with jquery. It degrades 100% gracefully for anyone without javascript. Doing this with html isn't really the best solution imho. For example:

<div id="div_link">
<h2><a href="mylink.htm">The Link and Headline</a></h2>
<p>Some more stuff and maybe another <a href="mylink.htm">link</a>.</p>
</div>

Then use jquery to make the block clickable (via web designer wall):

$(document).ready(function(){

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

});

Then all you have to do is add cursor styles to the div

    #div_link:hover {cursor: pointer;}

For bonus points only apply these styles if javascript is enabled by adding a 'js_enabled' class to the div, or the body, or whatever.

Justin
  • 55
  • 1
  • i want to use this but i have 2 links in the div... how can i modify it to be able click on both links? (it currently takes me to "mylink.html" if i click the second link as well..) – m3tsys Jul 26 '11 at 11:15
3
<a href="…" style="cursor: pointer;"><div> … </div></a>
2

Actually you need to include the JavaScript code at the moment, check this tutorial to do so.

but there is a tricky way to achieve this using a CSS code you must nest an anchor tag inside your div tag and you must apply this property to it,

display:block;

when you've done that,it will make the whole width area clickable (but within the height of the anchor tag),if you want to cover the whole div area you must set the height of the anchor tag exactly to the height of the div tag,for example:

height:60px;

this is gonna make the whole area clickable,then you can apply text-indent:-9999px to anchor tag to achieve the goal.

this is really tricky and simple and it's just created using CSS code.

here is an example: http://jsfiddle.net/hbirjand/RG8wW/

Hbirjand
  • 1,945
  • 19
  • 25
1

This is the simplest way.

Say, this is the div block I want to make clickable:

<div class="inner_headL"></div>

So put a href as follows:

<a href="#">
 <div class="inner_headL"></div>
</a>

Just consider the div block as a normal html element and enable the usual a href tag.
It works on FF at least.

Claudio
  • 884
  • 1
  • 15
  • 31
jeevanism
  • 29
  • 1
1

You can give a link to your div by following method:

<div class="boxdiv" onClick="window.location.href='https://www.google.co.in/'">google</div>
<style type="text/css">
.boxdiv {
    cursor:pointer;
    width:200px;
    height:200px;
    background-color:#FF0000;
    color:#fff;
    text-align:center;
    font:13px/17px Arial, Helvetica, sans-serif;
    }
</style>
Swarnamayee Mallia
  • 2,004
  • 14
  • 11
1

You can make surround the element with a href tags or you can use jquery and use

$('').click(function(e){
e.preventDefault();
//DO SOMETHING
});
THE AMAZING
  • 1,496
  • 2
  • 16
  • 38
1

This work for me:

<div onclick="location.href='page.html';"  style="cursor:pointer;">...</div>
DejanR
  • 441
  • 4
  • 11
0

I pulled in a variable because some values in my link will change depending on what record the user is coming from. This worked for testing :

   <div onclick="location.href='page.html';"  style="cursor:pointer;">...</div> 

and this works too :

   <div onclick="location.href='<%=Webpage%>';"  style="cursor:pointer;">...</div> 
Hari
  • 1,509
  • 15
  • 34
becky
  • 11
  • 1
    code doesn't show for some reason I used the onclick with a jsp variable inside to create a dynamic link – becky Apr 19 '12 at 15:13
0

Enclosing your div inside an anchor tag <a href></a> works like charm:

    <a href="">
      <div>anything goes here will turn into a link</div>
    </a>
saran
  • 356
  • 1
  • 3
  • 14
0

If you can use bootstrap, one simple solution is to use bootstrap .stretched-link.

https://getbootstrap.com/docs/4.3/utilities/stretched-link/

Sample Code

<div class="card" style="width: 18rem;">
  <img src="..." class="card-img-top" alt="...">
  <div class="card-body">
    <h5 class="card-title">Card with stretched link</h5>
    <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
    <a href="#" class="btn btn-primary stretched-link">Go somewhere</a>
  </div>
</div>
Pyae
  • 500
  • 1
  • 4
  • 15
0

Soviut's answer was not sufficient for me. I had to use

a { display: inline-flex; }

to remove baseline artifacts, when using just a img in the a.

ceving
  • 21,900
  • 13
  • 104
  • 178
0

Pure HTML & CSS case. No JS.

In case if you want to have other link elements inside of that fully clickable div.

Main idea is to stretch main clickable link, place it under the content, and disable clicks for content with pointer-events. For clickable elements inside of this element, set pointer-events: all; for each one.

Live demo:

<div style="
            width: 300px; height: 300px;
            position: relative;
            border: 1px red solid;
            pointer-events: none;
            z-index: 0;
            ">
  <h1>No wrapper</h1>
  <p>This is fully clickable div, click handled by anchor tag. It contains no wrapper</p>
  <button>Learn more</button>

  <p>See this link ➡️ <a style="pointer-events: all;" title="Why I see this ad?" href="http://example.com/">?</a></p>

  <a style="
            position: absolute;
            top: 0;left: 0;right: 0; bottom: 0;
            text-indent: -9999px;overflow: hidden;
            pointer-events: all;
            z-index: -1;
            " title="GO TO YANDEX" href="https://ya.ru">CLICK</a>
</div>

Codepen: https://codepen.io/ColCh/pen/OJaPpJQ

ColCh
  • 3,016
  • 3
  • 20
  • 20
0

While I don't recommend doing this under any circumstance, here is some code that makes a DIV into a link (note: this example uses jQuery and certain markup is removed for simplicity):

<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript">

$(document).ready(function() {
    $("div[href]").click(function () {
        window.location = $(this).attr("href");
    });
});

</script>
<div href="http://www.google.com">
     My Div Link
</div>
halfer
  • 19,824
  • 17
  • 99
  • 186
Brian David Berman
  • 7,514
  • 26
  • 77
  • 144
  • 3
    Again, this is a functional solution, but not really in the spirit of the original question which was for an XHTML solution. While not a huge deal, your answer *does* start to add noise to the question. – Soviut May 08 '09 at 01:10
-2

My smarty pants answer:

"Evasive answer to: "How to make block level element a hyperlink and validate in XHTML 1.1"

Just use HTML5 DOCTYPE DTD."

Didn't actually hold true for ie7

onclick="location.href='page.html';"

Works IE7-9, Chrome, Safari, Firefox,

Hailei
  • 42,163
  • 6
  • 44
  • 69
-4

if just everything could be this simple...

#logo {background:url(../global_images/csg-4b15a4b83d966.png) no-repeat top left;background-position:0 -825px;float:left;height:48px;position:relative;width:112px}

#logo a {padding-top:48px; display:block;}



<div id="logo"><a href="../../index.html"></a></div>

just think a little outside the box ;-)

philipp
  • 15
  • 1