Text Elements & Semantic Structure
Headings, paragraphs, and the semantic tags — header, nav, main, section, article, aside, footer — that give a page real meaning.
h1 Through h6 — A Hierarchy, Not a Font-Size Picker
HTML gives you six heading levels, <h1> through <h6>, ranked from most to least important. Browsers apply default styling that makes <h1> the largest and boldest and <h6> the smallest — but treating headings as a font-size shortcut is exactly the mistake this section exists to correct. Their real job is expressing the logical outline of a document, the way chapter titles and subheadings work in a book's table of contents.
<h1>Trailhead Boots</h1>
<h2>Waterproof Hiking Collection</h2>
<h3>Men's Styles</h3>
<h3>Women's Styles</h3>
<h2>Trail Running Collection</h2>
<h3>Lightweight Models</h3>
<h3>All-Terrain Models</h3>Read purely as structure, with all styling stripped away, this tells you exactly how the page is organized: one top-level topic, two major sections beneath it, and two subsections under each. A screen-reader user can navigate a page exactly this way — jumping heading to heading, skipping straight to "Women's Styles" without reading everything in between — which is precisely why this hierarchy is not a cosmetic detail.
Never skip a level
The hierarchy should descend one level at a time. Jumping from <h2> straight to <h4> because the smaller heading's default font size "looked right" is a genuinely common mistake, and it breaks the logical outline even though the page still renders without any visible problem.
<h2>Trail Running Collection</h2>
<h4>Lightweight Models</h4> <!-- should be h3 --><h3> renders bigger than you want, that is a CSS problem — override itsfont-size in your stylesheet (covered in the CSS Foundations phase). Do not solve a visual problem by breaking the document's logical structure; the two are entirely separate concerns, and conflating them is exactly the div-soup-adjacent mistake this whole module is steering you away from.One h1 per page — the convention, and its real nuance
The long-standing convention is exactly one <h1> per page, representing that page's single main topic — the same way a book chapter has one title, not several competing for the top spot. Since HTML5, the specification technically permits multiple <h1> elements when each is scoped inside its own <article> or <section> (each effectively starting a fresh sub-outline) — but in practice, essentially every accessibility guideline, SEO best-practice document, and real production codebase you will encounter still treats a single page-level <h1> as the expected, unambiguous norm. Deviating from it is a decision worth being deliberate about, not a default.
<p> vs <div> — Text Content vs a Generic Container
<p> marks up a paragraph — a block of actual, readable prose. <div> is a generic, meaning-free container that exists purely to group other elements for styling or scripting purposes. Confusing the two — most often, wrapping running text in a <div> instead of a <p> — is one of the most common structural mistakes in beginner HTML.
<div class="product-card">
<h3>Trail Runner GTX</h3>
<p>A lightweight trail shoe with a Gore-Tex membrane for wet-weather
traction on technical terrain.</p>
<p>Available in three colorways, starting at $139.</p>
</div>
<!-- div groups the whole card for styling — it carries no meaning of
its own. Each block of actual prose is a <p>, not another <div>. -->The practical difference is not just philosophical. Screen readers announce <p> elements as paragraphs and let users jump between them; browsers apply sensible default spacing (margin) around paragraphs that a plain <div> does not get; and search engines weight text inside meaningful content tags differently than text inside a generic container with no semantic role at all.
<p>. If you are grouping other elements together purely to apply a shared style or layout to them as a unit, <div> is the correct, honest choice — using it does not mean you did something wrong, it means you correctly identified that the group itself carries no specific meaning beyond "these belong together visually.""Div Soup" — What It Actually Looks Like, and Why It's a Problem
"Div soup" is the industry nickname for a page built almost entirely out of generic <div> elements, with classes doing all the work of describing what everything is — class="header", class="nav", class="main-content" — instead of using the HTML elements that already exist specifically to express those roles.
<div class="header">
<div class="logo">Trailhead Boots</div>
<div class="nav">
<div class="nav-item">Shop</div>
<div class="nav-item">About</div>
</div>
</div>
<div class="main-content">
<div class="article">
<div class="article-title">New Arrivals</div>
<div class="article-body">...</div>
</div>
</div>
<div class="footer">© 2026 Trailhead Boots</div>Styled with the right CSS, this can look absolutely identical to a well-structured page — the problem is entirely invisible to a sighted user clicking through it casually. It becomes very visible to anyone, or anything, not relying on vision or CSS to understand the page: a screen reader has no landmarks to announce or jump between, a search engine has no signal for which block is the real navigation versus the real content, and a browser's reader mode has nothing reliable to extract. Part 05 covers the specific elements that fix this exact pattern.
The Document Outline — What a Machine Understands About Your Page's Shape
The document outline is the logical, tree-shaped summary of a page's content that headings and semantic elements together produce — conceptually similar to a table of contents generated automatically from the structure itself, without anyone writing it by hand. It is what a screen reader's "jump to heading" navigation is built from, what browser reading-mode extraction relies on, and what search engines use to understand which part of a page is the actual article versus surrounding chrome like navigation and footer content.
<header>...</header>
<nav>...</nav>
<main>
<h1>Trail Running Shoes</h1>
<section>
<h2>Men's Collection</h2>
<article>
<h3>Trail Runner GTX</h3>
</article>
</section>
<section>
<h2>Women's Collection</h2>
</section>
</main>
<footer>...</footer>
/* Implied outline:
Trail Running Shoes
└── Men's Collection
└── Trail Runner GTX
└── Women's Collection */This is precisely why heading levels and semantic elements matter together rather than separately — a correct heading hierarchy inside a page built entirely from unlabeled <div>s still leaves assistive tools unable to tell where the actual main content starts, and correct semantic landmarks with a broken or skipped heading order still leave the internal structure of the content unclear. Both are needed for the outline to actually mean something.
header, nav, main, footer — The Elements That Fix Div Soup
HTML5 introduced a set of elements specifically to replace the class="header"-style pattern with real, machine-recognizable structure. These are called landmark elements, because assistive technology treats them as navigable landmarks a user can jump directly to.
<body>
<header>
<h1>Trailhead Boots</h1>
<nav>
<ul>
<li><a href="/shop">Shop</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
</header>
<main>
<!-- the ONE primary content area of the page -->
<h2>New Arrivals</h2>
...
</main>
<footer>
<p>© 2026 Trailhead Boots</p>
</footer>
</body>A few rules worth being precise about: <main> should appear exactly once per page, wrapping the primary content unique to that specific page — not the navigation, not the footer, not anything repeated across every page of the site. <header> and <footer> can each appear more than once, since they can also be scoped to an individual <article> or <section> (a blog post's own byline-and-date header, for example), not only at the page level. <nav> should wrap a genuine navigation block — a primary menu, a breadcrumb trail, a pagination control — not every single group of links on the page; a handful of related links inside an article's body does not need to be wrapped in <nav>.
section vs article vs aside — And When a Plain div Is Still Correct
These three elements are the ones beginners mix up most often, because they can look nearly interchangeable in a quick glance at rendered output. Each has a specific, distinct meaning.
<article> → Content that would make complete sense on its own, removed
from the page entirely — a blog post, a news story, a single
product listing, a forum comment. Ask: "could this be
syndicated/republished elsewhere and still make full sense?"
<section> → A thematic grouping of content, WITH ITS OWN HEADING, that is
part of a larger whole — a chapter-like grouping. Ask: "does
this have its own heading, and is it one distinct part of a
bigger document?"
<aside> → Content related to, but not essential to, the main content
around it — a sidebar, a pull quote, a "related articles"
box. Ask: "could a reader skip this entirely without losing
the main point?"<main>
<article>
<h2>Why Waterproofing Ratings Matter</h2>
<p>A 20,000mm rating means...</p>
<section>
<h3>How Ratings Are Measured</h3>
<p>...</p>
</section>
<section>
<h3>Comparing Common Ratings</h3>
<p>...</p>
</section>
</article>
<aside>
<h3>Related Reading</h3>
<ul>
<li><a href="/blog/gore-tex-explained">Gore-Tex, Explained</a></li>
</ul>
</aside>
</main>The section rule people miss most: it needs its own heading
A very common mistake is reaching for <section> purely as "a bigger div," without giving it a heading of its own. If a grouping of content has no heading identifying it as its own distinct thematic unit, it is not a <section> — it is very likely just a <div>, and that is the correct, honest choice in that situation.
<section class="card-grid">
<div class="card">...</div>
<div class="card">...</div>
</section>
<!-- No heading identifies this as its own thematic unit — plain div
is the honest choice here, not section. --><div> is for. Reaching for <section> everywhere "to be more semantic" without a heading inside each one is its own kind of mistake — it adds structure the document outline does not actually have.An Accessibility Audit Fails a Chicago News Site's Homepage
A Chicago-based local news site commissions a third-party accessibility audit ahead of a legal compliance deadline. The homepage looks completely normal — a masthead, a navigation bar, a grid of story cards, a footer — and passes every visual review the internal team ran. The audit comes back with a failing score anyway, flagged specifically for "no identifiable landmark regions" and "heading structure does not reflect page content."
What the audit tool actually found
The page was built entirely from <div> elements with CSS classes doing all the labeling — class="header", class="nav", class="story-headline" — with the actual headline text inside <div> tags styled to look exactly like headings, rather than real <h2> or <h3> elements. Sighted users scanning the page visually never noticed a problem, since the CSS made everything look correct. A screen reader, which relies entirely on real elements rather than class names, announced the entire homepage as one undifferentiated block of unlabeled text with zero navigable landmarks or headings.
<div class="header">
<div class="masthead">Chicago Daily</div>
<div class="nav">
<div class="nav-link">Local</div>
<div class="nav-link">Politics</div>
</div>
</div>
<div class="story-card">
<div class="story-headline">City Council Approves Budget</div>
<div class="story-summary">...</div>
</div><header>
<h1>Chicago Daily</h1>
<nav>
<ul>
<li><a href="/local">Local</a></li>
<li><a href="/politics">Politics</a></li>
</ul>
</nav>
</header>
<main>
<article class="story-card">
<h2>City Council Approves Budget</h2>
<p class="story-summary">...</p>
</article>
</main>The visual design did not change at all — the CSS classes stayed exactly the same, still controlling every pixel of appearance. Only the underlying elements changed, from generic <div>s to the correct semantic and heading elements each block actually represented. The remediation passed re-audit, and — a detail the team had not anticipated — organic search rankings for individual story pages measurably improved in the following weeks, since search engines now had real heading and article structure to index instead of an undifferentiated wall of divs.
Five Misconceptions About Semantic Structure
6 Interview Questions — With Complete Answers
Semantic Structure Mistakes Beginners Make Constantly
Errors and Audit Warnings You Will Hit — And Exactly Why
🎯 Key Takeaways
- ✓Heading levels (h1-h6) express the logical outline of a page, not a font-size shortcut — never pick a level for its default size; style it with CSS instead.
- ✓Never skip a heading level. Convention is exactly one h1 per page, representing the page's single main topic.
- ✓Use <p> for actual readable prose, <div> for a generic, meaning-free grouping used purely for styling or layout.
- ✓"Div soup" — a page built entirely from generic divs with CSS classes standing in for real structure — can look pixel-identical to well-structured HTML while being invisible or broken to screen readers, search engines, and reading-mode tools.
- ✓The landmark elements (header, nav, main, footer) replace class-labeled divs with real, machine-recognizable structure. main appears exactly once per page; header and footer can be scoped to individual articles/sections too.
- ✓article is content that makes full sense standalone; section is a thematic grouping WITH its own heading, forming part of a larger whole; aside is related-but-skippable content. A grouping with no heading of its own is correctly a plain div, not a section.
- ✓The document outline — built from headings and landmarks together — is what screen readers, reading-mode extraction, and search engines actually use to understand a page's shape.
What comes next
Module 04 covers the anchor tag in full — every href value type, the security implications of target="_blank", linking to a specific point within a page, and building a real, semantic navigation menu.
Module 04 → Links and NavigationDiscussion
0Have a better approach? Found something outdated? Share it — your knowledge helps everyone learning here.