Many modern pages are built almost entirely out of div and span, with CSS classes and a few lines of JavaScript added to make them behave like buttons, menus or headings. Visually the result can be identical to a well-written page, but to the browser, to screen readers and to search engines it is an almost silent document. Semantic HTML means choosing the element that describes the meaning of the content, not its appearance.
What "semantic" means
Every HTML element carries a role. A button is an activatable control, a nav is a navigation block, an h2 is a second-level heading. When you use the right element, the browser gives you a set of behaviours for free: keyboard focus, activation with Enter and Space, correct announcements by assistive technologies, the ability to jump from one section to another.
Compare these two snippets:
<!-- Not semantic -->
<div class="btn" onclick="save()">Save</div>
<!-- Semantic -->
<button type="button" onclick="save()">Save</button>
The first one does not receive keyboard focus, is not announced as a button and does not respond to the Enter key. To get the same behaviour you would have to add tabindex, an ARIA role and keyboard event handling. The second one already works.
Page structure: landmarks
HTML5 introduced elements that describe the main areas of a page. Screen readers expose them as landmarks the user can jump between.
header: the header of the page or of a section.nav: groups of main navigation links.main: the main content, only one per page.article: self-contained content that would make sense even outside the page (a post, a product card).section: a thematic portion with its own heading.aside: side content, such as a related-information box.footer: the footer of the page or of a section.
A typical skeleton:
<body>
<header>
<a href="/">Logo</a>
<nav aria-label="Main">...</nav>
</header>
<main>
<article>
<h1>Article title</h1>
<p>...</p>
<section>
<h2>First topic</h2>
</section>
</article>
</main>
<footer>...</footer>
</body>
Headings are not about size
A common mistake is picking h3 or h4 because it "has the right size". Heading levels describe the document hierarchy, not the font size: sizes are set with CSS. A good rule of thumb is one h1 per page and no skipped levels on the way down (from h2 to h4 without an h3). Many screen reader users navigate precisely by scrolling through the list of headings: a consistent hierarchy amounts to a readable table of contents.
Lesser-known semantic elements
Beyond landmarks there are small but very useful elements:
timewith thedatetimeattribute makes a date machine-readable:<time datetime="2025-03-14">14 March</time>.figureandfigcaptiontie an image or a code snippet to its caption.detailsandsummarycreate a native expandable panel, with no JavaScript.abbrwithtitleexplains an acronym.dl,dtanddddescribe term-definition pairs, ideal for glossaries and spec sheets.
Lists and tables used for what they are
A menu is a list of links, so ul with li is the natural choice: the screen reader will announce "list, five items", immediately conveying the structure. Tables, on the other hand, are for tabular data, not for layout. When you need them, use caption for the title, thead and tbody to separate headers from data, and th with scope to link each cell to its header.
The concrete benefits
Accessibility
This is the most obvious advantage. A real button, a real link and a real heading work with keyboards, screen readers, voice control and magnifiers without extra code. Every time you rebuild a native control with a div, you take on the job of replicating behaviours the browser had already implemented and tested.
SEO
Search engines use structure to understand what a page is about and which parts are main content as opposed to navigation and footer. Consistent headings, real paragraphs and descriptive links make the text easier to interpret. It is not a ranking shortcut, but it removes ambiguity.
Maintenance
Semantic code is easier to read. Whoever opens the file six months later finds nav, main and article instead of ten levels of div class="wrapper-inner". CSS benefits too: you can write shorter, less fragile selectors.
When a div is perfectly fine
Semantic HTML does not mean getting rid of div and span. They are perfect as purely presentational containers, for example to group elements laid out with Flexbox or Grid. The question to ask is simple: is there an element that describes the meaning of this content? If so, use it. If not, a div is the right choice.
How to check your markup
A few quick checks help you spot problems:
- Navigate the page using only the keyboard, with Tab, Enter and Space.
- Open the Accessibility panel in the browser developer tools and look at the accessibility tree.
- Disable CSS: the page should remain understandable and orderly.
- Check the heading hierarchy with an extension or the browser's outline view.
In short
- Choose HTML elements based on the meaning of the content, not on how they look.
- Use landmarks (
header,nav,main,footer) to give the page a navigable structure. - Heading levels describe hierarchy: sizes are handled with CSS.
- Native elements give you accessibility and keyboard behaviour for free.
divandspanare still useful, but only when no semantic element fits.