Semantic HTML is the practice of using HTML elements according to what content means rather than how it should look. A navigation menu is marked up as <nav>, the main body of a page as <main>, a self-contained article as <article>, a heading as <h2>, and a clickable control that performs an action as <button>. The alternative, building everything from generic <div> and <span> elements styled to look right, is known as div soup: it looks identical to a sighted visitor and is close to meaningless to everything else.
That difference matters because a web page is read by far more than people with working eyes and a mouse. Screen readers, keyboard users, search crawlers, AI crawlers, browser reader modes, translation tools, and automated agents all rely on the structure in the markup to work out what a page contains. Semantic HTML is the cheapest accessibility, SEO, and machine-readability work available, because it costs nothing extra at build time and cannot be retrofitted cheaply.
The core semantic elements
Page structure
<header> introductory content for the page or a section. <nav> a block of navigation links. <main> the primary content, used once per page. <article> a self-contained piece that would make sense on its own, such as a blog post. <section> a thematic grouping, normally with a heading. <aside> tangentially related content such as a sidebar. <footer> closing content for the page or a section.
Several of these map to landmarks that screen reader users navigate by, jumping straight to the main content or the navigation instead of listening through the whole page. A site built from anonymous divs offers no landmarks to jump to.
Text and content
<h1> through <h6> for the heading hierarchy, <p> for paragraphs, <ul>, <ol> and <li> for lists, <blockquote> for quotations, <figure> and <figcaption> for images with captions, <time> for dates and times in a machine-readable format, <address> for contact details, and <table> with proper <th> headers and scope for genuine tabular data.
<strong> and <em> convey importance and emphasis; <b> and <i> only change appearance. Screen readers can announce the former.
Interaction
<a> for anything that navigates somewhere. <button> for anything that performs an action. <form>, <label>, <input>, <select> and <fieldset> for forms. <details> and <summary> for expandable sections that need no JavaScript at all.
Why it matters
Accessibility
This is the strongest reason. Screen reader users navigate by headings, landmarks, links, and form controls. Keyboard users move through focusable elements in document order. Native semantic elements come with that behavior built in: a <button> is focusable, announced as a button, and activates with both Enter and Space. A <div> with a click handler does none of that unless someone painstakingly reimplements all of it, and usually they do not. Semantic markup is foundational to ADA compliance and to meeting WCAG.
Search engines
Crawlers use structure to work out what a page is about and which parts matter. A clear heading hierarchy signals how the content is organized and which passages answer which questions, which is part of how pages get selected for featured snippets and AI summaries. Semantic markup also makes a page easier to crawl, because real links are followable while JavaScript click handlers on generic elements may not be.
AI readers
Many AI crawlers do not execute JavaScript and read only the HTML the server returns. For them, structure in the markup is most of the signal available. A page where the main content sits inside <main>, sections carry real headings, and navigation is separated from body text is far easier to parse correctly than a wall of nested divs. The same is increasingly true for agentic systems that visit sites to complete tasks on someone’s behalf, which need to identify forms, buttons, and fields reliably.
Maintainability and browser features
Semantic markup is easier for the next developer to read, and it unlocks behavior you would otherwise build by hand: reader modes, print styles, browser autofill on properly labeled form fields, and native form validation.
Headings: the most common failure
Heading levels describe an outline, not a type scale. There should be one <h1> describing what the page is about, <h2> for its main sections, <h3> for subsections within those, and no skipped levels. The habit that breaks this is choosing a heading level because of how big it looks, which produces pages that jump from <h2> to <h4>, or use <h3> for a caption because the size suited the design. Size is a CSS decision. Level is a structural one.
The test is simple: read only the headings, in order. If that reads as a sensible outline of the page, the hierarchy is right. If it reads as a jumble, screen reader users navigating by heading get the same jumble.
Buttons, links, and clickable divs
The second most common failure is interactive elements built from the wrong thing. Use <a href> when the result is going somewhere: another page, another site, an anchor further down. Use <button> when the result is something happening: opening a menu, submitting a form, toggling a panel. Never attach a click handler to a <div> or a <span> and call it done, because it cannot be reached by keyboard, is not announced as interactive, and does not respond to Enter or Space.
A related rule applies to ARIA attributes. ARIA exists to describe behavior that HTML cannot express, and it is genuinely needed for some complex widgets. But adding role="button" to a div is strictly worse than using a button, because it promises behavior it does not deliver. Reach for the native element first and ARIA only when nothing native fits.
Forms
Every input needs a real <label> associated with it, not placeholder text standing in for one. Placeholders disappear as soon as someone types, are often too low-contrast to read, and are inconsistently announced. Related controls such as radio groups belong in a <fieldset> with a <legend>. Error messages should be associated with the field they describe rather than floating nearby. Correct form markup also improves conversion for everyone, because browser autofill works properly and tapping a label focuses its field.
Semantic HTML and structured data
Semantic HTML and schema markup answer different questions and neither replaces the other. Semantic elements describe the structure of the document: this is the main content, this is a heading, this is a list. Schema describes the meaning of the subject matter: this is a LocalBusiness, these are its opening hours, this is the author. A well-built page uses both, and they should agree with each other and with what the visitor sees.
Page builders and div soup
Markup quality is one of the clearest differences between a custom theme and a site assembled with a page builder. Builders wrap content in many layers of generic containers so that every spacing and alignment option can be exposed in a settings panel, and they let editors pick heading levels by appearance. The result is usually deeply nested, weakly structured markup with an inconsistent heading outline. It renders fine and reads poorly to everything that is not a browser, and the extra markup also weighs on Core Web Vitals. A custom theme can output exactly the elements a page needs, which is why we build them that way.
How to check your markup
Read the headings alone. Browser extensions and accessibility tools will list them as an outline. It should read like a table of contents.
Navigate with the keyboard. Tab through the page. Every interactive element should be reachable, visibly focused, and operable without a mouse.
Check the landmarks. Look for one <main>, a <nav>, a <header>, and a <footer> in the source.
Run an automated audit. Lighthouse and axe catch missing labels, poor contrast, empty links, and heading problems. They will not catch everything, but what they flag is real.
Inspect the accessibility tree. Browser developer tools show how the page is exposed to assistive technology, which is often more revealing than the HTML itself.
View the raw source. What the server sends is what non-rendering crawlers read.
Common mistakes
Heading levels chosen for size rather than structure, breaking the outline.
Clickable divs and spans that keyboard users cannot reach.
Placeholder text instead of labels on form fields.
Multiple <main> elements, or none at all.
Tables used for layout, or layout grids marked up as tables.
Decorative images with meaningless alt text, and meaningful images with none. See alt text.
Links labeled “click here”, which tell a screen reader user navigating by link nothing at all.
ARIA piled onto generic elements where a native element would have worked.
Where it fits
Semantic HTML is not a task to schedule; it is a standard to hold. It is built into every theme we write, checked as part of our technical SEO services, and it underpins both accessibility and responsive design, since well-structured content reflows sensibly at any screen size. If you are unsure what your site’s markup looks like underneath the design, book a discovery call and we will take a look.