Lesson 4 of 20

HTML Headings

Six Levels, and What They Really Mean

HTML gives you six heading elements, <h1> down to <h6>. The number is not a size setting. It is a rank in an outline, exactly like the numbering in a project report: 1, then 1.1, then 1.1.1. An <h2> announces a major section of the page; an <h3> announces a subsection of whatever <h2> came before it.

Browsers do give each level a different default size, and that is where the confusion starts. Beginners pick <h3> because "h2 looked too big", which is a bit like choosing chapter numbers in your report based on how the font looked. The size is a default you will override with CSS in about five minutes. The rank is permanent information about your document that other software depends on.

Read the example below as an outline rather than as a set of font sizes. It describes a page about a college fest: one page title, three major sections, and two subsections inside one of them. Anyone could reconstruct the structure of that page from the headings alone, without reading a single paragraph — and that is exactly what a screen reader user does.

Example
<h1>Techfest 2026</h1>

<h2>Events</h2>

  <h3>Coding Contest</h3>
  <h3>Robotics Challenge</h3>

<h2>Registration</h2>

<h2>Contact the Organisers</h2>

<!--
  As an outline:
    1.   Techfest 2026
    1.1  Events
    1.1.1  Coding Contest
    1.1.2  Robotics Challenge
    1.2  Registration
    1.3  Contact the Organisers
-->

Why You Cannot Fake a Heading With CSS

It is tempting to write <p class="big-title">Events</p> and make it look like a heading with CSS. On your screen the result is identical. To every piece of software that is not showing pixels to a sighted user, the result is completely different — because CSS changes appearance and nothing else. A paragraph styled to look like a heading is still, as far as the document is concerned, an ordinary paragraph.

Here is what that costs, concretely. Screen readers such as NVDA and VoiceOver let a user press a single key to jump to the next heading, and can list every heading on a page so the user can pick one. That is how a blind student skims a page — the equivalent of your eye flicking down a page looking for bold text. A fake heading appears in none of those lists. To that user, your page has no structure at all; it is one long undifferentiated wall of text they must listen to from the top.

The same logic applies in reverse, and it is just as common a mistake. Do not use a heading element for text that is not a heading, just because you wanted it big and bold. A pull-quote, a product price, a large greeting on a landing page — none of those are section titles, and marking them as headings pollutes the outline with entries that lead nowhere. Use the correct element and let CSS handle the size.

Example
<!-- Wrong: looks like a heading, is not one -->
<p class="big-title">Events</p>
<div style="font-size: 32px; font-weight: bold;">Registration</div>

<!-- Right: real headings, styled with CSS -->
<h2>Events</h2>
<h2>Registration</h2>

/* In your stylesheet, size is entirely your choice */
h2 {
  font-size: 1.5rem;
  color: #333;
  margin-top: 2rem;
}
Notes
  • This is not only an accessibility matter. Search engines read your headings to work out what a page covers and how it is organised. A page whose headings are all fake paragraphs looks structureless to a crawler too.

Do Not Skip Levels

Heading levels should step down one at a time. Going from <h1> straight to <h3> is the equivalent of a report that jumps from chapter 1 to section 1.1.1 with no 1.1 in between — a reader following the structure is left wondering what they missed.

For a screen reader user this is more than untidy. When the software announces "heading level three" after "heading level one", the listener reasonably assumes there was a level two section they have skipped past, and may go back looking for it. Do that a few times on one page and the outline stops being trustworthy, which means it stops being useful.

Going back up is completely fine, and is in fact how you signal that a section has ended. After finishing the two <h3> subsections under Events, jumping back to <h2> for Registration is exactly right. The rule only constrains how far you may descend in one step, never how far you may climb.

If you find yourself wanting to skip a level, the usual cause is that you are choosing by size again. You wanted something smaller, so you reached for a bigger number. Choose the level that describes the structure, then set its size in CSS.

Example
<!-- Skipping a level: h1 straight to h3 -->
<h1>Techfest 2026</h1>
<h3>Coding Contest</h3>       <!-- where did h2 go? -->

<!-- Correct: one step down at a time -->
<h1>Techfest 2026</h1>
<h2>Events</h2>
<h3>Coding Contest</h3>
<h3>Robotics Challenge</h3>
<h2>Registration</h2>          <!-- climbing back up is fine -->
  • Descend one level at a time: h1 to h2, h2 to h3, never h1 to h3
  • Climbing back up any number of levels is normal and correct
  • Choose a level for what it means, then set the size you want in CSS
  • In practice you will rarely need <h5> or <h6>; if you do, your page may be trying to do too much

How Many h1 Elements Should a Page Have?

The safe and widely recommended answer is one. The <h1> is the title of the whole page — the answer to "what is this page about?" — and a document with one clear answer to that question is easier for everyone, human and machine, to understand.

You may have read that HTML5 introduced an "outline algorithm" under which each <section> restarts the heading hierarchy, so multiple <h1> elements would be interpreted as nested levels. That idea appeared in early drafts and was widely written about, but no browser and no screen reader ever implemented it, and it has since been removed from the specification. So a second <h1> inside a section is not silently demoted to a level two heading — it is just another level one heading, and your outline now has two top-level titles.

Practical guidance, then: put one <h1> near the top of each page, make it describe that page specifically, and let it usually match your <title> closely. A common beginner pattern is to make the site name the <h1> on every page — so twenty pages all announce "Robotics Club" as their heading and nothing distinguishes them. Put the site name in your header as ordinary text or a link, and give the <h1> to the actual page topic.

Notes
  • The <title> and the <h1> are different things doing similar jobs: <title> names the page from outside (tab, bookmark, search result), <h1> names it from inside. They need not be identical, but they should never contradict each other.

Writing Heading Text That Earns Its Place

Because headings are read out of context — in a screen reader's heading list, in a search result, in an automatically generated table of contents — each one has to make sense on its own. "More", "Details" and "Click here" fail that test completely. "Registration deadlines" and "How to reach the campus" pass it.

Keep headings short enough to scan and specific enough to be useful, and put the important words first. A visitor scanning your page reads the first two or three words of each heading and moves on, so "Fees and payment methods" works better than "Information regarding the fees and the methods of payment available". Do not put a full stop at the end of a heading; it is a label, not a sentence.

One last habit: check your outline before you call a page finished. Read only the headings, in order, from top to bottom. If that alone tells the story of the page, your structure is sound. If it reads like a random list, your structure needs work — and no amount of CSS will fix it.

  • Make every heading understandable when read on its own, out of context
  • Front-load the important words; readers scan the first few and move on
  • Keep them short — a heading longer than a line is usually a sentence in disguise
  • No full stop at the end of a heading
  • Do not repeat the same heading text twice on one page; it makes the outline useless for navigation
Notes
  • Developer Tools in most browsers can show you an accessibility tree, and free extensions can list every heading on a page in order. Reading that list is the fastest way to check whether your page really has the structure you think it has.
Ask AI