The <section> element

Previously on the CogitActive Saga:
Admittedly, adding the <section> element to my articles would be beneficial for improving the semantic structure of my content.

Introduction

It all started with a simple goal: turning my headings into link targets. A seemingly straightforward task—just one step in my blog housekeeping journey—that, as usual, turned into a rabbit hole of discovery. I could have simply added ID attributes to my headings and called it a day. Done.

Acceptable:
<h2 id="introduction-to-everything">Introduction to everything</h2>

If you follow this blog, you know I don’t do “quick.” I don’t just implement—I interrogate. In keeping with CogitActive principles, I investigate, I study, I question, I chase down the “right” way until I either find it or exhaust myself trying. I can’t help it—I need to understand the why, not just the how. So when I set out to add anchor links to my headings, I didn’t stop at the first solution. I kept digging, kept questioning, and before I knew it, I had a second post in the making. Again 1.

I keep going until I’m confident I’ve found the best way.

And I found it—the proper, recommended way to add an anchor to a heading: wrap the heading in a <section> element with an id attribute.

Recommended:
 <section id="introduction-to-everything">
  <h2>Introduction to everything</h2>
  ...
 </section>

To be honest, this was the first time I had encountered this element. Remember, I’m not a web developer—I discovered HTML when I embarked on this website adventure. Still, the logic behind it was compelling. According to the HTML specification, a <section> represents a thematic grouping of content, typically introduced by a heading. It’s not just a container—it’s a meaningful structural unit.

I quickly recognized that using <section> throughout my blog posts could enhance the semantic clarity of my content. But the deeper I dug into its technical implications, the more I realized this wouldn’t be a simple change. Implementing the recommended structure would mean retrofitting every single post I’ve written—a massive undertaking in the context of my blog housekeeping. I care deeply about doing things the right way. But at that moment, I had to set the <section> element aside:

I will come back to the <section> element, and whether I should use it or not, in a future post.CogitActive

Although I opted for the “acceptable” approach—making the header elements themselves the anchors—for my housekeeping endeavor, I didn’t reject the <section> element altogether. I knew it could improve accessibility for screen readers and potentially benefit SEO. But would it benefit my sighted readers as well? And more importantly, is it appropriate for my blog? Now, it’s time to figure out.

The <section> element: what the docs say

The <section> element is one of the semantic elements introduced with HTML5 for structuring the content in webpages. Before (HTML5), developers relied heavily on <div> elements to organize content. While useful for layout, <div> carries no semantic meaning—it’s just a generic container. This widespread reliance led to what many dubbed “div soup”: a tangled mess of indistinct wrappers that made it difficult for browsers, screen readers, and search engines to interpret the structure and purpose of a page. Without meaningful tags, machines couldn’t distinguish between navigation, main content, or sidebars, and accessibility suffered as a result.

Box 1: HTML5

HTML5 is the fifth and final version of the HyperText Markup Language formally published by the World Wide Web Consortium (W3C) in 2014. It was designed to modernize the web by replacing both HTML4 and XHTML1, introducing new features while remaining backward-compatible. Its goals were to support multimedia natively, improve accessibility, and make web content more meaningful to both humans and machines.

Among its most important contributions was the introduction of semantic elements—tags like <section>, <article>, <nav>, <header>, and <footer>—which allow developers to structure content based on meaning rather than presentation. These elements help screen readers, search engines, and browsers better interpret the purpose of each part of a page.

Although HTML5 was once a versioned specification, it has since been retired by the W3C. Today, the language continues to evolve as the HTML Living Standard, maintained by the Web Hypertext Application Technology Working Group (WHATWG), a consortium of major browser vendors. This shift reflects a new philosophy: HTML is no longer released in discrete versions, but updated continuously to meet the changing needs of the web.

The term HTML5 is essentially a buzzword that refers to a set of modern web technologies. This includes the HTML Living Standard, along with JavaScript APIs to enhance storage, multimedia, and hardware access.MDN Web Docs

The <section> element represents a standalone, thematic grouping of content within a document. It’s not just a container—it’s a semantic signal that the enclosed content belongs together (e.g., chapters in a book) and contributes to the document’s structure. Importantly, it should be used only when no more specific semantic element applies. If the content fits a more specific semantic role—like a blog post (<article>), navigation menu (<nav>), or sidebar (<aside>)—those elements should be used instead.

A general rule is that the section element is appropriate only if the element’s contents would be listed explicitly in the document’s outline.WHATWG

Each <section> should ideally have a heading (<h1><h6>) to describe its purpose. This isn’t just a best practice—Sections should always have a heading, with very few exceptions. Headings help browsers, screen readers, and search engines understand the hierarchy and meaning of the content. Proper nesting of <section> elements—each with its heading—also allows screen readers to generate an outline of the page 3, making navigation easier for users who rely on them.

The MDN Web Docs also specifies that the <section> element only supports global attributes—those that are common to all HTML elements. These attributes provide additional functionality or metadata, regardless of the tag they’re applied to. Two global attributes are especially relevant here:

id — This is the attribute I initially set out to use when trying to turn my headings into link targets (see introduction). It defines a unique identifier for the element, making it a target for links, scripts, and styles.

role — This attribute defines the semantic purpose of an element for assistive technologies. I’ll return to the role attribute in more depth later.

To sum up, used correctly, <section> brings real benefits. It improves accessibility by helping assistive technologies navigate the page more effectively. It enhances SEO by signaling content structure to search engines. And it makes code more readable and maintainable for developers.

If you’re familiar with the HTML section element, then you understand just how instrumental it is to organize your document successfully.Anna Fitzgerald

Is the <section> element appropriate for blog posts?

On paper, the <section> element looks like a clear improvement (see above), and I knew I should use it from the very beginning. That much was clear from the Google Developer Documentation Style Guide—it didn’t just suggest it, it recommended it. And if Google says it’s best practice, it must be valid, right?

Authors might prefer the former style for its terseness, or the latter style for its additional styling hooks. Which is best is purely an issue of preferred authoring style.WHATWG

But as I mentioned when I first encountered it, adopting <section> isn’t frictionless. There are real headaches involved—like figuring out how to implement it within the Gutenberg editor (checked), and navigating a few lingering questions I still hadn’t answered. To be honest, even with the Gutenberg part figured out, integrating the <section> element into my workflow would be a significant shift. It might prove beneficial in the long run, but it would definitely slow down my already time-consuming publishing process. It’s not just a matter of adding a tag— as you’ll see toward the end of this post, provided I actually finish it before the complexity derails me, again 1.

So if I were to go down this path, I needed to be absolutely sure that <section> was appropriate for my use case—not just valid in theory, but suitable for blog posts specifically.

From frustration…

I just wanted to know if using <section> to wrap headings—specifically in a blog post—was the right move. Simple question, right? So I did what anyone would do: I checked other blogs. From personal sites like mine to polished company blogs, I scrolled through dozens. And guess what? Not a single one used <section> to assign ID attributes to their headings. They all followed the “acceptable” way—just like WordPress did during that brief moment when they flirted with the feature.

So I kept digging. I read everything. Yes, that’s a lot—and that’s why this is post #365 (a little hooray for that milestone; if I published daily instead of weekly, my blog would be a year old—funny thought) and not #332. But every article I found missed the point. None of them addressed my actual question: is <section> appropriate for a single blog post with multiple headings? They all focused on homepage layouts 4, like the example in the WHATWG spec:

A web site’s home page could be split into sections for an introduction, news items, and contact information.

Indeed, nearly every article I encountered at the time (see right) explained how to use the <section> element to structure large, multi-purpose layouts—much like the example from the WHATWG spec. The focus was on carving out zones that made a page easier to scan and navigate, often in tandem with other semantic elements like <header>, <nav>, <main>, and <footer>. In short, <section> was framed as a tool for highlighting significant parts of a web page when no more specific landmark element applied.

But what about my use case—adding an anchor to a heading within a single blog post? Was <section> appropriate there? Not one article zoomed in on the anatomy of a blog post 4. Worse still, many warned against overusing <section>, cautioning that it could clutter the markup and dilute its semantic value.

Overpopulating a web page with landmarks will reduce their ability to help users find the most important parts of web pages. In other words, if everything’s a landmark then there’s nothing really special about them, is there? Instead, rely on proper heading levels to indicate implicit sections and sub-sections of your content.Scott O’Hara

…to the Eureka moment

I kept digging. I had to. The delay I mentioned earlier? It wasn’t procrastination—it was persistence. I refused to stop until I found something that made sense. But the deeper I went, the more frustrated I became. Why did Google keep recommending an approach that nobody seemed to use? Why did every article echo the same pattern—layouts, landmarks, homepage anatomy—while my use case remained invisible?

By Kevin Powell

Kevin Powell’s video, “HTML section elements are a lie (sort of)”, wasn’t about blog posts. It wasn’t about anchoring headings. It was yet another take on layout-centric usage. But this time, something clicked. He highlighted a subtle but crucial detail from the W3C spec: the <section> element only becomes a landmark—specifically, role="region"if, and only if, it has an accessible name. Otherwise, it defaults to a generic role 5.

HTML ElementDefault Landmark Role
sectionregion when it has an accessible name using aria-labelledby, aria-label or title attribute

That was it. That was the missing piece. Suddenly, all those articles I’d read made sense—they were assuming <section> was always a landmark, as if it inherently carried role="region". In fact, Kevin admitted he’d always assumed the same, which is precisely what prompted his video.

Since then, I’ve found other sources confirming this nuance. And strangely enough, after that realization, my search results began to shift—as if Google had finally tuned in to what I was really asking. But more importantly, when I narrowed my focus to trusted, authoritative sources, the message was consistent and unequivocal. Still, to be absolutely sure, I verified it myself using the Accessibility tab in Microsoft Edge’s Developer Tools. This panel reveals the accessibility tree—a simplified structure that shows how assistive technologies interpret the page. When inspecting a <section> element without an aria-label, aria-labelledby, or title attribute, its role was listed as “generic,” not “region.” No landmark functionality.

So while I didn’t yet have a definitive answer to whether <section> is appropriate for my use case, I knew what to look for and what to ignore:

Generally, you can forget about <section> elements because they were introduced to support the outline algorithm, which went nowhere.Stefan Judis

Why <section> matters more than I thought

Turns out, the <section> element is a potent tool in the semantic HTML toolbox—its value goes far beyond landmark functionality (role="region"). Even when used as a semantically valid but generic container, <section> can be nested to reflect the true hierarchy of content. This deepens the document outline, making it easier for screen reader users to navigate and for search engines to interpret the structure—potentially boosting accessibility and SEO alike. So yes, not only is the <section> element appropriate for a blog post, it’s ideal (and “recommended”) for my use case: anchoring headings with semantic precision.

Admittedly, it’s not required, and it’s certainly not widely adopted. Most blogs—including WordPress itself—stick to the “acceptable” method of assigning IDs directly to headings. But I’m not “most.” I adhere to CogitActive principles, striving for excellence and committing to quality—no matter the cost. If there’s a better way (“recommended”) to do something, I won’t settle for the “acceptable” one, even if the latter is valid and the former demands more effort.

Headings alone can only show where a piece of content starts, not where it ends, which makes it difficult to tell what belongs to what.Heydon Pickering
Brain
All right reserved

This ambiguity is more than theoretical—it’s demonstrable. So let’s put it to the test with a quick quiz and a real example from this very post. Just above, I included the following:

So while I didn’t yet have a definitive answer to whether <section> is appropriate for my use case, I knew what to look for and what to ignore:

Generally, you can forget about <section> elements because they were introduced to support the outline algorithm, which went nowhere.Stefan Judis

Where would you place this in the document’s structure? Put differently: Which heading do you instinctively associate this with?

“Is it part of the subheading ‘…to the Eureka moment’ that comes right before it? Or does it belong to the broader section ‘Is the <section> element appropriate for blog posts?’?”

Correct answer: It belongs to the H2 heading “Is the <section> element appropriate for blog posts?”, not the H3 subheading that visually precedes it.

This confusion stems from relying solely on heading levels to imply structure. Without sectioning elements to wrap and define boundaries, paragraphs like the above example float ambiguously in the markup—misleading screen readers, search engines, and even sighted readers who assume visual proximity equals semantic grouping. Without explicit sectioning, the document outline becomes a guessing game. The very element that could have clarified this structure is <section>!

Authors are also encouraged to explicitly wrap sections in elements of sectioning content, instead of relying on the implicit sections generated by having multiple headings in one element of sectioning content.W3C Working Draft

To make this clearer, I’ve created a visual representation of the document’s structure—the very one that led to the ambiguity in the quiz. Take a look at the illustration below. It mirrors the HTML outline and shows exactly why that final paragraph appears to fall under the wrong heading.

Heading Level 1

This paragraph belongs to heading level 1.

Heading Level 2

This paragraph belongs to heading level 2.

Heading Level 2

This paragraph belongs to heading level 2.

This paragraph belongs to heading level 1, not level 2!

To make this clear, we should add sections!

Authors should explicitly section elements and not rely on heading levels to implicitly create them.Nat Dunn

The power of sectioning lies in its ability to prescribe clearly defined boundaries, resulting in a more modular document hierarchy. Because sectioning elements wrap their contents, we know exactly where they begin—and more importantly—where they end. We know what content belongs to what. Or at least, assistive technologies and indexing parsers do. What about sighted readers? That’s a problem I’ve yet to tackle.

If clarity, accessibility, and semantic integrity matter to you, then <section> is not just a tool—it’s a necessity.

The unanswered questions—Let’s clear them up

When I first encountered the <section> element—during my search for the proper way to anchor a heading—I immediately understood that it would be appropriate to use it to divide the different parts of a blog post. Still, I flagged a few concerns at the time, what I referred to as “headaches,” that ultimately led me to lower my standards and opt for the “acceptable” approach instead. Some of the questions I uncovered were quickly resolved (for instance, yes, <section> elements can be nested), but others remained unanswered. One caveat stood out in particular: my introduction itself posed a problem, as it lacked a heading entirely.

“Should I use <section> for the introduction of a post that doesn’t have a heading?”

Technically, no. Using the <section> element without a heading would compromise the very semantic structure it’s meant to reinforce. Still, what about the exceptions noted in the MDN Web Docs? After all, they do say: Sections should always have a heading, with very few exceptions.

Circumstances where you might see <section> used without a heading are typically found in web application/UI sections rather than in traditional document structures. In a document, it doesn’t really make any sense to have a separate section of content without a heading to describe its contents. Such headings are useful for all readers, but particularly useful for users of assistive technologies like screen readers, and they are also good for SEO.

So that settles it—not an option! But if my introduction can’t be wrapped in a <section>, what can I do instead? Should I restructure it to include a heading? I’ve avoided doing so because it feels awkward in the context of a blog post—unlike a scientific paper, where an introductory heading is expected (at least, when you submit your manuscript for publication). Aesthetically, I’ve always preferred a clean, heading-free opening. But if I’m serious about aligning with the principles of semantic HTML, maybe it’s time to challenge my “looking good” argument. To be honest, I really struggled with this one—until I revisited this insight:

A general rule is that the section element is appropriate only if the element’s contents would be listed explicitly in the document’s outline.WHATWG

“Do I want the introduction to appear in the document outline?”

As I’ve hinted before, I’m more accustomed to the structure of scientific papers than blog posts—but I didn’t want that bias to cloud my judgment. So I tried to think in terms of accessibility, setting aesthetics aside. Would including the introduction in the table of contents (ToC) be helpful? Framed like that, maybe not. But if the ToC is used for navigation, then yes—readers might appreciate a link back to the introduction, especially in longer articles like this one. More importantly, screen readers would benefit from the added clarity. That’s an accessibility win. But what about my aesthetic?

Accessibility isn’t just a nice-to-have; it’s foundational.

I didn’t want to clutter the visual flow of my post with an obvious “Introduction” heading—it felt out of place, more academic than blog-like. But I also couldn’t ignore the accessibility and semantic benefits of wrapping the intro in a <section> with a proper heading. So, I found a middle ground: I added a heading, but made it visually hidden. Using a simple CSS class (.visually-hidden, for instance), I ensured the heading was invisible to sighted readers but fully accessible to screen readers and search engines. That way, the introduction became a clearly defined section—structurally sound, semantically correct 6, and still aesthetically clean. All without disrupting the look and feel of the post. Sometimes, the best design is the one you don’t see.

The logical next step would’ve been to hunt down the CSS for .visually-hidden. But I didn’t have to—my theme, Twenty Seventeen, already had me covered. It ships with a fully accessible utility class:

/* Text meant only for screen readers. */

.screen-reader-text {
	clip: rect(1px, 1px, 1px, 1px);
	height: 1px;
	overflow: hidden;
	position: absolute !important;
	width: 1px;
	word-wrap: normal !important; /* Many screen reader and browser combinations announce broken words as they would appear visually. */
}
Box 2: One <h> to rule them all
Sections may contain headings of any rank, but authors are strongly encouraged to either use only h1 elements, or to use elements of the appropriate rank for the section’s nesting level.W3C Working Draft

You’ve probably heard the rule: There should only ever be one <h1> element on the page. So why do so many HTML5 examples—including official documentation—feature multiple <h1>s? The answer lies in a bold idea from the early HTML5 era: the outline algorithm. This model was designed to simplify modular content reuse and improve semantic clarity. The concept was that each sectioning element—like <section>—could start its own outline. Within that scope, a heading like <h1> would be interpreted relative to its nesting, not globally. There was even talk of a generic <h> element—free from numbered levels—that would let the browser assign hierarchy based on context.

By “producing” the required heading level automatically, we no longer have to decide separately which numbered heading we should include. It effectively prevents us from choosing the wrong heading level, which would be bad for parsable structure. A subsection must be subject to its parent section. Because this relationship between sections determines “level,” numbered headings are made redundant — hence, the proposed <h>.Heydon Pickering

As it turns out, we didn’t get the generic <h> element. Despite its inclusion in early W3C Working Drafts, the HTML5 outline algorithm was never implemented by browsers or assistive technologies. Screen readers continued to treat all <h1>s as top-level headings, ignoring section nesting. This led to confusion, accessibility issues, and ultimately, the algorithm’s quiet deprecation in HTML5.1. Experts now advise against relying on it. Developers should use traditional heading levels (<h1> to <h6>) to maintain accessibility and semantic clarity.

Now, the advised method for creating a document outline is to still make use of nested <section> elements, but in combination with the appropriate heading rank for each section.Ire Aderinokun

For a deeper dive into this topic, check out Adrian Roselli’s article: “There Is No Document Outline Algorithm” (external link).

Implementing the <section> element in my Gutenberg workflow

When I first set out to use the <section> element in WordPress via the Gutenberg editor, I wasn’t sure how to do it. I knew how to create a <section> block:

  1. Select the blocks you want to wrap together.
  2. Click the Group icon in the contextual toolbar.
  3. By default, this creates a <div>, but you can change the HTML tag.
  4. In the Block Inspector sidebar, under Advanced, there’s a dropdown labeled HTML Element.
  5. From there, you can choose <section>.

But I wasn’t sure where to start: should I create my content as usual and then group it as described above, or build the <section> elements first and populate them afterward?

One thing to beware of: WordPress automatically inserts an extra <div> between the <section> and its heading. This can clutter the markup slightly, especially if you’re aiming for clean, semantic structure. Can you avoid it? Not directly through the editor; it’s baked into how Gutenberg renders Group blocks 7. So I didn’t bother.

<div class="wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained">

Since I already draft my posts in Word, with a clear outline in place, I don’t need to pre-build empty sections in Gutenberg. For me, it’s much more efficient to paste the content first (as I’ve always done) and then group related blocks—applying structure retroactively. Once a section is complete, I group all its blocks and then move on to adding the content for the next section. Tip: I do this in the List View panel (on the left); it’s far easier than grouping blocks one by one. For sub-sections, I simply create a Group block inside an existing Group block, following the same outline I would have used otherwise.

The only change is that I now assign the id to the <section> tag (the “recommended” way) rather than to the heading (the “acceptable” way). Since I couldn’t figure out how to view the HTML of a Group block directly, I now use the HTML Anchor field in the Block > Advanced tab to set the id. Of course, I also make sure to apply the .screen-reader-text class to my H2 introduction. I apply this class after grouping the introduction blocks, since the moment it’s added, the block becomes visually hidden. That’s it.

Grouping blocks in Gutenberg is intuitive and fast—especially when the content is already written. It’s a semantic pass that comes after the creative one. This ensures my document retains its semantic structure and accessibility benefits without adding friction to the editing process.

Looking back, what started as a small question—How to add an anchor to a heading the proper way—turned into a deeper reflection on structure, accessibility, and the philosophy behind good HTML. It’s easy to dismiss semantic markup as pedantic or overly technical, especially when visual results seem unaffected. But the truth is, structure matters. It matters for screen readers, for search engines, for maintainability—and yes, even for aesthetics, once you understand how the invisible scaffolding supports the visible design. So when people say it’s not worth the effort, I can’t help but think they’re missing the point.

Some people will tell you not to bother with sectioning. They say that it’s hard work or that it doesn’t make sense. This is hokum. Sure, if you’re lazy, don’t bother with sectioning, but don’t pretend you’re doing it on principle. Using sections demonstrably enhances HTML structure without breaking accessibility.Heydon Pickering

1 These multi-part posts often emerge organically. I begin drafting out of necessity before I’ve fully solved the problem—time constraints, you know… I used to have a buffer of at least four posts and the luxury to fully adhere to CogitActive principles. But since that fateful summer of 2020 (yes, five years already), each week has been a struggle to keep up. It’s part of why these explorations sometimes stretch across multiple entries. You’re reading along as I investigate, experiment, and often realize—mid-draft—that the issue is more complex than expected. Weekly publishing keeps me moving, but it also means you’re witnessing the process unfold almost live. ^
2 Sources include the HTML Standard by WHATWG, MDN Web Docs, and the HTML5 Working Draft by W3C. For info, the W3C ceded authority over the HTML standards to WHATWG on 28 May 2019, as it considered that having two standards is harmful (according to Wikipedia). The HTML Living Standard is now authoritative. However, W3C will still participate in the development process of HTML. As for MDN, it’s one of the most trusted and comprehensive resources for web developers. Maintained by Mozilla, it is widely respected for its clarity, accessibility, and practical examples. ^
3 Some screen reader users do access headings to understand a page’s content, but here is the sad truth: Originally, headings were supposed to outline a document, just as MS Word or Google Docs can produce an outline based on headings, but browsers never implemented this structure. One advantage of the aforementioned “recommended” approach (to add an anchor to a heading) compared to the “acceptable” way is that each time you nest a <section>, the outline depth increases by one level. This means that the headings end up at the right depth automatically. ^
4 All but two! I found a HubSpot post—“How to Use the Section Element in HTML” by Anna Fitzgerald—showing both a “Homepage Example” and an “Article Example with Nested Sections.” Unfortunately, it just presents the examples without any explanation. And by the way, they’ve since removed the post; I had to dig it up via the Wayback Machine! As for the second, I distinctly remember a long-form article about restructuring an entire blog using the <section> element. It strongly advocated for its use, but despite my best efforts, I haven’t been able to locate it again. I’ve uncovered more articles since then—but let’s not spoil the plot just yet. ^
5 Specifically, the <section> element has an implicit ARIA role of region only if it has an accessible name provided via aria-label, aria-labelledby, or the title attribute. If no accessible name is present through these attributes, the role defaults to generic, which offers no landmark functionality. ^
6 This question pops up often in developer forums—sometimes out of genuine curiosity, sometimes out of SEO anxiety. The first reaction is usually a firm “No!” followed by warnings about Google penalties for hidden text. Stack Overflow (external link) and Webmasters Stack Exchange (external link) have threads full of cautionary tales. But here’s the twist: those warnings are aimed at shady tactics like hiding keyword-stuffed content. What I’m doing here—hiding a heading for accessibility and semantic clarity—is a different story. Even Google’s own guidelines allow for it when done responsibly. So yes, the concern is real, but in this case, it’s misplaced. ^
7 When you use a Group block in WordPress, even if it’s just a simple div, the output typically includes two nested <div> elements. The outer wrap is the main container for the Group block. If you convert this to a <section>, you’re replacing the outermost wrapper. The inner <div> wraps the actual content inside the Group block. It’s used for layout and spacing purposes, especially when themes apply padding, margins, or flex/grid styles. WordPress adds this automatically to maintain consistent rendering across blocks. Even though you’ve changed the outer <div> to a <section>, the inner container remains a <div>. ^