tags:

views:

175

answers:

8

Excuse me while I detach from reality.. I have a summary div which contains a small heading, a little bit of text, maybe an image. I'd like the whole summary div to be a link, something like this:

<div class="summary">
  <a href="#">
    <h4>Small Heading</h4>
    <p>Small amount of text</p>
  </a>
</div>

I'd then style the href to look like a nice box, change the H4 and P on :hover, etc etc. But putting an href there makes browsers angry.

Can anyone suggest a way of achieving the same effect without resorting to Javascript? Is that even possible?

Many thanks!

+1  A: 

This syntax - block level items inside links - is allowed in HTML5. This should be supported by all browsers (because people who don't know better have always done this stuff).

All you need to do is change your doctype and then boast to your friends how modern you are :-)

edeverett
I love this answer :D
Al
A: 

Why not use javascript?

<div class="summary" onclick="window.location.href='www.google.com';>
  <h4>Small Heading</h4>
  <p>Small amount of text</p>
</div>

With no javascript you will not get all the div area clickable. Only the text.

Andrejs Cainikovs
Progressive enhancement please. Your example won't work at all without JS.
David Dorward
Can you read? This code piece was left for an option if the guy will change his mind using JS. These times even my phone has JS.
Andrejs Cainikovs
A: 

how about changing the style of the a element to display:block?

Adrian Mester
That will not work, as an a element still cannot contain a block level element per w3c standards.
Residuum
+2  A: 

A pure CSS solution would be to do this:

<a href="#">
  <span class="header4">Small Heading</span>
  <span class="paragraph">Small amount of text</span>
</a>

Then change the A to a block element, and style the spans according to how you want the header and paragraph to look:

<style>
a {
 display: block;
}

span.header4 {
 display: block;
 font-size: 24px;
 font-weight: bold;
 margin: 0 0 10px 0;
}

span.paragraph {
 display: block;
 margin: 0 0 10px 0;     
}
</style>

HTML/CSS purist will won't like it, though!

Then the purist is a design goof. This degrades to text only browser really well, and the html/css is all valid! What would they have to complain about?
rpflo
It doesn't degrade to text only well as the meaning of the tags is lost so the browser doesn't know that the heading is a heading...
edeverett
Thanks 10goto10 - you're right I didn't want to use spans initially but it seems to be the best available option.
Al
It doesn't degrade to text only really well. It doesn't work nicely with a screen reader in "Tell me the headings" mode. It doesn't give nice SEO for the text. It doesn't give sane lengths of links for "Read me the links" mode in screen readers. It doesn't help generate a nice table of contents for a document.
David Dorward
A: 

Expanding on what Andrejs said:

    a.clickDiv {
       display:block;

    }


    <a href="somelink.html" class="clickDiv">

    content

    </a>
A: 

The short answer is "Not with valid, standard, semantically correct HTML". (HTML 5 isn't standard yet and needs hacks to get it to work in various browsers)

You can achieve it if you resort to invalid techniques, or by throwing away headings, but this isn't a good idea.

A reasonable number of users skim links in documents looking for useful ones. Screen reader users are a good example. If the link text is huge (as it would be in your example) this benefit is lost.

Using JavaScript is a good solution here (but, naturally, only in a way which is still functional if JS is not available).

I'll use jQuery for this example (it does sufficient different things with the DOM to justify it).

<div class="summary">
    <h4><a href='#'>Small Heading</a></h4>
    <p>Small amount of text</p>
</div>

jQuery('div.summary').click(function () {
    jQuery('a', this).click();
});

I haven't tested this, but if click() doesn't do what I expect you can replace it with:

jQuery('div.summary').click(function () {
    document.location = jQuery('a', this).attr('href');
});

If JavaScript is not available, the heading is still a clickable link. If it is, then the whole area can be clicked.

You can add hover effects with:

jQuery('div.summary').addClass('hoverable');

and

div.hoverable:hover { background-color: green; }

(This way the hover effect won't fire if JS is not available but CSS is)

David Dorward
Seriously this is your answer? Ouch, how'd you get to 21k?
drlouie - louierd
A: 

I may be missing your goal altogether.

When I copied your example code to a text editor and opened it in a browser (FF 3.5 on Leopard), it worked fine. I even added a bit of styling to be sure.

So is it a specific browser that it breaks on? Or is it that it doesn't validate?

Did you try placing the anchor tag on the outside of the div?

Anthony
This should work on all modern browsers as they are built to display invalid HTML as best as possible and the meaning of this is not ambiguous.HTML5 takes advantage of this and includes it in the specification, so to make things validate, just change the doctype to the HTML5 doctype.
edeverett
So it breaks in older browsers without the correct DTD or it is not valid under HTML4 (or both?). Bear in mind this isn't my question. But I am curious what the original problem was (actual visual problem).
Anthony
It shouldn't break. It's just not valid. (I know this works in all browsers with any significant market share at the moment - I don't know how it works in Netscape 4, Safari 1.3 etc.)
edeverett
For what it's worth, my new site is being made in HTML5 precisely so that I can use this syntax. So I've been doing some browser testing on this.
edeverett
A: 

This will do what you want, but you'll lose the ability to select (copy+paste) text that is under the link overlay. You also won't have control over the :hover pseudo-class in IE6 (since IE6 and below doesn't support it).

Here's the HTML:

<div class="summary">
    <h4>Some Text</h4>
    <p>A short description</p>
    <a href="#" class="overlay">Anchor Text</a>
</div>

And here's the CSS:

<style>
div.summary {
 position: relative; 
 width: 200px; 
 height: 100px; 
 z-index: 10; 
}

div.summary h4 {
 position: relative;
 font-size: 18px;
 font-weight: bold; 
}

div.summary p {
 position: relative; 
}

a.overlay {
 display: block; 
 position: absolute; 
 text-indent: -9999px; 
 width: 200px; 
 height: 100px; 
 z-index: 30; 
 top: 0; 
 left: 0;
}
</style>

As a note, make sure you declare a position on the container element of the .overlay class, so that absolute positioning works. You also need to make sure you declare a position on the parent element of each z-index positioned element.

Let me know if you have any issues.

Intelekshual