Semantic HTML: meaningful structure, forms and access for everyone
Lesson 2 of 8
2Semantic HTML: meaningful structure, forms and access for everyone
The big pictureHTML is not "text with colours". It is structure that tells the browser, the screen reader and the search engine: this is the page header, this is the navigation, this is the main content, this is a button. CSS and JavaScript sit on top, and the sounder the structure, the easier their job.
What the picture shows: A semantic page from top to bottom. Each box is an element with meaning, and a screen reader jumps between them as your eyes do.
Map of this part
The concepts in order, click any one to jump to it:
Two ways into the same idea
Think of HTML as a house frame before the paint: where the door is, where the rooms are, where the hall runs. Build everything from one wall type (div) and a guest gets lost; put up "kitchen" and "bedroom" signs and they find their way even in the dark. A screen reader, a program that reads the page aloud for blind people, is that guest in the dark. A search engine is another guest, reading the signs to learn what your page is about.
Semantic elements produce the accessibility tree with implicit roles: <nav> has the navigation role and <main> the main role, so they appear as landmarks a screen reader jumps between. <button> takes focus and answers Enter and Space with no JavaScript. Forms carry built-in validation (required, type=email, pattern, min/max) and the Constraint Validation API with the :invalid and :user-invalid pseudo-classes. <picture> and srcset/sizes let the browser pick the right image, loading="lazy" defers what is below the fold, and width/height prevent layout shift (CLS). ARIA complements semantics and does not replace them: "the first rule of ARIA is not to use it" when a native element exists.
Before You Start
📄Your first web page
You know tags, elements, attributes and the file skeleton.
📨HTTP
You know a form sends a request to the server.
🧰An editor
VS Code with the Live Server extension, or the live playground in the lesson.
The Core Idea
1Semantic page structure
Instead of <div class="top"> write <header>. The core elements: header for the page or section header, nav for the main navigation links, main for the primary content (only one per page), article for self-contained content that makes sense alone (a post, a product card), section for a section with a heading, aside for side content, and footer for the page footer. div stays a box with no meaning, for when you need a wrapper just for styling.
A page with semantic structure
It looks exactly like a page of divs, but the meaning differs. Open developer tools, then the Accessibility tab, and you will see the landmarks: banner, navigation, main and contentinfo.
Order headings h1 to h6 without skipping (do not jump from h2 to h4). Many screen reader users move through a page by headings alone; they are its table of contents.
2Forms: field types and labels
A form collects what the user types and sends it. Every field needs a label tied to it with for, equal to the field's id: clicking the text focuses the field and a screen reader reads its name. name is the value's name when it reaches the server. The field type changes the phone keyboard and turns on fitting validation.
An order form with every kind of field
Click the word "Oat" itself: the button gets picked because the label wraps it. Radio buttons sharing the same name allow only one choice.
placeholder instead of label. The grey text vanishes as soon as you type so the user forgets what the field was, and screen readers may not read it. A placeholder is a format example; a label is the field's name.3Built-in validation: the browser checks before sending
Without a single line of JavaScript, the browser refuses to send a form with errors and shows a message: required is mandatory, type="email" must be an email, minlength/maxlength limit text length, min/max bound numbers and dates, and pattern is a pattern (regular expression) the text must match. CSS can colour a wrong field with :user-invalid.
Try to get it wrong on purpose
Press "Sign up" with the fields empty, then type an email with no @, then a 9-digit phone number. Every message you see was written by the browser alone.
required in developer tools. Browser validation is for the user's comfort; server validation is for safety. You will write it in the server lesson.4Buttons and links: each has its job
The rule is simple: a link takes you somewhere, a button does something. <a href> for navigation (another page, another section), and <button> for actions (add to cart, open the menu, send). A button inside a form defaults to submit, so write type="button" for one that should not send.
A real button versus a clickable div
Click inside the preview, then press Tab a few times. Notice the focus skips the div and never reaches it.
5Responsive images and media
A 400-pixel-wide phone does not need a 3000-pixel image that eats the user's data plan. srcset offers the browser several sizes, and sizes tells it the displayed width, so it picks the lightest that fits. width/height reserve the image's space before it loads so the page does not jump, and loading="lazy" defers far-away images until the user nears them. figure with figcaption is for an image with a caption.
<figure>
<img src="latte-800.jpg"
srcset="latte-400.jpg 400w, latte-800.jpg 800w, latte-1600.jpg 1600w"
sizes="(max-width: 600px) 100vw, 50vw"
alt="كوب لاتيه برسمة قلب على الرغوة"
width="800" height="600" loading="lazy">
<figcaption>لاتيه اليوم بحليب الشوفان</figcaption>
</figure>
<video src="pour.mp4" controls width="640" poster="pour.jpg">
<track kind="captions" src="pour.ar.vtt" srclang="ar" label="العربية">
</video>video and audio take controls to show the play buttons. track adds captions, needed by deaf viewers and anyone watching with the sound off.
6Accessibility: a page for everyone
One in six people worldwide lives with some form of disability, according to the World Health Organization. An accessible page is one a blind person uses with a screen reader, someone without a mouse uses with a keyboard, and someone with low vision uses with enlarged text. The five rules that matter most:
(1) The right element first: button, a, label, nav. (2) Everything by keyboard: Tab reaches everything pressable, and you can see where focus is. (3) Alternative text for every image that carries meaning. (4) Enough contrast between text and background (4.5 to 1 for normal text). (5) A correct lang so the screen reader speaks the right language with the right accent. Use aria-* only when no native element carries the meaning, like aria-label for an icon-only button.
<!-- icon-only button: give it a name the screen reader can say --> <button type="button" aria-label="إغلاق القائمة">✕</button> <!-- a live message read aloud when it changes --> <p role="status">أُضيف اللاتيه إلى سلتك.</p>
7Page information: for search and sharing
What is in head does not show on the page but shows elsewhere: title on the tab and in the Google result, meta name="description" as the snippet under the link in search results, and Open Graph tags (og:) as the image and title when your link is shared on WhatsApp or X.
<head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>مقهى درب | قهوة مختصة في الرياض</title> <meta name="description" content="نحمّص القهوة كل صباح. اطلب أونلاين واستلم خلال 10 دقائق."> <meta property="og:title" content="مقهى درب"> <meta property="og:image" content="https://example.com/cover.jpg"> <link rel="icon" href="/favicon.svg"> </head>
Worked example
Problem: an "add to cart" button written <div class="btn" onclick="add()">Add</div>, and an email field <input placeholder="Email">. What is wrong? Analysis: the div takes no Tab focus, ignores Enter, and a screen reader does not know it is a button. The field has no label so it is read as just "edit text", and without type="email" there is no validation and no @ key on the phone keyboard. Fix:
<button type="button" class="btn" onclick="add()">أضف للسلة</button>
<label for="email">البريد</label>
<input id="email" name="email" type="email" required autocomplete="email"
placeholder="you@example.com">The same look after CSS, with all the behaviour for free: focus, keyboard, the right announcement and validation.
Myth vs Reality
| Myth | Reality |
|---|---|
| HTML is easy and needs no advanced learning. | Writing it is easy; writing it right for accessibility, search and speed is a skill many lack. |
| div and span are enough for everything. | They work visually but carry no meaning, so you rebuild what the semantic element gives you for free. |
| Accessibility is only for a small group. | It helps everyone: captions for someone in a noisy place, the keyboard for someone in a hurry, contrast for someone reading in sunlight. |
Where you meet it at work
🔍Search engines
Headings, semantic structure and the description tag lift how a page is understood and ranked.
♿Screen readers
Millions browse by voice through headings and landmarks.
⚖️Laws and contracts
Many government bodies and companies require the WCAG standard on their sites.
Test your understanding
Which element fits the site's main list of links?
nav gives the navigation role, so a screen reader jumps straight to it.
Why tie a label to its field with for?
The link helps screen readers and enlarges the tap target on phones.
What is srcset for?
A phone downloads a small copy and a big screen a sharp one.
A "open menu" button inside a form submits the form every time you press it. What is the fix?
A button in a form is submit by default. type="button" makes it a plain button.
What protects the server from bad data?
Browser validation is easy to bypass; only the server has the final say.
Quick review cards
Check Your Understanding
Why is button better than a clickable div?
It takes focus, answers Enter and Space, and is announced as a button to screen readers, with no extra code.
Is form validation enough?
No. It is for user experience. The server must check everything because a request can be sent without the form.
How many main elements per page?
One visible main, holding the page's primary content.
What is the difference between placeholder and label?
The label is the field's permanent, readable name; the placeholder is an example that vanishes when you type and cannot replace it.
Resources for this lesson
Grouped by type. Start with the official docs for precision, or an article or video for the explanation.
Articles1
Done with this lesson?
Sign in to save your progress.