Skip to main content

Step-by-step tutorial

HTML Tutorial: Build a Complete Semantic Web Page

Build a small developer profile while learning how each part of an HTML document contributes structure, meaning, accessibility, and discoverability.

HTMLbeginner4 min readWeb foundations

Learning overview

Estimated time
4 minutes
Difficulty
Beginner
Prerequisites
No prior experience required
Learning outcome
Explain html using a clear mental model · Apply html in practical HTML work
Last updated
July 18, 2026

What you will build and learn

The finished page has a descriptive head, a skip link, site navigation, one main topic, a project article, and a labeled contact form. Build it in stages and open the file after every stage so mistakes remain local.

  • A valid HTML document
  • Landmarks and heading hierarchy
  • Accessible links, images, and forms
  • A repeatable validation checklist

Step 1: Create the document foundation

The doctype selects standards mode. The lang attribute identifies the document language. UTF-8 supports modern text, while the viewport declaration lets mobile browsers use the device width. The title names the page in tabs and search results.

index.html
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Alex Morgan — Frontend Developer</title>
  <meta name="description" content="Projects and contact details for frontend developer Alex Morgan.">
</head>
<body>
</body>
</html>

Step 2: Add landmarks and navigation

A skip link lets keyboard users bypass repeated navigation. Header introduces the page, nav contains the primary links, main wraps the unique content, and footer contains closing site information.

page-landmarks.html
<body>
  <a href="#main-content">Skip to main content</a>
  <header>
    <a href="/">Alex Morgan</a>
    <nav aria-label="Primary">
      <ul>
        <li><a href="#about">About</a></li>
        <li><a href="#projects">Projects</a></li>
        <li><a href="#contact">Contact</a></li>
      </ul>
    </nav>
  </header>
  <main id="main-content"></main>
  <footer><p>© 2026 Alex Morgan</p></footer>
</body>

Step 3: Create a clear content hierarchy

Use one h1 for the profile’s main topic. Each major section receives an h2. A project is an article because it can stand on its own, and its title becomes an h3 beneath the Projects section.

profile-content.html
<main id="main-content">
  <h1>Alex Morgan, Frontend Developer</h1>
  <section id="about" aria-labelledby="about-title">
    <h2 id="about-title">About me</h2>
    <p>I build fast, accessible interfaces for the web.</p>
  </section>
  <section id="projects" aria-labelledby="projects-title">
    <h2 id="projects-title">Selected projects</h2>
    <article>
      <h3>Transit status dashboard</h3>
      <p>A keyboard-friendly dashboard for live service updates.</p>
      <a href="/projects/transit-dashboard">Read the case study</a>
    </article>
  </section>
</main>

Step 4: Add useful media

Alternative text should communicate the image’s purpose in this context. Width and height reserve layout space before the image loads. A figure is appropriate when the image and caption form one referenced unit.

project-figure.html
<figure>
  <img
    src="/images/transit-dashboard.webp"
    alt="Transit dashboard showing three delayed rail lines"
    width="960"
    height="540"
    loading="lazy">
  <figcaption>Delay status grouped by rail line.</figcaption>
</figure>

Step 5: Build the contact form

Visible labels remain available after users begin typing. The email input provides appropriate keyboard and validation behavior. The button’s default type inside a form is submit, but stating it explicitly makes intent clear.

contact-form.html
<section id="contact" aria-labelledby="contact-title">
  <h2 id="contact-title">Contact</h2>
  <form action="/contact" method="post">
    <p>
      <label for="name">Name</label>
      <input id="name" name="name" autocomplete="name" required>
    </p>
    <p>
      <label for="email">Email</label>
      <input id="email" name="email" type="email" autocomplete="email" required>
    </p>
    <p>
      <label for="message">Message</label>
      <textarea id="message" name="message" rows="6" required></textarea>
    </p>
    <button type="submit">Send message</button>
  </form>
</section>

Step 6: Validate the finished page

Run an HTML validator, inspect the accessibility tree, navigate with Tab and Shift+Tab, zoom to 200 percent, and review the page without CSS. These checks reveal nesting errors, missing names, illogical order, and structure that depended on visual styling.

  • No duplicate IDs
  • Every form control has an accessible name
  • Heading levels describe the content hierarchy
  • Every link makes sense out of context
  • Images have purposeful alt text and dimensions
  • The page remains understandable without CSS

Frequently asked questions

Can I complete this HTML tutorial without CSS?

Yes. The goal is a meaningful, usable document before styling. Adding CSS later should not require changing the content hierarchy.

Why use semantic elements instead of div elements?

Semantic elements communicate roles to browsers, assistive technologies, search engines, and developers. Use div only when no more meaningful element fits.

How do I know whether my HTML is correct?

Combine automated validation with keyboard testing, accessibility-tree inspection, and a manual review of headings, labels, links, and alternative text.

Topic graph

A taxonomy-generated path through this subject.

  1. HTML
  2. Web foundations
  3. html
  4. tutorial
  5. semantic-html
  6. accessibility
  7. What Is HTML in Programming?
  8. Learn HTML: From First Page to Semantic Websites
  9. CSS Tutorial: Build a Responsive Profile Card

Recommended automatically from shared technologies, topics, intent, and difficulty.

Hand-picked companion pages that deepen this topic.

Your next steps

Continue learning

  1. 1glossaryWhat Is HTML in Programming?
  2. 2guidesLearn HTML: From First Page to Semantic Websites
  3. 3guidesCSS Tutorial: Build a Responsive Profile Card
  4. 4guidesC++ (Cpp) Tutorial: Build a Student Grade Calculator