Learning on Web Dev Open is free for all.

Take It Apart > HTML is a data structureThe tags that do work for you
Phase 01HTML is a data structure38 of 434

The tags that do work for you

A div and a button can look identical and behave completely differently. One of them you have to build; the other arrives finished.

Concept18 minAI adversary

Take a <div> and give it a click handler, a background, a border radius and some padding. It looks exactly like a button. It is not a button. It is not reachable by keyboard, so a third of your users cannot press it. It is not announced as a control, so a screen reader user has no idea it does anything. It does not respond to the space bar or enter. It does not participate in a form. It has no disabled state. It does not get the focus ring your operating system draws.

To reach parity you would write a tabindex, a role, key handlers for enter and space, a focus style, an aria-disabled state, and logic to keep all of that in sync. Roughly thirty lines, and you will get at least one of them subtly wrong, because everyone does. Or you type <button> and all of it is already there, implemented in C++, tested by every browser vendor, and free.

That is the main idea for semantic HTML and it has nothing to do with tidiness. The correct element is not the polite choice, it is the one where someone has already done the work. <details> gives you a disclosure widget with no JavaScript at all. <dialog> gives you a modal with focus trapping and an escape key. <label for> gives you a click target that focuses the input, for free, forever.

The second thing semantics buy is structure that other software can act on. <header>, <nav>, <main>, <article>, <aside> and <footer> are landmarks. A screen reader user can jump between them the way you jump between headings in a long document, it is a table of contents for a page, and it costs you nothing but choosing a different tag name. Reader modes use them. Search engines use them. Your future self, reading the markup in a year, uses them.

The swap below renders the same page twice. Look carefully: the rendered output is identical. That is deliberate and it is the uncomfortable part, nothing on screen tells you which version you are looking at. The difference only appears in the landmark list and in the "what you would have to build yourself" column. Press the tab-through button and watch focus order in each, which is the fastest way to feel the gap rather than read about it.

The same page, twice

Rendered: identical in both
Skip to main content
Aurora

Type on the web

A measure between 45 and 75 characters is not a style preference. It is the range in which the eye finds the start of the next line without hunting.

Measure

Set it in ch units and the value survives a font change.

Built in 2026. No cookies, no tracking.
<header> <nav> <form role=search> <main> <article> <aside> <footer>

What the rotor lists: every one of these is a single keystroke away.

  • banner<header>
  • navigation<nav>: Primary
  • search<form role="search">
  • main<main>
  • article<article>: Type on the web
  • complementary<aside>: Related
  • contentinfo<footer>

Headings

  • h1Type on the web
  • h2Measure
  • h2Related
Focus order

Nothing to walk through. Four things on this page look like controls and none of them can take focus, because a div is not focusable and never becomes focusable by being styled like a button.

Seven landmarks and 0 tab stops, and the rendered page did not move by one pixel when you switched. The tags cost nothing to type and carry the behaviour of six features you would otherwise be maintaining.

Identical rendering, completely different documents. Tab through both to feel the difference rather than read about it.

Now go and open the page your model generated in Phase 00 and count the divs. Then count how many of them are actually one of: a section, an article, a nav, a list, a button, or a heading. The ratio is the size of the job, and fixing it is usually an afternoon that makes the page work for people who could not use it at all before.

Worth reading

You should now be able to

  • Choose the element that already does what you were about to implement
  • List what a semantic element gives you for free
  • Explain why identical rendering does not mean identical behaviour
  • Recognise the four or five elements models systematically under-use
Ask the community

Loading…