tags:

views:

756

answers:

5

I'd like to have something that looks and behaves as hyperlink inside larger rectangle (full page wide) which is also hyperlink. Below there is ASCII-art representation of what it should look like:

|-------------------------------------------|
| Some text  [_link_]                            |
|-------------------------------------------|

The whole outer rectangle (block element) is to be hyperlink. Inside this rectangle there should be some text, and at the end of this text there should be another link.

Unfortunately nesting links (A elements) is illegal in (X)HTML:

12.2.2 Nested links are illegal

Links and anchors defined by the A element must not be nested; an A element must not contain any other A elements.

(from http://www.w3.org/TR/html401/struct/links.html#h-12.2.2), so the most natural way of implementing above

<a href="xxx" style="display: block">
  Some text
  <a href="yyy">link</a>
</a>

is not valid HTML. What is even worse is that some web browsers in some cases enforce this requirement by moving inner link element just outside closing element of outer link element. This of course utterly breaks layout.

So what I'd like to ask is how to arrive at layout presented above using HTML and CSS (but no JavaScript), but without nested link elements in HTML source. It would be nice if behaviour was as close as possible to the one with nested link elements (for browsers which are not overly strict in implementing HTML standard).


Edit (16-01-2009)

Clarification: Solutions which use more than two link elements are perfectly acceptable

<a href="xxx" ...>Some text</a>
<a href="yyy" ...>Link</a>
<a href="xxx" ...>& nbsp;</a>
...
A: 

What I have done in the past is use Javascript to attach the proper functionality to the div (assuming that is the parent element) so that when it is clicked, window.location is ran opening the .href attribute of the child link.

Something like this perhaps.

// jQuery Code
$(".parentDivLink").click(function(){
  window.location = $(this).find("a.mainLink").attr("href");
});

<div class="parentDivLink">
  <a href="http://www.google.com" title="Google" class="mainLink">Click Me</a>
</div>
Jonathan Sampson
He said no Javascript.
Paolo Bergantino
You're right. Perhaps my second response will suffice.
Jonathan Sampson
+1  A: 

Perhaps this would work?

div.parentBox {
  position:relative;
  height:100px;
}
  a.someLink {
    position:absolute;
    top:0;
    left:0;
    height:100px;
  }

// Now just position the two spans

<div class="parentBox">
  <span class="someText">Some Text</span>
  <a href="#" class="someLink">
    <span class="linkText">Link Text</span>
  </a>
</div>
Jonathan Sampson
Smashing Magazine recently suggested something similar, but using padding rather than width and height since block will already fill up the available area. http://www.smashingmagazine.com/2008/12/15/10-useful-techniques-to-improve-your-user-interface-designs/
DavGarcia
Thanks for the link - this response was ad-hoc, so I will enjoy reading what SM has to say on the technique.
Jonathan Sampson
I'm confused.. where is the outer link?
Paolo Bergantino
@Paolo, There is no "outer link." Visually, there is, but semantically there isn't. Instead, the inner link is 100% the width of the parent, and 100% the height too. No matter where you click on the parent, you will be clicking on the inner link.
Jonathan Sampson
A: 

Just place on onclick event handler on the outer element which when clicked calls "window.location ='yourURLhere';"

You could add a style attribute - "cursor:pointer" to get the hand cursor when mouse over.

You could also have a css hover code block to get the colour changes.

EDIT: just realised no javascript, so in that case, keep the 'a' tag and simply define a style for it in css, that way you can give it height, width, etc.

Jobo
+1  A: 

You could try something like this:

<style type="text/css" media="screen">
    div.a {
     position: relative;
     background-color: #F88;
     z-index: 0;
    }
    a.b {
     position: relative;
     z-index: 2;
    }
    a.b:hover {
     background-color: #8F8;
    }
    a.c {
     position: absolute;
     top: 0;
     left: 0;
     width: 100%;
     height: 100%;
     z-index: 1;
    }
    a.c:hover {
     background-color: #88F;
    }
    a.c span {
     display: none;
    }
</style>

<div class="a">foo <a href="bar" class="b">bar</a><a href="foo" class="c"><span>baz</span></a></div>
Gumbo
A: 

A float with negative margins should work as well.

Tested (in IE6 only):

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&gt;
<html>
<head><title>Link within link</title>
<style type="text/css">
.Parent {
width: 500px;
background-color: yellow;
}
.sub {
float: left;
margin-left: -300px;
}
.foo {
display:block;
float: left;
text-decoration: none;
}
</style>
</head>
<body>
<a href="foo" Class="foo"><div class="Parent">foo </div></a>
<div class="sub"><a href="bar">Link text</a></div>
</body>
</html>

You do realize the great potential for user confusion.

Traingamer