Create your own
Lesson illustration

Building a Web Page with Semantic HTML

Hello—your small-business-starter project now has an index.html file in the right place, ready to become a real page. So far, you have organized where the pieces of a website live. This lesson focuses on the next architectural habit: expressing what each part of a page is for.

You will build a one-page starter site using semantic HTML: meaningful elements for the site header, navigation, main content, supporting information, and footer. The page will be simple and unstyled on purpose. In the next lesson, CSS will control its visual appearance; today, the browser, search tools, and assistive technology should already be able to understand its structure.


Meaning first, appearance later

HTML is not primarily a drawing tool. It is a way to describe a document’s content and structure.

Consider two ways to identify a group of links:

<div class="top-links">
  <a href="#start">Get started</a>
  <a href="#resources">Resources</a>
</div>
<nav>
  <a href="#start">Get started</a>
  <a href="#resources">Resources</a>
</nav>

Both can be styled to look identical later. But the second version communicates something useful immediately: this is navigation. A screen-reader user can move directly to the navigation area rather than listening through every item on the page. The same meaningful structure also helps you, months later, read a file and recognize the responsibility of each area.

This is semantic HTML: choosing an element because its built-in meaning matches the content.

The diagram below shows a familiar page layout. Treat it as a map of responsibilities, not a fixed visual design. A footer does not have to look purple or sit in a particular pixel position to be a footer.

A typical web page divided into a header, navigation area, primary content, contextual aside, and footer. Semantic HTML identifies these responsibilities even before CSS creates a visual layout.

The core elements in this lesson are:

ElementMeaning and typical use
<header>Introductory content for the whole site or for a specific section: a site name, logo, tagline, or related navigation.
<nav>A major group of navigation links.
<main>The page’s unique, primary content. Use one per page.
<section>A themed grouping of content, normally introduced by a heading.
<article>A self-contained item that could make sense on its own, such as a post, news item, product review, or resource card.
<aside>Supporting or tangential content, such as a tip, related links, or author information.
<footer>Closing or site-wide information, such as contact details, legal links, or copyright.

A <div> is still useful later when no semantic element describes a grouping, especially for CSS layout. But it has no inherent meaning. Begin with the question, “What is this content for?” Use <div> only when the honest answer is “it is merely a grouping needed for styling or scripting.”

HTML & CSS for Absolute Beginners: Semantic HTML

Watch “HTML & CSS for Absolute Beginners: Semantic HTML” by Kevin Powell for a concise visual explanation of why semantic elements matter and how the main page regions fit together.

Watch semantic meaning to connect correct tags with accessibility and page comprehension. Then watch page regions, focusing on the distinct jobs of header, main, section, and footer, and on keeping opening and closing tags properly nested.


The page plan: a useful small-business foundation

Rather than filling a page with placeholder text, build a small resource page called Small Business Starter. It represents the kind of lightweight, practical tool that might eventually help a new business owner decide what to do first.

Before writing tags, state the content plan in ordinary language:

  1. The site introduces itself and offers links to areas on the same page.
  2. The main content explains a first step and provides two independent starter resources.
  3. A supporting tip reminds the reader to keep scope manageable.
  4. The footer provides a simple contact route and copyright notice.

Now translate that plan into HTML meaning:

Content responsibilityAppropriate element
Site title, short purpose statement, and primary links<header> containing <nav>
All unique content for this page<main>
“Start with one clear problem” topic<section>
Individual reusable resource recommendations<article>
A related but secondary “keep it small” reminder<aside>
Contact and copyright information<footer>

A key distinction is worth making now:

  • Use a <section> when grouping a themed part of the current page. It should generally have a heading.
  • Use an <article> when the content is self-contained and could plausibly be reused elsewhere without the rest of the page. A resource card, blog entry, forum post, or news item is often an article.
  • Use an <aside> for related material that is not central to the main flow. An aside is not simply “anything that appears at the side of the screen.” CSS decides placement; HTML describes the relationship to the main content.

The document’s heading hierarchy should read like an outline:

H1  Small Business Starter
  H2  Start with one clear problem
  H2  Starter resources
    H3  Define one audience
    H3  Test the smallest useful version
  H2  Keep the first version small

Use one <h1> for the page’s main title. Use <h2> for major subdivisions and <h3> only for subdivisions within an <h2> topic. Do not choose heading levels because you want larger or smaller text; CSS will eventually handle that visual decision.

Structuring documents - Learn web development | MDN

Read the relevant parts of MDN’s “Structuring documents” to reinforce the relationship between familiar page regions and the semantic elements that describe them.

In “Basic sections of a document,” read the page-region overview. Notice that header, navigation, main content, sidebars, and footers are defined by their purpose rather than their visual styling. Then continue through “HTML for structuring content” for the accessibility reason behind choosing the right element. In “HTML layout elements in more detail,” read from the element definitions and wrapper guidance. Focus especially on the distinctions among main, article, section, and aside, and on why div and span are fallbacks rather than default page-structure elements.


Build the semantic page

Open index.html in VS Code. It was intentionally empty at the end of the last lesson. Replace its contents with the following code, then save using Ctrl+S.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Small Business Starter</title>
  </head>

  <body>
    <header>
      <h1>Small Business Starter</h1>
      <p>Practical first steps for turning a useful idea into a manageable project.</p>

      <nav aria-label="Main navigation">
        <ul>
          <li><a href="#start">Start here</a></li>
          <li><a href="#resources">Resources</a></li>
          <li><a href="#tip">Keep it small</a></li>
        </ul>
      </nav>
    </header>

    <main>
      <section id="start">
        <h2>Start with one clear problem</h2>
        <p>
          A useful first version does not need to solve every problem a business has.
          Choose one person, one frustrating task, and one small improvement you can test.
        </p>
      </section>

      <section id="resources">
        <h2>Starter resources</h2>

        <article>
          <h3>Define one audience</h3>
          <p>
            Describe a specific person you want to help. Avoid trying to serve every
            possible customer at once.
          </p>
        </article>

        <article>
          <h3>Test the smallest useful version</h3>
          <p>
            Make one workflow work from beginning to end before adding dashboards,
            accounts, notifications, or advanced customization.
          </p>
        </article>
      </section>

      <aside id="tip">
        <h2>Keep the first version small</h2>
        <p>
          A smaller project is easier to understand, afford, maintain, and improve
          from real feedback.
        </p>
      </aside>
    </main>

    <footer>
      <p>Contact: hello@example.com</p>
      <p>&copy; 2025 Small Business Starter</p>
    </footer>
  </body>
</html>

This contains two broad kinds of HTML:

  1. The document setup inside <head>, which provides information about the page.
  2. The visible document content inside <body>, which users read and interact with.

Do not confuse <head> with <header>:

ElementJobNormally visible in the page?
<head>Holds document metadata such as title, character encoding, and future stylesheet links.No
<header>Holds introductory content within the visible page.Yes

The first line, <!doctype html>, tells the browser to interpret this as a modern HTML document. The <html lang="en"> element wraps the complete document and declares that its primary language is English. This language information supports browser translation features and assistive technologies.

Inside the <head>:

  • <meta charset="UTF-8"> allows the page to represent a wide range of characters reliably.
  • The viewport meta element prepares the page to be displayed sensibly on narrow screens when you begin responsive CSS later.
  • <title> supplies the browser-tab title. It is not the same as the visible <h1>.

Inside the <body>, observe the nesting. Every child of <main> is indented one level; every child inside each <section>, <article>, or <aside> is indented again. Indentation does not change how the browser interprets HTML, but it makes the hierarchy understandable to humans—the first audience for your code is often a future version of you.


Inspect the result in a browser

You do not need a server for this static page yet.

  1. Save index.html.
  2. In VS Code Explorer, right-click index.html and select Reveal in File Explorer.
  3. Double-click index.html in File Explorer to open it in your default browser.
  4. Confirm that the browser tab says Small Business Starter.
  5. Click Start here, Resources, and Keep it small in the navigation. Each should scroll to its matching part of the page.

The page will likely look plain. That is expected: browsers apply a small amount of default styling to headings, paragraphs, lists, and links, but you have not yet written CSS. Semantic HTML remains valuable even when the visual design changes completely.

If a navigation link does not work, compare its href value with the target element’s id:

<a href="#resources">Resources</a>
<section id="resources">

The words following # must match exactly. These are fragment links: links to a particular element on the current page.


Read the structure as a browser would

A useful semantic check does not require any new tool. Collapse parts of the file in VS Code using the small arrows beside opening tags, or simply scan the opening and closing tags.

Your outer page structure should be:

<body>
  <header>...</header>
  <main>...</main>
  <footer>...</footer>
</body>

Within <header>, the <nav> is appropriate because the links help users move around the page. Putting a random “Email us” link in <nav> just because it appears at the top would be less appropriate; a navigation element is for a meaningful set of navigation choices, not every link.

Within <main>, there is exactly one primary content region. This is a practical rule: a visitor using assistive technology should be able to locate the main content area without encountering several competing candidates.

The page uses two sections:

  • The first section is a single focused topic, “Start with one clear problem.”
  • The second section, “Starter resources,” groups two articles under one broader theme.

Each <article> could later be displayed on a different page, selected from a database, or reused in a resource listing without losing its meaning. At this stage it is just static HTML, but choosing this boundary now records the content’s intended independence.

Finally, the <aside> is inside <main> because its advice is related to the page’s central subject. It is not the main lesson, but it provides useful context. In a later CSS lesson, it might appear as a highlighted callout, below the resource list, or in a sidebar. Its semantic meaning stays the same.

A short build checklist:

  • index.html begins with <!doctype html>.
  • The document has one <head> and one <body>.
  • The visible page has one <h1>.
  • There is one <main> element.
  • Every <section> has a heading.
  • Navigation links target existing IDs.
  • Tags close in the reverse order in which they open.
  • The page opens in a browser without showing raw HTML text.

If the browser displays tags such as <h1> as visible words, the file may have been saved as index.html.txt. Return to VS Code Explorer and confirm that the filename is exactly index.html.


Choose semantics deliberately, not mechanically

Semantic HTML is not a contest to use the greatest number of specialized tags. It is a decision process.

When deciding how to wrap a block of content, work through these questions:

  1. Is this the page’s unique primary content? Use <main>—but only once.
  2. Is this introductory or ending information for the whole page or a subsection? Consider <header> or <footer>.
  3. Is this a major navigation group? Use <nav>.
  4. Is this a themed grouping that needs a heading? Use <section>.
  5. Would this item still make sense if copied into another context? Consider <article>.
  6. Is it useful but secondary or tangential to the main content? Consider <aside>.
  7. Does none of those meanings honestly fit? Use a <div> with a clear class later, when a purely presentational grouping is needed.

For example, suppose the page later has a row containing two buttons that form a visual unit: “Save draft” and “Publish.” That wrapper may be a plain <div class="actions">, because it may not represent a distinct section, article, navigation landmark, or aside. Semantic HTML does not prohibit <div>; it prevents it from becoming a substitute for thinking about structure.

You can also have headers and footers inside articles and sections. For example, a future article could have its own <header> containing its title and author, and its own <footer> containing a publication date or tags. A page-level <header> and <footer> describe the site or page; nested ones describe their parent content. Keep today’s example straightforward, but recognize that semantic elements express relationships through their nesting.


Wrap-up

You have built a complete, meaningful HTML page rather than a collection of visually positioned boxes.

The important takeaways are:

  • Semantic HTML describes the purpose of content, while CSS will control its visual presentation.
  • <header>, <nav>, <main>, and <footer> describe major page regions.
  • <section> groups a themed part of a page; <article> holds independently meaningful content; <aside> provides supporting material.
  • Use one <h1> as the page title and maintain a logical heading sequence.
  • Use one <main> element for the unique primary content.
  • Prefer semantic elements over generic <div> wrappers when an appropriate semantic meaning exists.
  • Correct nesting and readable indentation make the page maintainable as it grows.

Next, you will apply CSS rules from styles/main.css to control typography, spacing, color, and layout—turning this structurally sound but plain document into a more deliberate interface.

Can't find a good explanation? Sign up and we'll make it for you

Sign up