Skip to main content
Ben Nadel at CFCamp 2023 (Freising, Germany) with: Raphael Schürholz
Ben Nadel at CFCamp 2023 (Freising, Germany) with: Raphael Schürholz

Anchor Tags Can Contain Block-Level Elements As Of HTML5

By
Published in Comments (8)

The world of web development moves quickly; and, it is often be hard for me to keep my mental model in alignment with the current trends and standards. Today, I learned that one of my internal rules was critically out of date. As of HTML5 - which was released years ago - it is OK to wrap block-level elements inside of an Anchor tag. In fact, pretty much the only thing you can't put inside of an Anchor tag is another Anchor tag. This new understanding is going to completely change my HTML markup choices.

Run this demo in my JavaScript Demos project on GitHub.

View this code in my JavaScript Demos project on GitHub.

Prior to HTML5, Anchor tags - <a> - could only contain "inline" elements (aka, "phrasing content"). To live comfortably within this specification, I often reached for embedded <span> tags that were styled to behave like block-level elements:

<a href="https://www.bennadel.com" class="block">
	<span class="block">
		Ben Nadel
	</span>
	<span class="block">
		Lover of JavaScript, HTML, and CSS.....
	</span>
</a>

Here, the <a> is semantically "correct" in that it only contains the inline elements <span>, even though both the <a> and <span> tags are styled to behave like block-level elements.

As of HTML5, however, such finagling is no longer needed. From the W3C specification for the Anchor tag:

Changes in HTML5

Although previous versions of HTML restricted the a element to only containing phrasing content (essentially, what was in previous versions referred to as "inline" content), the a element is now transparent; that is, an instance of the a element is now allowed to also contain flow content (essentially, what was in previous versions referred to as "block" content) - if the parent element of that instance of the a element is an element that is allowed to contain flow content.

This means that I can use just about anything that makes sense inside of an Anchor tag. To demonstrate, here's a "User Card" that is an Anchor tag that contains block-level elements:

<!doctype html>
<html lang="en">
<head>
	<meta charset="utf-8" />

	<title>
		Anchor Tags Can Contain Block-Level Elements As Of HTML5
	</title>

	<link rel="stylesheet" type="text/css" href="./style.css" />
</head>
<body>

	<h1>
		Anchor Tags Can Contain Block-Level Elements As Of HTML5
	</h1>

	<!--
		NOTE: This is an Anchor tag that contains the BLOCK Elements, Div and P. Prior
		to HTML5, this was not valid; however, as of HTML5, the Anchor tag can now
		contain both INLINE and BLOCK elements. Woot woot!
	-->
	<a href="https://www.bennadel.com" target="_blank" class="card">
		<img
			src="https://www.gravatar.com/avatar/f9bbc701ca6770ef482cc1e172344e25?s=120"
			alt="Avatar of Ben Nadel"
			class="avatar"
		/>
		<div class="name">
			Ben Nadel
		</div>
		<p class="description">
			Lover of JavaScript and Movies and Dogs and all things pudding. Free spirit
			with a rigid sense of timing.
		</p>
	</a>

</body>
</html>

As you can see, the <a> tag contains the block-level elements, <div> and <p>. If we run this page in the browser, we get the following output:

User Card that is made of an Anchor tag containing block-level elements in HTML5.

And, what's more, if we run this through the W3C Markup Validator, we get:

Document checking completed. No errors or warnings to show.

I know I'm like 5-10 years behind on this knowledge; which is to say, somewhat embarrassing. I think back to how many <span> tags have been used needlessly in an effort to author "correct" HTML. But no more! This particular gap in my mental model has been fixed. And, I will start reaching for more semantically correct elements, even when embedded within a block-styled Anchor tag.

Want to use code from this post? Check out the license.

Reader Comments

1 Comments

Be sure not to overlook that qualifier in the last part of the quoted spec: "... if the parent element of that instance of the a element is an element that is allowed to contain flow content."

i.e. an A which is a child of a SPAN or am EM cannot legally contain block elements.

15,811 Comments

@Stephan,

That's a really good catch / point! My primary use-case for something like this is probably going to be in a list-item scenario like:

<li>
	<a href="#">
		<div class="some-blocky-thing">
			<!-- ... -->
		</div>
	</a>
</li>

So, for me, that's a limitation that I'll be able to work with.

15,811 Comments

@Samiullah,

It's a group effort to learn all this stuff, am I right?! Too much for any one person to keep in their head, by far!

1 Comments

Its useful but also can be used in the wrong way, I know the user card is an example but consider accessibility, wrapping lots of content in a single anchor can create issues for users of screen readers.

Have a read of this https://inclusive-components.club/cards/ there are techniques out there that can make a card completely clickable like everything is wrapped in an anchor when really it is only the necessary text,

15,811 Comments

@Claudia,

I suppose that block-level elements are not arbitrarily exchangeable. Just because an Anchor tag can now contain block-level elements, I don't think that it means an Anchor can go anywhere.

15,811 Comments

@Sean,

That's very interesting. I'm relatively new to thinking about accessability at this level. I will give your link a reading. I am wondering if we could perhaps using something like title to override the contents? Just thinking out-loud. I also see that there is a book by the author of that content, will definitely check that out!

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel