Semantically correct nested anchors

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.

<strong>Steve Jobs</strong> 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"?


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.



<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>


.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; }


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.


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:

<div class="snippet" data-lang="js" data-hide="false"> <div class="snippet-code">

.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>

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.


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.


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);


  • How to set div exactly in the center of screen whose size is changing dynamically
  • Javascript - Infinite scroll JSON array?
  • dojo 1.9: what annotation does declare.safeMixin add?
  • how do you read the ramda docs?
  • Configuring a TreeView which scans Local fie system to only include folders which have a file type
  • JAXB: How to bind element with namespace
  • Post comment to WordPress Blog from iPhone programmatically
  • Could not install package 'Microsoft.Owin.Security 2.0.1'
  • Query timeout expired in django-mssql when executing custom SQL directly
  • Weird LEFT OUTER JOIN on Includes eager loading of rails 3
  • Mongoose TypeError: Cannot use 'in' operator to search for '_id' in
  • Reloading table causes flickering
  • Can you build a truly RESTful service that takes many parameters?
  • Pre-populated SQLite Database not reading properly in Android Studio
  • Can long-polling be achieved in Restlet by just making the thread sleep?
  • What is the default HTTP verb in WebApi ? GET or POST?
  • ckeditor and jquery UI dialog not working
  • Converting query results into DataFrame in python
  • LESS CSS how to modify parent property in mixin
  • Prevent Tomcat from caching request during starup
  • Floated image with variable width and heading with background image
  • Possible to get mouse events fired when cursor is outside page?
  • NUnit 3.0 TestCase const custom object arguments
  • ASP.NET MVC 2 Preview 2 - display directory list rather than home/index
  • xcode don't localize specific strings
  • Adjust width of select element according to selected option's width
  • jQuery ready not fired after rails link_to is clicked
  • how to display data from 1st point on words on y axis for line chart in d3.js
  • Listbox within Listbox and scrolling trouble in Windows Phone 7 Silverlight
  • Yii2: Config params vs. const/define
  • Change multiple background-images with jQuery
  • Algorithm for a smudge tool?
  • Java Scanner input dilemma. Automatically inputs without allowing user to type
  • Change JButton Shape while respecting Look And Feel
  • Why doesn't :active or :focus work on text links in webkit? (safari & chrome)
  • Modifying destination and filename of gulp-svg-sprite
  • Join two tables and save into third-sql
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • CSS Applying specific rule for a specific monitor resolution with only CSS is posible?
  • Change div Background jquery