A Beginner's Guide to Semantic HTML
Using <div> and <span> for everything works, but semantic elements like <nav>, <main>, and <article> give your markup real meaning — for free.
HTML gives you elements that describe what content is, not just
how it looks. Semantic HTML means choosing those elements — <nav>,
<main>, <article>, <header>, <footer>, <button> — over a
generic <div> or <span> wherever a more specific element fits.
Why it matters beyond style
A <div> carries no meaning on its own; all of its behavior comes
from CSS and JavaScript you add yourself. A <button>, by contrast,
is keyboard-focusable and clickable by default, announces itself as
a button to screen readers, and responds to both Enter and Space
without any JavaScript. Reach for <div onclick="..."> instead and
you've silently thrown all of that away — and now have to rebuild
keyboard support and screen-reader semantics by hand just to match
what <button> already did.
A quick before/after
<!-- Generic, no inherent meaning -->
<div class="nav">
<div class="nav-item">Home</div>
</div>
<!-- Semantic -->
<nav>
<a href="/">Home</a>
</nav>
The semantic version tells a screen reader "this is navigation,
containing a link" automatically. The <div> version tells it
nothing — a screen reader has no way to know class="nav" means
anything at all.
Structural elements worth knowing
<header>/<footer>— introductory or closing content for the page or a section<main>— the page's primary content, exactly once per page<nav>— a block of navigation links<article>— self-contained content that would make sense distributed on its own (a blog post, a news story)<section>— a thematic grouping of content, usually with its own heading
The practical payoff
Semantic markup improves accessibility (screen readers and other
assistive tech rely on it directly), gives search engines a much
clearer structural signal about your page than a wall of <div>s,
and — as a side effect — tends to produce more readable, more
maintainable markup, since the tag names describe the content
instead of hiding behind arbitrary class names.