Semantic HTML and Why It Matters
By the end of this lesson
Choose elements for meaning rather than appearance, and explain what that gives you for free.
Semantic HTML means choosing elements based on what the content is, not how you want it to look.
A button that performs an action should be a button element. You can make a div look identical with CSS, and it will be worse in ways that are invisible until someone tries to use it with a keyboard.
<!-- Looks like a button, behaves like nothing -->
<div class="btn" onclick="save()">Save</div>
<!-- Actually a button -->
<button type="button" onclick="save()">Save</button>- The div cannot be focused with Tab, cannot be activated with Enter or Space, and is not announced as a button by a screen reader.
- The button element gets all of that behaviour with no extra work, because that is what the element means.
What the correct element gives you without any effort:
- Keyboard operation — focus order, Enter and Space activation
- Screen reader announcement of what the thing is and what it does
- Correct behaviour in forms, including submission on Enter
- Browser features such as autofill and password management
- A sensible starting appearance before any CSS
Structure carries meaning too
<header>
<nav aria-label="Primary">
<a href="/learning">Learning Academy</a>
</nav>
</header>
<main id="main-content">
<h1>Entity Framework Core</h1>
<section>
<h2>What you will learn</h2>
<p>Map C# types to database tables and keep the SQL visible.</p>
</section>
</main>
<footer>
<p>Anvi Software Solutions</p>
</footer>- header, nav, main, section and footer describe what each region is. Screen reader users can jump directly between them.
- There should be one main element, and one h1 that states what the page is about.
- aria-label on the nav distinguishes it when a page has several navigation regions.
<!-- Broken: the text is near the field but not connected to it -->
<div>Email address</div>
<input type="email" />
<!-- Correct: for matches id, so the label belongs to the field -->
<label for="email">Email address</label>
<input type="email" id="email" name="email" />- With a real association, a screen reader announces the label when the field is focused, and clicking the label focuses the field.
- Without it, the user hears "edit text, blank" and has no idea what is wanted.
Summary
- Choose elements for meaning; use CSS for appearance
- The correct element supplies keyboard support and screen reader semantics for free
- Headings form an outline — pick the level for structure, not for size
- Labels must be associated with inputs via for and id, and placeholders are not labels
Practice
Attempt each one before opening the solution. Getting it wrong first is how the idea sticks.
Try it yourself
Try it yourself
Take this markup and make it semantic and accessible: a div styled as a heading, a div acting as a clickable row, and a search input with text next to it instead of a label.
Show solution
Each fix replaces a styled div with the element that already means what you intended, which removes the need to re-add behaviour manually.
<h2>Available courses</h2>
<ul>
<li>
<a href="/learning/courses/csharp">C# From Beginner to Advanced</a>
</li>
</ul>
<form role="search">
<label for="course-search">Search courses</label>
<input type="search" id="course-search" name="q" />
<button type="submit">Search</button>
</form>Knowledge check
Nothing is recorded and there is no score. The explanation appears either way.
Saved in this browser only.