Are You Allowed to Nest a Link Inside of a Link

Are you allowed to nest a link inside of a link?

Straight from the W3C for HTML4:

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.

Since the DTD defines the LINK element to be empty, LINK elements may not be nested either.

HTML 5

And for HTML5 it is a little different.

You cannot have Interactive Content inside an A element. Interactive Content includes anchor tags.

Are nested a links legal?

Nope.

Two parts of section 4.5.1 The a element in the HTML 5 spec together forbid this:

4.5.1 The a element


Categories:


Flow content.

Phrasing content.

Interactive content.

Palpable content.

...

Content model:


Transparent, but there must be no interactive content descendant.

(emphasis mine).

Since <a> elements cannot contain interactive content, but themselves are interactive content, it follows that an <a> element cannot contain another <a> element.

What's more, this doesn't work in real browsers. If you try out the HTML from the question (fiddle) in a browser, you will observe that the browser makes all four <a> elements siblings, rather than letting the inner ones descend from the outer ones.

Why are nested anchor tags illegal?

Keep in mind that an anchor isn't just a link, it's also something to which one can link. (Though the former use is far more common than the latter.) Quoting W3C (old, but relevant):

An anchor is a piece of text which marks the beginning and/or the end of a hypertext link.

To that end, don't think of an anchor as a link. Think of it as a point in the document which connects to (and/or from) another point (in the same document or another document, it makes no difference). Two points in some non-physical space which are connected by a non-physical thread.

Given that, anchors shouldn't contain a lot of content. If it contains a lot of content, it ceases to become a "point" and starts to become an "area." For example, imagine an anchor which when rendered takes up more space than the browser can display at once. If something links to that anchor, where should it go? The beginning? Middle? End? (Intuitively you might think the beginning, but you get the idea.)

Furthermore, anchors definitely shouldn't contain other anchors. The non-physical connections between the non-physical points can become ambiguous. Does the child anchor connect to the other point, or does the parent anchor connect to the other point? This probably doesn't result in being a big deal in most cases, since the vast majority of anchors today are one-way links from the anchor to another document. But the purpose of the anchor is more than just a one-way link to another document, so the definition continues to embody that purpose.

Valid alternative to nested links (a tags) for rich web applications?

A very important thing to note is that I'd like to preserve some of the defaults that come with links, including the fact that clicking it with middle click/ctrl opens in new tab, or that on hover the link is displayed at the bottom of Chrome...

First of all, great that you’re thinking about this – a large number of developers don’t, but just go “Ah, I’ll just drop a click handler on it, and then open the URL via location.href, and that’s that done & dealt with …”

Giving user’s their accustomed browser UI & functionality is a big part of accessibility IMHO.


So, since links can not be nested into each other (which makes sense of course, the resulting behavior would just be undefined – do we open the target URL of the inner link, or the outer?), another solution would be to emulate what you want to achieve via a little CSS trickery.

.card {  position: relative;  z-index: 1;  display: inline-block;  width: 100px;  padding: 50px;  background: #ccc;}
.cardlink { position: absolute; top: 0; bottom: 0; left: 0; right: 0; z-index: -1;}
<div class="card">  <a class="cardlink" href="#fullcardview"></a>  <p>Foo bar baz</p>  <p>    <a href="#like">Like</a>  </p></div>

Can I nest a button element inside an a using HTML5?

No, it isn't valid HTML5 according to the HTML5 Spec Document from W3C:

Content model: Transparent, but there must be no interactive content descendant.

The a element may be wrapped around entire paragraphs, lists, tables, and so forth, even entire sections, so long as there is no interactive content within (e.g. buttons or other links).

In other words, you can nest any elements inside an <a> except the following:

  • <a>

  • <audio> (if the controls attribute is present)

  • <button>

  • <details>

  • <embed>

  • <iframe>

  • <img> (if the usemap attribute is present)

  • <input> (if the type attribute is not in the hidden state)

  • <keygen>

  • <label>

  • <menu> (if the type attribute is in the toolbar state)

  • <object> (if the usemap attribute is present)

  • <select>

  • <textarea>

  • <video> (if the controls attribute is present)


If you are trying to have a button that links to somewhere, wrap that button inside a <form> tag as such:

<form style="display: inline" action="http://example.com/" method="get">
<button>Visit Website</button>
</form>

However, if your <button> tag is styled using CSS and doesn't look like the system's widget... Do yourself a favor, create a new class for your <a> tag and style it the same way.

href inside href

In order to have nested a please do the following changes ....

You have to wrap the nested a inside a object tag.

<a href="/venues/manage/">
<div class="col-md-4">
<div class="panel panel-default">
<img src="/img/venue.svg">
<h5 class="text-vert crop">
<b>Venue Title</b>
<object><a href="#" data-toggle="tooltip" title="Verified Venue">Verified</a></object>
</h5>
</div>
</div>
</a>

Here is a bootply (see the generated HTML) : http://www.bootply.com/MmYwCLTF0P

Here is a conference from Vitaly Friedman : https://vimeo.com/162334949

Nested Links & Buttons In A Card With Link NextJs

This issue is not really related to Next.js. You'd have the same issues with normal anchor tags because nesting links produces invalid HTML, though there are some workarounds like putting the nested link into an object tag.

Other than that, you could try the following approaches:

  1. Handle either the container link or the nested links via an onClick handler instead of an anchor tag.
  2. Don't nest your links in the HTML tree but instead make them siblings and align them using only CSS. You could use a div container and position all of your links with position: absolute inside that div.

In any case you will probably also need to look at event bubbling and add an onClick={e => e.stopPropagation()} where necessary.

Creating anchor tag inside anchor tag

As @j08691 describes, nested a elements are forbidden in HTML syntax. HTML specifications do not say why; they just emphasize the rule.

On the practical side, browsers effectively enforce this restriction in their parsing rules, so unlike in many other issues, violating the specs just won’t work. The parsers effectively treat an <a> start tag inside an open a element as implicitly terminating the open element before starting a new one.

So if you write <a href=foo>foo <a href=bar>bar</a> zap</a>, you won’t get nested elements. Browsers will parse it as <a href=foo>foo</a> <a href=bar>bar</a> zap, i.e. as two consecutive links followed by some plain text.

There is nothing inherently illogical with nested a elements: they could be implemented so that clicking on “foo” or “zap” activates the outer link, clicking on “bar” activates the inner link. But I don’t see a reason to use such a structure, and the designers of HTML probably didn’t see one either, so they decided to forbid it and thereby simplify things.

(If you really wanted to simulate nested links, you could use a normal link as the outer link and a span element with a suitable event handler as the inner “link”. Alternatively, you could duplicate links: <a href=foo>foo</a> <a href=bar>bar</a> <a href=foo>zap</a>.)

Nested text links in HTML

Use JavaScript for best results

I know:

I'd prefer solutions without scripting,

but…

any suggestions are welcomed.

You can add an inline onclick handler to a child span:

<a href="#A">AAAA <span onclick="event.preventDefault(); window.location.assign('#B'); return false;">BBBB</span> AAAA</a>

Or, to be DRY, pass in a reference to the handler instead:

<a href="#A">AAAA <span onclick="embedLink('#B');">BBBB</span> AAAA</a>

Definition of handler:

function embedLink(url) {
event.preventDefault();
window.location.assign(url);
return false;
}

Working example: