Skip to content

Build a page with semantic HTML

You will organize a web page with semantic HTML elements that identify its navigation, main content, sections, independent entries, related information, and footer.

Semantic HTML describes what each part of a page does. This structure helps browsers, assistive technologies, search tools, and other developers interpret the content.

What you will practice

  • Explain the difference between semantic meaning and visual appearance.
  • Choose header, nav, main, section, article, aside, and footer from the purpose of the content.
  • Use headings to give sections and articles clear names.
  • Identify when a div is appropriate because no semantic element describes the content.
  • New: Semantic HTML elements, page landmarks, fragment links, and a method for choosing an element by purpose.
  • Reused: The HTML document structure, tags, attributes, nesting, headings, paragraphs, lists, links, saving a file, and reloading a browser page.

Starting point

Before you start

  • The html-elements folder and index.html file from the previous lesson.
  • VS Code and a current version of Edge, Chrome, or Firefox.
  • A page that already opens in the browser and contains valid HTML elements.
Current state
index.html contains a complete HTML document. Its body contains a heading, paragraphs, a list, and a link, but it does not identify the page's major regions.
First action
Open the html-elements folder in VS Code, open index.html, and find the opening and closing body tags.
First checkpoint
You can identify the complete body element and the visible content nested inside it.
Help trigger
Ask for help if index.html no longer opens in the browser, the previous page content is missing, or you cannot find the matching body tags.

You have completed the lesson when:

  • index.html contains one visible main element;
  • the page uses header, nav, main, section, article, aside, and footer for content that matches each element’s purpose;
  • the page has one h1, and its section and article headings follow a clear h2 and h3 order;
  • both navigation links target the matching section on the same page; and
  • every opening tag that requires a closing tag has one in the correct nesting order.

A semantic element states the purpose of its content. For example, nav identifies major navigation, and main identifies the page’s primary content.

A div groups content but does not describe the group’s purpose. It is a non-semantic element. A div is still useful when you need a grouping element for CSS or JavaScript and no semantic element matches the content.

Choose an element by answering this question:

What job does this content perform on the page?

Use the most specific element whose meaning matches that job.

Element Use it for
header Introductory content for a page or for a section, often including a name, heading, or navigation
nav A major group of navigation links
main The primary content that is unique to the current page
section A thematic group of content, usually with a heading
article Self-contained content that could make sense on its own, such as a journal entry or news item
aside Related content that is useful but not part of the main flow
footer Closing information for a page or for a section, such as authorship or related links
div A group with no more specific semantic meaning

Several semantic elements also create landmarks. A landmark is a page region that assistive technologies can use for navigation. A page-level header, nav, main, aside, and page-level footer can make the overall structure quicker to identify.

In the head element, change the existing title element to <title>Web learning journal</title>.

Next, replace the complete body element in index.html with this code:

index.html — body element
<body>
<header>
<p><a href="index.html">Web learning journal</a></p>
<nav aria-label="Primary navigation">
<ul>
<li><a href="#entries">Entries</a></li>
<li><a href="#practice">Practice plan</a></li>
</ul>
</nav>
</header>
<main>
<h1>Web learning journal</h1>
</main>
<footer>
<p>Web learning journal</p>
</footer>
</body>

Save index.html and reload the browser.

The page now has three page-level regions:

  • header introduces the site and contains its primary navigation;
  • main contains the content unique to this page; and
  • footer contains closing information about the page.

Use one visible main element on a page. Repeated site content, such as the site name, primary navigation, and page footer, belongs outside main.

The nav element contains the page’s major navigation links. It uses aria-label="Primary navigation" to give that navigation region a clear name. This label becomes especially useful if a page contains more than one nav element.

The two link destinations start with #. These are fragment links. A fragment link points to the element whose id has the same value. The target elements do not exist yet, so the links will work after you add the sections in the next step.

Confirm these results:

  1. The browser tab and main heading both show Web learning journal.
  2. The page shows links named Entries and Practice plan.
  3. The footer text appears after the main heading.
  4. Selecting either navigation link does not move to a section yet. This is the expected result because the matching id values are not present.
  • If the old page still appears, save index.html and reload the browser.
  • If content is missing, confirm that the new body remains between the closing head tag and the closing html tag.
  • If the browser shows text such as <header>, confirm that each tag uses both < and >.

Checkpoint: The page-level regions are in place

What now works
The browser tab shows Web learning journal. The page shows a header with navigation, one main heading inside main, and a footer after main.
Files changed
index.html
What remains
Add named sections, self-contained journal entries, and related reference content inside main.
Next action
Find the main element and replace it with the expanded main element in the next section.
If it does not work
Check that header, main, and footer are siblings inside body and that each element has a matching closing tag.

Replace the complete main element with this code:

index.html — main element
<main>
<h1>Web learning journal</h1>
<section id="entries">
<h2>Recent entries</h2>
<article>
<h3>HTML document structure</h3>
<p>I created a complete HTML document with head and body elements.</p>
</article>
<article>
<h3>Choosing elements by purpose</h3>
<p>I choose an HTML element from the role of its content, not from its default appearance.</p>
</article>
</section>
<section id="practice">
<h2>Practice plan</h2>
<ol>
<li>Check the document structure.</li>
<li>Identify each major page region.</li>
<li>Reload and check the browser result.</li>
</ol>
</section>
<aside>
<h2>Current reference</h2>
<p>Keep the HTML elements lesson open when you need to review tags, attributes, or nesting.</p>
</aside>
</main>

The section elements group content by topic. Each section has an h2 that names the group.

The first section contains two article elements. Each journal entry is self-contained and has an h3 that names the entry. The heading order reflects the content hierarchy:

Heading structure
h1: Web learning journal
h2: Recent entries
h3: HTML document structure
h3: Choosing elements by purpose
h2: Practice plan
h2: Current reference

The aside contains a reference related to the page, but the journal still makes sense without it. This relationship makes aside more suitable than section for that content.

The id="entries" and id="practice" attributes supply the targets for the two fragment links. The value after # in each link must match the target id exactly.

  1. Save index.html and reload the browser.
  2. Select Entries in the navigation. The URL ends in #entries, and the browser moves to the Recent entries section when there is enough page space to scroll.
  3. Select Practice plan. The URL ends in #practice, and the browser moves to the Practice plan section when there is enough page space to scroll.
  4. Confirm that the page shows one h1, three h2 headings, and two h3 headings.

If the full page fits in the browser window, a fragment link can update the URL without a visible scroll. Make the browser window shorter if you want to observe the movement.

  • If a navigation link does not update the URL, compare its href with the matching section id. #entries must match id="entries".
  • If one article appears outside the Recent entries section, check the closing article and section tags.
  • If a heading is missing, confirm that its text is between the matching opening and closing heading tags.

Checkpoint: The main content has a semantic structure

What now works
The navigation links target two named sections, each journal entry is an article, and the related reference is an aside.
Files changed
index.html
What remains
Verify the complete element structure and explain why each semantic element fits its content.
Next action
Complete the self-check and use the element-choice questions to review any uncertain region.
If it does not work
Read the page from body inward, match each opening tag with its closing tag, and compare each fragment link with its target id.

Use these questions when you are uncertain which element to use:

  1. Is this the primary content unique to the page? Use main.
  2. Is this a major set of navigation links? Use nav.
  3. Is this introductory or closing content for a page or a section? Consider header or footer.
  4. Is this a thematic group that needs a heading? Consider section.
  5. Could this content make sense as an independent item? Consider article.
  6. Is this content related but secondary to the surrounding content? Consider aside.
  7. Does no semantic element describe the purpose? Use div for the necessary grouping.

The correct choice depends on the content, not only on the element’s position. A header or footer can belong to the complete page, an article, or a section. A group of links needs nav only when the group provides major navigation.

Do not use section as a replacement for every div. If a group exists only to support layout or styling and has no thematic meaning, div is the more accurate element.

Self-check

Complete these checks against the required result.

  1. Confirm that index.html contains one visible main element and that the page h1 is inside it.
  2. Select both navigation links and confirm that each URL fragment matches a section id.
  3. Identify the heading that names each section and article.
  4. Explain why a journal entry uses article while the related reference uses aside.
  5. Explain why a div would be more accurate than section for a grouping used only for CSS layout.
  6. Match every opening tag with its closing tag and confirm that nested elements close from the inside out.

Semantic HTML adds meaning to the document structure. It does not guarantee a particular visual design, accessibility result, or search ranking by itself.

A useful page still needs:

  • headings that describe the content hierarchy;
  • link text that identifies each destination;
  • valid nesting and complete tags;
  • text alternatives for meaningful images; and
  • CSS that remains readable at different viewport sizes.

Semantic elements provide a stronger foundation for those parts. They let different tools start from the same documented content structure instead of inferring every region from generic div elements.

The required lesson is complete when the page uses semantic elements for matching content roles, both fragment links work, and you can explain each element choice from the purpose of its content.

Continue to Use Git and GitHub as a solo developer to save the journal as a sequence of commits and connect the local project to GitHub.

If you stop here, leave yourself this resume note: Next action: open the Git and GitHub lesson with the completed html-elements folder ready in VS Code.