Headings
How to use heading elements to create a meaningful document outline that helps all users navigate your content.
A heading in HTML is not just large, bold text. It is a structural marker. Heading elements tell the browser, search engines, and assistive technology what the page is about and how its content is organised.
This distinction matters the moment you stop being the only person reading your page.
What headings actually do
Browsers display headings with large, bold text by default. That visual presentation is a side effect. The real job of a heading is to contribute to the document outline.
A screen reader (software that reads the page aloud for users who are blind or have low vision) gives users the ability to pull up a list of every heading on the page. This list works like a table of contents. Users can scan it to find the section they need and jump directly to it, without listening to the entire page from start to finish.
If your headings are chosen for their visual size rather than their structural role, that list is meaningless. A page full of <h4> elements because the default <h4> style looks right in a sidebar is a page where no user can navigate by structure.
Here is what the heading list for a well-structured article looks like:
Introduction to CSS Grid (h1)
What is CSS Grid? (h2)
Rows and columns (h3)
Grid lines (h3)
Setting up a grid container (h2)
The grid-template property (h3)
Placing items on the grid (h2)And here is what a heading list looks like when headings are chosen by visual size:
Introduction to CSS Grid (h1)
What is CSS Grid? (h4)
Rows and columns (h4)
Grid lines (h2)
Setting up a grid container (h3)
Placing items on the grid (h4)The second version tells a screen reader user nothing about how the content is organised. The levels jump around with no relationship to the actual nesting of ideas.
The six heading levels
HTML provides six heading elements: <h1> through <h6>. Each level represents a tier in the document outline. <h1> is the top level. <h6> is the most deeply nested.
<h1>Web Development Fundamentals</h1>
<h2>HTML Basics</h2>
<h3>Document Structure</h3>
<h4>The DOCTYPE Declaration</h4>
<h5>Why DOCTYPE matters in old browsers</h5>
<h6>Internet Explorer compatibility notes</h6>In practice, most pages use <h1> through <h3>. Going deeper than <h4> is a signal that your content might be too nested and could benefit from reorganisation.
One h1 per page
Every page should have exactly one <h1>. It describes what the page is about. Think of it as the title of a document.
<!-- Wrong: two h1 elements -->
<h1>SAE Academy</h1>
<p>A coding school for beginners.</p>
<h1>Getting Started with HTML</h1>
<p>HTML stands for HyperText Markup Language...</p>A screen reader user who encounters two <h1> elements sees a document with two equally-weighted top-level topics. That creates the impression of a document that cannot decide what it is about.
The correct approach is to use the page's main topic as the <h1>, and treat the site name as part of the <title> element in the <head> or as a logo or visually styled element that is not a heading at all.
<!-- Correct: one h1 for the page's main topic -->
<header>
<p>SAE Academy</p><!-- site name as plain text, styled with CSS -->
</header>
<main>
<h1>Getting Started with HTML</h1>
<p>HTML stands for HyperText Markup Language...</p>
</main>Why this rule exists
Search engines use the <h1> to understand the page's primary topic. Multiple <h1> elements dilute that signal. More importantly, assistive technology uses the single <h1> as the entry point for navigating a page. When there are two, neither is authoritative.
Do not skip heading levels
Heading levels must descend one step at a time. After an <h1>, the next heading must be an <h2>. After an <h2>, the next can be an <h2> (same level, new section) or an <h3> (one level deeper). Jumping from <h1> directly to <h3> skips a level.
<!-- Wrong: h2 is skipped -->
<h1>Building a To-Do App</h1>
<h3>Setting Up Your Project</h3>
<h3>Writing the HTML</h3><!-- Correct: levels descend in order -->
<h1>Building a To-Do App</h1>
<h2>Setting Up Your Project</h2>
<h2>Writing the HTML</h2>
<h3>The input field</h3>
<h3>The task list</h3>Browsers render both visually in a way that might look acceptable. The difference only becomes visible when you look at the document outline or use a screen reader. A screen reader user navigating with the heading list expects <h3> to mean "a subsection of the most recent <h2>." When <h2> does not exist, that expectation breaks.
An accessibility auditing tool (like the axe browser extension) will flag skipped heading levels as a violation.
Never choose a heading level for its visual size
The most common mistake beginners make with headings is treating them as font size controls. The default browser stylesheet makes <h1> large and <h6> small, so it is tempting to reach for <h4> when you want a smaller heading-like appearance.
<!-- Wrong: h4 chosen because it looks small, not because it is a sub-sub-subsection -->
<main>
<h1>Dashboard</h1>
<aside>
<h4>Recent Activity</h4><!-- visually fits, structurally wrong -->
<h4>Quick Links</h4>
</aside>
</main>This breaks the document outline. A screen reader user who navigates by heading now sees <h4> elements with no <h2> or <h3> parents, which makes no structural sense.
The fix is to use the correct heading level and control the size with CSS.
<!-- Correct: h2 for the correct structure, CSS handles the visual size -->
<main>
<h1>Dashboard</h1>
<aside>
<h2 class="sidebar-heading">Recent Activity</h2>
<h2 class="sidebar-heading">Quick Links</h2>
</aside>
</main>.sidebar-heading {
font-size: 0.875rem;
font-weight: 600;
text-transform: uppercase;
}The visual result is identical to the broken version. The document outline is now correct.
Decorative text that is not a heading
Sometimes you want large, styled text that is not actually a section heading. A hero banner with a big marketing phrase, a pull quote, or a stylistic label are not headings. They do not introduce sections of content.
Use a <p> or <span> styled with CSS instead of a heading element.
<!-- Wrong: not actually a heading -->
<h2>Start building today.</h2><!-- marketing tagline, not a section -->
<!-- Correct: styled with CSS, not a heading element -->
<p class="tagline">Start building today.</p>If you make it a heading, it appears in the document outline as a structural section. That is misleading.
Heading hierarchy across the whole page
The heading hierarchy applies to the entire page, not just individual components. An article's internal headings nest inside the page's heading structure.
A page with a <h1> for the page title and an article component that starts its own internal hierarchy must continue from where the page left off.
<!-- Page structure -->
<h1>Blog</h1><!-- page title -->
<article>
<h2>Introduction to Flexbox</h2><!-- article title: h2, not h1 -->
<h3>The flex container</h3>
<h3>Flex items</h3>
</article>
<article>
<h2>CSS Grid vs Flexbox</h2><!-- next article: also h2 -->
<h3>When to use Grid</h3>
</article>If each article started its own <h1>, the page would have multiple top-level headings and the outline would be broken.
Common mistakes
Multiple h1 elements. One <h1> per page. The site name is not a heading. Use a logo, a styled <p>, or an <a> inside a <header>.
Skipping heading levels for visual sizing. If you want smaller text, use CSS. Use the heading level that reflects the document structure.
Using headings for text that is not a heading. A pull quote, a tagline, or a sidebar label is not a heading. Use a <p> or <span> and style it.
Forgetting that article headings nest inside page headings. If your page has an <h1> for the page title, each article should start at <h2>, not <h1>.
Choosing <h6> because you need something very small. Six levels of nesting is almost never the right structural answer. If you are going this deep, the content needs reorganisation, not a deeper heading level.
Exercise
Build a blog post page with a correct heading hierarchy. The page has a site header, a main article, and sections within the article. Read the outline top-to-bottom after you are done and check that it makes sense as a table of contents.
When you are done, read every heading from top to bottom. Ask yourself: does this read like a table of contents? Does each <h3> clearly belong under the <h2> above it?