Refactoring a Page to Semantic HTML
The best way to cement what you have learned is to take a real page, see what is wrong with it, and fix it deliberately. This lesson walks through a complete refactor.
The starting point
Section titled “The starting point”Here is a working but poorly structured HTML page. It renders correctly in a browser, but the structure communicates nothing:
<!doctype html><html lang="en"> <head> <meta charset="utf-8"> <title>Trail Blog</title> </head> <body> <div id="top"> <div id="site-name">Trail Blog</div> <div id="links"> <a href="/">Home</a> <a href="/about.html">About</a> </div> </div>
<div id="content"> <div class="post"> <div class="post-head">Choosing Your First Trail</div> <div class="post-date">May 2025</div> <div class="post-body"> <div>For a first outing, stay under 5 miles.</div> <div class="tip">Tip: Check trail reports before you go.</div> <div>Look for easy-rated trails on local hiking sites.</div> </div> </div> </div>
<div id="bottom"> <div>© 2025 Trail Blog</div> <div><a href="mailto:hello@trailblog.com">Contact</a></div> </div> </body></html>What is wrong
Section titled “What is wrong”| Issue | Description |
|---|---|
<div id="top"> | Should be <header> |
<div id="site-name"> | Should be <h1> |
<div id="links"> | Should be <nav> |
<div id="content"> | Should be <main> |
<div class="post"> | Should be <article> |
<div class="post-head"> | Should be <h2> |
<div class="post-date"> | Should be <p> |
<div class="post-body"> | Unnecessary wrapper — remove it |
Content <div>s inside post-body | Should be <p> elements |
<div class="tip"> | Should be <aside> |
<div id="bottom"> | Should be <footer> |
Footer content <div>s | Should be <p> elements |
The refactored version
Section titled “The refactored version”<!doctype html><html lang="en"> <head> <meta charset="utf-8"> <title>Trail Blog</title> </head> <body> <header> <h1>Trail Blog</h1> <nav> <a href="/">Home</a> <a href="/about.html">About</a> </nav> </header>
<main> <article> <h2>Choosing Your First Trail</h2> <p>May 2025</p> <p>For a first outing, stay under 5 miles.</p> <aside> <p><strong>Tip:</strong> Check trail reports before you go.</p> </aside> <p>Look for easy-rated trails on local hiking sites.</p> </article> </main>
<footer> <p>© 2025 Trail Blog</p> <p><a href="mailto:hello@trailblog.com">Contact</a></p> </footer> </body></html>What changed and why
Section titled “What changed and why”<div id="top">→<header>— The top of every page is not just visually the top; it is the introductory landmark.<div id="site-name">→<h1>— Site names are headings. One<h1>per page.<div id="links">→<nav>— This is major site navigation.<div id="content">→<main>— Primary content deserves the<main>landmark.<div class="post">→<article>— A blog post is self-contained and independently meaningful.<div class="post-head">→<h2>— Article titles are headings. Using a<div>styled to look like a heading is meaningless to screen readers and search engines.<div class="tip">→<aside>— The tip is related but secondary — exactly what<aside>is for.<div id="bottom">→<footer>— The bottom of the page is the footer landmark.- All remaining content
<div>s →<p>— Text content belongs in paragraphs, not anonymous boxes.
Exercise
Section titled “Exercise”Open index.html in VS Code.
By now your file should already have <header>, <main>, <footer>, <section>, <aside>, and <nav> in place from the previous lessons. Do a final review pass:
- Check every
<div>in the file. If you have any left, ask yourself: does a semantic element fit here? If yes, replace it. - Check heading hierarchy. Your
<h1>should be inside<header>. Your<h2>headings should be inside<main>. No levels should be skipped. - Check your
<section>elements. Each one should have its own<h2>(or deeper heading). - Check
<aside>. Is it inside a<section>and related to that section’s content? - Check
<nav>. Is it inside<header>and linking to real pages?
When you are done, index.html should have a structure something like this:
<body> <header> <h1>Your Topic</h1> <nav> <a href="index.html">Home</a> <a href="about.html">About</a> </nav> </header>
<main> <section> <h2>First Subtopic</h2> <p>...</p> <aside><p><strong>Tip:</strong> ...</p></aside> </section>
<section> <h2>Second Subtopic</h2> <p>...</p> <img src="images/photo.jpg" alt="..."> </section> </main>
<footer> <p>Built while learning HTML.</p> <p><a href="mailto:you@example.com">Contact</a></p> </footer></body>Save, open in your browser, and confirm everything still renders correctly. It should look identical to before — structure is invisible until CSS gets involved.
Module 03 Recap
Section titled “Module 03 Recap”- Semantic HTML communicates meaning, not just appearance.
<div>is a generic container — use it only when no semantic element fits.- Page-level structure:
<header>→<main>→<footer>. - Content organization inside
<main>:<section>(related group),<article>(standalone content),<aside>(supplementary). <nav>marks major navigation blocks as a landmark.- Proper heading hierarchy (
<h1>→<h2>→<h3>) must be maintained within this structure.