Semantically correct nested anchors

2019-07-09 05:06发布

I am working on a web applicaton. And what we also create is something that could be described as inline editing. Just to portray thing I am trying to solve I use example of Facebook post.

You have post like.

Steve Jobs added 5 new photos

Steve Jobs is link that redirects to his profile so in HTML, that would be:

<div class="post-block">
   <p><a href="stevejobs/" title="#">Steve Jobs</a> added 5 new photos.<p>
</div>

But what I want is the whole post "block" to be clickable although I want only that name to appear to be link. Normally in HTML logic would say to to this:

<a href="stevejobs/" title="#"><div class="post-block">
   <p><a href="stevejobs/" title="#">Steve Jobs</a> added 5 new photos.<p>
</div></a>

But this isn't semantically correct. Quick look to HTML 4.01 or any other standard says something like this:

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

How to create it semantically correct other than using javascript and defining div:hover state for the whole "div anchor"?

6条回答
老娘就宠你
2楼-- · 2019-07-09 05:29

HTML:

<div class="post-block">
 <p><a href="stevejobs/" title="#"><span class="author">Steve Jobs</span> <span class="posttext">added 5 new photos.</span></a> <p>
</div>

CSS:

.post-block { margin: 0px; } 
.post-block p { margin: 0px; } 
.post-block p a {display: inline-block; background-color: transparent; width: 100%; min-height: 100px; /* can be varied */ }
.post-block p span.author { display: inline-block; }
.post-block p span.posttext { display: inline-block; }
查看更多
Summer. ? 凉城
3楼-- · 2019-07-09 05:31

Just replace the anchor tag around "Steve Jobs" in your second example with a span and style it as you want:

<a href="stevejobs/" title="#"><div class="post-block">
    <p><span class="post-block-user">Steve Jobs</span> added 5 new photos.<p>
</div></a>

with CSS:

a {
    cursor: default;
}
.post-block-user {
    font-weight: bold;
    cursor: pointer;
}

or whatever styles you're looking to apply or not apply. Actually I would try to lose the div and put the class on the anchor tag, unless there's other reasons for keeping that structure.

查看更多
祖国的老花朵
4楼-- · 2019-07-09 05:35

I have had the same issue for years, in that I want to maintain HTML semantics and SEO semantics too e.g. heading tags and paragraphs etc., while still keeping default anchor behaviours, e.g. indicating the destination URL in-browser, keeping tabbing intact and keeping the default anchor hover actions, which JavaScript doesn't do inherently.

The best solution I could figure was to put an absolutely positioned, block-level anchor over (covering) the content, and use the parent element's hover action to integrate any behaviours into the actual content, which is semantically correct and should be parsed correctly by all web-crawlers, thus:

.post-block {
  position: relative;
}

.post-block p span.anchor {
  text-decoration: underline;
}

.post-block:hover p span.anchor {
  text-decoration: none;
}

.postblock a.overlay {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1; /* to be on the safe side */
  text-indent: -9999em;
}
<div class="post-block">
  <p><span class="anchor">Steve Jobs</span> added 5 new photos.<p>
  <a class="overlay" href="stevejobs/" title="#">Steve Jobs</a>
</div>

This works well for block and grid layouts and even plays nice with touch devices, because the anchor itself has no hover action - which some devices hijack the first click for :)

Not 100% sure if search engines penalise the text indent, but there are any number of additional work-arounds, discussion here to get anyone interested started.

查看更多
倾城 Initia
5楼-- · 2019-07-09 05:38

Nesting anchor tag is forbidden.

If you want only the name to appear as a link use anchor tag. And if you need entire block to be clickable do it in onclick function in jquery. Something like

$(.post-block).click(//your function);
查看更多
Juvenile、少年°
6楼-- · 2019-07-09 05:39

In HTML5, a can be used as block-level element.

<div class="post-block">
   <a href="stevejobs/"><p>Steve Jobs added 5 new photos.<p></a>
</div>

Now, remove the default link styling with CSS (.post-block a {text-decoration:none;}).

To get a link style back for the name, enclose the name in an element and add a class like "name". The b element would be a suitable choice here (otherwise use span):

<div class="post-block">
   <a href="stevejobs/"><p><b class="name">Steve Jobs</b> added 5 new photos.<p></a>
</div>

Now to get back the styling: .post-block .name {text-decoration:underline;}.

Enclosing the name in an element even allows you to use the microformat hCard, if you like.

查看更多
SAY GOODBYE
7楼-- · 2019-07-09 05:53

Since you don't want javascript(which would have been easier), here is another method:

<div class="post-block">
   <p><a href="stevejobs/" title="#">Steve Jobs <span style="color:none; text-decoration:none;">added 5 new photos.</span></a></p>
</div>

Any other style effects can be added. Such as cursor: none; etc. depending on your desired effect.

查看更多
登录 后发表回答