Building a Complete Static Page
A full project pulling structure, semantics, media, and forms together into one real, complete HTML page — start to finish.
Quick answer
Building a full page means planning its sections first, then writing semantic markup for each: a header with navigation, a main area with one <h1> and sections under <h2>s, media with alt text, a form with labels, and a footer, plus complete <head> metadata.
- Sketch the sections before writing any tags.
- One <h1>; each section gets its own <h2>.
- Every technique comes from an earlier lesson in this track.
<body>
<header>
<a href="/">FreshCart</a>
<nav aria-label="Main"><a href="#menu">Menu</a> <a href="#contact">Contact</a></nav>
</header>
<main>
<h1>Fresh groceries in 2 hours</h1>
<section id="menu"><h2>This week</h2>…</section>
<section id="contact"><h2>Contact us</h2><form>…</form></section>
</main>
<footer><p>© 2026 FreshCart</p></footer>
</body>Everything From Lessons 1–15, in One Real Page
This lesson is different from the previous 15 — instead of introducing a new topic, it builds one complete, real page from start to finish: a small local business landing page (a fictional coffee roastery), combining document structure, semantic sectioning, images, navigation, a contact form, and metadata into a single genuine build. Every technique used here was already covered in an earlier lesson — this is deliberately a synthesis, not new material, and each section below names exactly which earlier lesson it draws from.
What We're Building, and Why Structure Comes First
Before writing a single tag, sketch the page's actual sections: a header with navigation, a hero introduction, an "About" section, a "Menu" section with a list of offerings, a contact section with a real form, and a footer. This maps directly onto the semantic landmark elements from Lesson 3 — deciding the sections BEFORE writing markup is what keeps the result genuinely semantic instead of div-soup with classes bolted on afterward.
header (site branding + nav)
main
section (hero — page title + one-line pitch)
section (about the roastery)
section (the menu — a real content list)
section (contact — a real working form)
footer (copyright + secondary links)Starting From Lesson 2's Foundation
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fernwood Coffee Roastery — Small-Batch, Portland OR</title>
<meta name="description" content="Small-batch, ethically-sourced coffee roasted weekly in Portland, Oregon. Visit our roastery or order online.">
<link rel="icon" href="/favicon.ico">
</head>
<body>
<!-- page content goes here -->
</body>
</html>Every piece here traces back to an earlier lesson: the DOCTYPE and lang attribute (Lesson 2), the charset and viewport meta tags (Lessons 2 and 13), and the title/description tags that determine how this page appears in search results and browser tabs (Lesson 13).
Building From Lessons 3 and 4
<header>
<a href="/" class="logo">Fernwood Coffee Roastery</a>
<nav aria-label="Main navigation">
<ul>
<li><a href="#about">About</a></li>
<li><a href="#menu">Menu</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
</header>The <nav> landmark and the <ul> list structure inside it are exactly the pattern from Lesson 3 (semantic structure) and Lesson 4 (links & navigation) — the in-page #about/#menu/#contact links use the anchor links technique from Lesson 4, targeting the id attributes each section below will carry.
Text Hierarchy From Lesson 3, Images From Lesson 5
<main>
<section aria-labelledby="hero-heading">
<h1 id="hero-heading">Small-Batch Coffee, Roasted Weekly</h1>
<p>Ethically sourced, roasted in small batches every Tuesday in Portland, Oregon.</p>
</section>
<section id="about" aria-labelledby="about-heading">
<h2 id="about-heading">About Fernwood</h2>
<figure>
<img src="/roastery-interior.jpg"
alt="The Fernwood roastery's interior, with a large drum roaster and bags of green coffee beans"
width="800" height="500" loading="lazy">
<figcaption>Our roastery on SE Belmont Street, open for tours every Saturday.</figcaption>
</figure>
<p>Founded in 2019, Fernwood roasts small batches of ethically sourced beans every week...</p>
</section>The image follows the complete pattern from Lesson 5: real, descriptive alt text (not decorative — this image genuinely conveys information), explicit width/height to prevent layout shift, wrapped in figure/figcaption for a captioned image, and loading="lazy" since this image sits below the initial viewport.
A Real Content List, From Lesson 6
<section id="menu" aria-labelledby="menu-heading">
<h2 id="menu-heading">This Week's Roast</h2>
<ul>
<li>
<h3>Ethiopia Yirgacheffe</h3>
<p>Bright, floral, notes of bergamot and stone fruit. Light roast.</p>
</li>
<li>
<h3>Colombia Huila</h3>
<p>Balanced, caramel sweetness, a clean finish. Medium roast.</p>
</li>
<li>
<h3>Sumatra Mandheling</h3>
<p>Full-bodied, earthy, low acidity. Dark roast.</p>
</li>
</ul>
</section><ul> is the correct choice here (rather than <ol>) because this week's roast list has no meaningful order — Lesson 6's core distinction between the two list types applied directly to a real decision.
A Genuinely Accessible Form, From Lessons 8, 9 and 10
<section id="contact" aria-labelledby="contact-heading">
<h2 id="contact-heading">Get in Touch</h2>
<form action="/submit-contact" method="POST">
<div>
<label for="contact-name">Name</label>
<input type="text" id="contact-name" name="name" required>
</div>
<div>
<label for="contact-email">Email</label>
<input type="email" id="contact-email" name="email" required>
</div>
<fieldset>
<legend>What are you reaching out about?</legend>
<label><input type="radio" name="reason" value="wholesale"> Wholesale orders</label>
<label><input type="radio" name="reason" value="visit"> Visiting the roastery</label>
<label><input type="radio" name="reason" value="other" checked> Something else</label>
</fieldset>
<div>
<label for="contact-message">Message</label>
<textarea id="contact-message" name="message" rows="5" required></textarea>
</div>
<button type="submit">Send Message</button>
</form>
</section>Every field is correctly labeled (Lesson 8), the reason-for-contact question uses a real fieldset/legend-grouped radio set (Lesson 9), and every input that matters for the business to receive has a name attribute — the single most common real mistake flagged in Lesson 8's own Real World example, deliberately avoided here.
Closing Out the Page
<footer>
<p>© 2026 Fernwood Coffee Roastery. All rights reserved.</p>
<nav aria-label="Footer navigation">
<ul>
<li><a href="/privacy">Privacy Policy</a></li>
<li><a href="/terms">Terms of Service</a></li>
</ul>
</nav>
</footer>
</main>The © entity here is a direct callback to Lesson 14 — a literal © character can be typed directly in most editors today, but the entity form remains common in real production code and is always guaranteed to render correctly regardless of the file's declared encoding.
Checking the Finished Page Against Lesson 15
With the full page assembled, running it through the W3C Markup Validator (Lesson 15) is the final step before considering it done — checking for unclosed tags, duplicate IDs (a real risk here, since both the header and footer navigation reuse similar list structures), and any invalid nesting introduced while assembling the sections.
hero-heading, about-heading, menu-heading, contact-heading, contact-name, contact-email, contact-message — a quick scan (or the validator) confirms none collide, which matters because a duplicate ID breaks label for associations silently, exactly as covered in Lesson 8.A Real Freelance Client Site Built From Exactly This Pattern
A freelance developer is hired to build a landing page for a local bakery — genuinely the same shape of project as this lesson's build. The client later asks why their site ranks reasonably well in local Google searches despite having no marketing budget at all.
What actually drove that result
The exact fundamentals from this lesson — a single clear h1, a real semantic document structure search engines can parse confidently, a proper meta description, and real descriptive alt text on every image — are themselves meaningful, genuine SEO signals, with zero paid marketing involved. The developer's own explanation to the client: "there's no trick here — this is just what a well-structured page looks like to a search engine, and most sites built quickly without attention to this structure never get it for free."
Four Misconceptions About Assembling a Real Page
4 Interview Questions — With Complete Answers
Mistakes Beginners Make Assembling a Real Page
Issues You Will Hit Assembling a Real Page — And Exactly Why
🎯 Key Takeaways
- ✓A real page starts with planning its sections BEFORE writing markup — that planning is what keeps the result genuinely semantic instead of div-soup with classes added afterward.
- ✓Every technique in this build traces back to an earlier lesson: document structure (Lesson 2), semantic sectioning (Lesson 3), navigation (Lesson 4), images (Lesson 5), lists (Lesson 6), forms (Lessons 8-9), entities (Lesson 14), and metadata (Lesson 13).
- ✓Exactly one h1 per page, with h2/h3 used consistently for every section's own heading, keeps the document outline sensible from top to bottom.
- ✓Every form field needs both a real associated label AND a name attribute — the single most common real-world mistake this build deliberately avoids.
- ✓Validating the finished page (Lesson 15) — especially checking for duplicate IDs — is the correct final step before considering a real build done.
- ✓Strong semantic HTML fundamentals are themselves a genuine, free SEO signal — not a separate technique layered on top afterward.
What comes next
Phase 3 begins here — CSS Foundations, starting with how CSS actually applies styles: syntax, selectors, and the cascade.
Lesson 17 → What is CSS? Syntax, Selectors & the CascadeQuick check
How many <h1> elements should the page have?
HELP US IMPROVE
How was this lesson?
Your note is shared with the Chaduvuko team for review. Please don’t include personal or sensitive information.
Spotted a mistake or something unclear? Suggest a fix on GitHub or email us. Select the text first and it is quoted for you.
Discussion
0Have a better approach? Found something outdated? Share it — your knowledge helps everyone learning here.
