Semantic Markup vs Div Soup

Semantic elements carry meaning that the browser, assistive technology, and search engines can act on. A div carries none. Every semantic element you choose correctly gives its implicit ARIA role for free and contributes to a navigable landmark structure that assistive technology users depend on.

HTML6 min readConcept 31 of 42

What it is

Semantic HTML means choosing elements whose name reflects the role of their content. <nav> says "this is a navigation block". <main> says "this is the primary content of the page". <article> says "this content could stand alone if extracted". Each of these elements has an implicit ARIA role that the browser assigns automatically: <nav> gets role="navigation", <main> gets role="main", and so on. A <div> gets role="generic": that is the browser saying "I don't know what this is". The same applies to <span> inline.

"Div soup" is the informal name for a page built entirely of <div> and <span> elements with no semantic elements, relying on class names for organisation. Class names describe the developer's intent but carry no meaning that browsers, AT, or search engines can process. A div with class="header" is still a generic container; a <header> is a landmark.

Why it matters

Assistive technology builds a landmark navigation list from the semantic elements on the page. Screen reader users press a shortcut key to open this list and jump directly to the section they want (main content, navigation, complementary info, footer) without reading every element in between. A page built with div soup has no landmarks, so the user must tab through every link and interactive element in source order to find the content they came for. This is the problem that WCAG's "bypass blocks" requirement (2.4.1) exists to solve.

Search engines also use semantic structure. An <article> signals that the content inside is a self-contained piece worth indexing independently. Headings inside <article> are weighted differently than headings inside a generic <div>. The landmark structure created by semantic elements is one of the signals crawlers use to understand which content on a page is primary.

How it works

Replace structural divs with the element whose name matches what the content does. Site header: <header>. Primary navigation: <nav>. Main content: <main> (only one per page). Sidebar: <aside>. Site footer: <footer>. Self-contained content (a blog post, a news item, a product card): <article>. A named section within main content: <section> with an accessible heading inside it.

The same semantic elements can appear multiple times on a page in different contexts. A <header> inside an <article> is the article's header, not the page-level banner. Similarly, a <footer> inside an <article> is the article footer, not the page footer. The implicit ARIA role of <header> and <footer> changes to "generic" when they are not a direct descendant of <body> (or equivalent landmark), because they are no longer the page-level banner or contentinfo landmark.

If you genuinely cannot use a semantic element (rendering constraints, third-party component libraries), add an explicit role attribute to the div: <div role="navigation">. This is called an ARIA role override. It is always better to use the native element, but the role attribute is the correct fallback. The rule of thumb is: native element first, ARIA second, <div> without role last.

Try it

Watch a page structure built from divs transform into named semantic landmarks, and see what assistive technology gains from the change.

Div soup to semantic landmarks

div.header
div.nav
div.main
div.aside
div.footer

What AT landmark navigation sees

Div soup

div.headergeneric
div.navgeneric
div.maingeneric
div.asidegeneric
div.footergeneric

No landmark shortcuts available

Semantic HTML

banner
navigation
main
complementary
contentinfo

Jump to any landmark directly

Implicit ARIA roles

<header>bannerpage-level only
<nav>navigation--
<main>mainone per page
<footer>contentinfopage-level only
<aside>complementary--
<article>article--
<section>+nameregionneeds accessible name
<div>genericnot a landmark

Check yourself

Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.

  1. 1What implicit ARIA role does a <div> have?
  2. 2A <header> is nested inside an <article>. What is its implicit ARIA role?
  3. 3Why do screen reader users benefit from a page that uses <main> instead of <div id="main">?

Remember this

  • <div> has role="generic": it is in the accessibility tree but conveys no meaning to AT or search engines.
  • Semantic elements give their implicit ARIA landmark roles for free: <nav> = navigation, <main> = main, <header> = banner (page-level only).
  • <header> and <footer> only carry their landmark roles at page level; inside <article> or <section> they fall back to generic.
  • Landmark navigation is how AT users bypass repeated blocks: no landmarks means no bypass, which fails WCAG 2.4.1.

Done with this concept?

Mark it complete to track your progress. No login needed.