HTML Headings
Headings are the labels that break a page into sections, the same way chapter titles and subheadings organize a book. HTML gives you six levels of heading elements, from <code>h1</code> down to <code>h6</code>, and using them correctly is one of the most important things you can do for readability, accessibility, and search engines. This lesson covers what headings are, how the browser renders and interprets them, and how to avoid the mistakes that trip up most beginners.
Overview / How it works
HTML provides six heading elements: <code>h1</code>, <code>h2</code>, <code>h3</code>, <code>h4</code>, <code>h5</code>, and <code>h6</code>. The number represents the heading’s rank: <code>h1</code> is the highest-level, most important heading (usually the title of the page or the main topic), and each increasing number represents a deeper, more specific subsection. There is no <code>h7</code> or beyond — six levels is the limit the HTML specification defines.
Semantically, headings are not just big bold text. They tell the browser, assistive technology, and search engines about the <strong>structure</strong> of your content. When the browser parses a heading element, it adds it to the DOM tree as an element node with its own tag name (<code>H1</code> through <code>H6</code>), and browsers maintain an internal notion of a <strong>document outline</strong> built from the nesting of these headings. Screen readers use this outline to let users jump directly between sections (“skip to next heading”), and search engines use it to understand which topics matter most on a page.
Visually, browsers apply a built-in default stylesheet (the <strong>user agent stylesheet</strong>) that renders headings in bold, with font sizes that shrink as the level increases, and with margin space above and below each one. But this default appearance is just a suggestion — it comes from CSS, not from any special rendering rule baked into the HTML itself. You should never choose a heading level because “it looks like the right size.” Sizing is a job for CSS; the heading level is a job for document structure. If an <code>h3</code> needs to be bigger, you style it with CSS — you don’t change it to an <code>h1</code> just to get bigger text.
Syntax
The general form of a heading is straightforward: an opening tag, text content, and a matching closing tag.
<h1>Page or article title</h1>
<h2>Major section</h2>
<h3>Subsection</h3>
| Element | Rank | Typical use |
|---|---|---|
h1 |
Highest | The page’s main title or topic (usually one per page) |
h2 |
2nd | Major sections of the page |
h3 |
3rd | Subsections within an h2 section |
h4 |
4th | Subsections within an h3 section |
h5 |
5th | Rarely used; deep nested subsections |
h6 |
Lowest | Rarely used; the deepest level of nesting |
All six elements accept the same global attributes as any other HTML element (such as id, class, and title), but they take no attributes of their own that are specific to headings.
Examples
Example 1: A simple heading hierarchy
<h1>Understanding Volcanoes</h1>
<h2>Types of Volcanoes</h2>
<h2>How Eruptions Happen</h2>
Result: The browser displays “Understanding Volcanoes” in large bold text at the top, followed by “Types of Volcanoes” in a somewhat smaller bold size, then “How Eruptions Happen” at that same second-level size below it. Each heading starts on its own line, since headings are block-level elements.
This is the simplest correct pattern: one <code>h1</code> for the page topic, and two <code>h2</code> elements marking sibling sections underneath it.
Example 2: A nested outline with subsections
<h1>Getting Started with Gardening</h1>
<h2>Choosing Your Plants</h2>
<h3>Vegetables</h3>
<h3>Flowers</h3>
<h2>Preparing the Soil</h2>
<h3>Testing pH Levels</h3>
<h3>Adding Compost</h3>
Result: The page renders a title (“Getting Started with Gardening”), followed by two major section headings (“Choosing Your Plants” and “Preparing the Soil”), each with two smaller subheadings nested beneath it. Visually the <code>h3</code> elements are noticeably smaller than the <code>h2</code> elements above them.
Notice the logical nesting: both “Vegetables” and “Flowers” belong under “Choosing Your Plants” because they follow that <code>h2</code> and rank one level below it. This is exactly the kind of structure a screen reader announces as “heading level 2, heading level 3, heading level 3, heading level 2…” letting a user understand the page’s shape without seeing it.
Example 3: Headings inside an article with supporting markup
<article>
<h1>How Bread Rises</h1>
<p>Yeast produces carbon dioxide gas as it feeds on sugars in the dough.</p>
<h2>The Role of Yeast</h2>
<p>Yeast is a living organism that ferments sugar into alcohol and CO₂.</p>
<h2>Kneading and Gluten</h2>
<p>Kneading develops gluten strands that trap the gas bubbles produced by yeast.</p>
</article>
Result: The browser renders a bold title, a paragraph of body text, then a smaller bold subheading, another paragraph, another subheading, and a final paragraph — each heading visually separating the article into digestible chunks.
This is closer to a realistic page: headings are mixed in with paragraphs and other content to break up a longer piece of writing, which is exactly their purpose.
How it works step by step
When the browser encounters a heading tag while parsing HTML, several things happen in sequence:
1. The parser reads the opening tag (for example <code><h2></code>) and creates a new element node in the DOM tree with the tag name <code>H2</code>.
2. Any text or inline elements between the opening and closing tags become child nodes of that heading node.
3. The closing tag (<code></h2></code>) tells the parser the heading element is complete, and parsing continues with the next sibling node.
4. During rendering, the browser’s default stylesheet applies a bold font weight, a specific font size relative to the level, and vertical margins, causing the heading to display on its own line as a block-level box.
5. Separately from visual rendering, the browser (and any assistive technology reading the page) builds a conceptual outline of the document by tracking heading levels in the order they appear, which is what lets a screen reader user navigate “by heading” and lets tools generate a table of contents automatically.
Common Mistakes
Mistake 1: Choosing a heading level based on how big you want the text
<h1>Welcome to My Blog</h1>
<h4>Latest Post</h4>
Here the author jumped from <code>h1</code> straight to <code>h4</code> simply because they liked how small an <code>h4</code> looked, skipping <code>h2</code> and <code>h3</code> entirely. This breaks the logical outline: assistive technology and outline-generating tools now see a confusing jump in rank with nothing in between. The fix is to use the heading level that reflects the section’s actual place in the hierarchy, and adjust the visual size separately with CSS.
<h1>Welcome to My Blog</h1>
<h2>Latest Post</h2>
Mistake 2: Using multiple h1 elements as generic “big text,” or skipping h1 altogether
<h1>Chapter One</h1>
<p>Some intro text.</p>
<h1>Chapter Two</h1>
<p>More text.</p>
While the HTML specification technically permits more than one <code>h1</code>, using several top-level headings for what are really sibling sub-sections confuses the page’s outline and makes it unclear what the page’s actual main topic is. In most page layouts you want a single <code>h1</code> that names the whole page, with <code>h2</code> used for each major section beneath it.
<h1>My Book</h1>
<h2>Chapter One</h2>
<p>Some intro text.</p>
<h2>Chapter Two</h2>
<p>More text.</p>
Mistake 3: Using a heading tag for something that isn’t actually a section heading
<h3>Click here to subscribe!</h3>
Wrapping a call-to-action or a caption in a heading tag just to make it bold and larger misuses the element’s semantic meaning; screen reader users navigating by heading will land on “Click here to subscribe!” expecting it to introduce a section of content, and be confused when it doesn’t. If you just want bold, larger text that isn’t a real section label, use <code><strong></code> or apply CSS to a <code><p></code>, not a heading element.
Best Practices
- Use exactly one <code>h1</code> per page to represent the page’s main topic or title.
- Never skip heading levels going down (don’t jump from <code>h2</code> to <code>h4</code>); nest one level at a time.
- Choose heading levels based on document structure, not on the font size you want — control appearance with CSS instead.
- Keep heading text short, descriptive, and unique enough that a reader skimming just the headings understands the page’s structure.
- Don’t use headings purely for visual emphasis on non-heading content; use <code><strong></code> or <code><em></code> instead.
- Write headings that make sense out of context, since search engines and assistive technology often surface them independently of surrounding paragraphs.
Practice Exercises
1. Write a heading hierarchy for a recipe page with a main title, two major sections (“Ingredients” and “Instructions”), and two subsections under “Ingredients” (“Produce” and “Pantry Items”). Use the correct heading levels for each.
2. Below is a broken hierarchy. Rewrite it so the levels nest correctly without skipping: <code><h1>My Portfolio</h1></code>, <code><h5>Projects</h5></code>, <code><h5>Contact</h5></code>.
3. Identify what’s wrong with using <code><h2>Read more → </h2></code> as a link button on a homepage, and describe what element you would use instead.
Summary
- HTML provides six heading levels, <code>h1</code> through <code>h6</code>, ranked from most to least important.
- Headings are semantic: they define the document’s outline, which browsers, search engines, and assistive technology all rely on.
- The browser’s default stylesheet renders headings bold with decreasing font sizes, but visual size should be controlled with CSS, not by picking a different heading level.
- Use one <code>h1</code> per page and never skip levels when nesting subsections.
- Never use a heading element purely for visual styling on content that isn’t actually a section label.
