Semantic HTML - <main>

Chapter 22 14 mins

Learning outcomes:

  1. What is <main>
  2. Examples of using <main>
  3. Things to note regarding <main>
  4. Further reading on <main>

What is <main>?

Most webpages, if not all of them, always have a portion denoting the main content of the page.

For example, consider a page showcasing a blog article. Typically, the main content of blog articles is the actual text of the article, possibly including the heading, the subheading, and the comments (if there are any).

Similarly, if we have a products list page on an online shopping store, its main section would be the entire section listing the products along with their price.

In short, it isn't impractical to talk of the main content of a webpage. And when we do so, that's essentially the perfect place to include the <main> element.

The <main> element is used to denote the main content of a webpage.

As simple as that.

As per our convention, quoting from the official HTML standard:

The main element represents the dominant contents of the document.

The <main> element is a handy thing to use in our webpages in order to make it crystal-clear as to which part of the page represents the main content.

In that sense, <main> should ideally contain (mostly) unique content. Things such as website headers, footers, navigational menus, etc. shouldn't really be part of <main>.

To consider an illustrative example, consider the following:

A blog article page.
A blog article page.

The illustration represents a blog article page. The blue-bordered box represents the main section of the page, which is basically just the contents of the article. This is the perfect candidate for <main>.

Also note the section right after the header: it is a means of promoting other articles and doesn't clearly constitute as part of the page's main content. Hence, it shouldn't be a part of <main>.

Shown below is another illustration labelling the main content of a webpage:

A products list page.
A products list page.

The blue-bordered box represents the section containing the filtering functionality for the products and the products themselves, which clearly constitutes as the main content of the webpage. This is perfect for <main>.

Again, notice how the blue-bordered box doesn't encapsulate the promotional slider after the header; that's simply because it isn't really a part of the page's main content.

Customarily, an HTML document contains no more than one <main> element.

As we shall learn later on in this chapter, it is possible to have more than one <main> element on a webpage, given that we abide by a certain criterion (we'll soon see what that is).

Let's now consider some code examples of <main>.

Examples of <main>

Let's borrow the idea shown in the illustration above and create a very basic blog article page, where we'll eventually leverage the <main> element.

We'll be emulating the following four sections in the given order: a header, a section promoting other articles, the main content, and finally a footer.

Here's the HTML of the page (obviously only showing the content of <body>):

<header style="background-color: pink">The header</header>

<aside style="background-color: lightgrey; padding: 10px">
   <p>Here are some other articles from our website.</p>
   <ul>
      <li><a href="#">Who invented HTML, when, and how?</a></li>
      <li><a href="#">What exactly is semantic HTML?</a></li>
      <li><a href="#">How to create a list in HTML?</a></li>
   </ul>
</aside>

<main> <h1>Writing your first HTML document</h1> <p>Written by <em>Alice</em>.</p> <p>It's very easy to write your first HTML document.</p> <p>...</p> </main>
<footer style="background-color: pink">The footer</footer>

Trivially, the header and footer are denoted using the <header> and <footer> elements, respectively. The background color applied to them make them look like separate sections on the page.

Similarly, the promotional section, as it's not related to the main content of the page, is denoted using <aside>. Once again, the styles given to <aside> try to make it look a bit different than the rest of the content.

The most important part in the code is the <main> element, representing the article's contents, which is essentially the main thing on the page.

Assume that the ... in the second <p> element above stand for a large number of paragraphs, that would otherwise exist in a real article.

Let's see the output produced:

Live Example

Nothing difficult to understand here, right?

Moving on, as we stated earlier, it's not just blog article pages that have main content; nearly every other webpage has it.

Let's consider another example of using <main> in a products listing page for an online store.

In the following code, we try to emulate a webpage showing a list of products:

<header style="background-color: pink">The header</header>

<main>
   <h1>Products</h1>
   <section>
      <p>This is the filter section.</p>
   </section>
   <section>
      <article>
         <h2>Wooden chair</h2>
         <p>$15.49 <s>$20.49</s></p>
         <p><a href="#">See details &rarr;</a></p>
      </article>
      <article>
         <h2>Glass vase</h2>
         <p>$4.99 <s>$5.99</s></p>
         <p><a href="#">See details &rarr;</a></p>
      </article>
   </section>
</main>

<footer style="background-color: pink">The footer</footer>

For brevity, we've only displayed two products. Each product consists of its name, followed by its price (new vs. the old one), followed by a link to take us to a dedicated page containing more info about the product.

As a quick side note, the text &rarr; inside the <a> elements above is an HTML entity, specifically to represent a rightwards arrow (hence the name).

Here's the output of the HTML:

Live Example

Obviously, because we don't have a lot of CSS to style this page, it doesn't resemble a typical product list page. But, nonetheless, the idea of the HTML is still, more or less, the same.

Whenever you're developing the HTML of a webpage, always give at least a minute of thought on which part of the webpage you feel represents the main content, then wrap that part with <main>.

This is a really good habit to develop at this stage. Believe it!

This is because using <main> to denote the main content of a webpage makes the webpage, obviously, semantically more meaningful and also more accessible for people relying upon screen readers to comprehend the webpage.

Things to note

As you'd agree, the <main> element isn't really hard to understand. There isn't really much confusion as to when exactly to use it.

But, there are certain technical things to keep in mind while using <main> to make sure that our HTML conforms to the standard and is, therefore, semantically valid.

Let's talk about them one-by-one.

Only one active <main> element

Restating the point mentioned above, an HTML document can have at most one <main> element. However, there is an exception to this.

We'll get to the exception in a moment, but for now, let's think about this rule.

Does it actually make sense?

Well, it sure does. We can't really have two pieces of main content on a webpage; the main content has to be one single piece. Consequently, we can't really have two <main> elements on a webpage.

Here's an example of bad HTML owing to two <main>s:

<main>
   <p>The first main section.</p>
</main>

<!-- Can't have another <main> element! -->
<main>
   <p>The second main section.</p>
</main>

Now, let's get to the exception.

Incorporating the exception with the rule stated above, it goes as follows: we can NOT have two or more <main> elements on a webpage unless they have the hidden attribute set on them.

The hidden attribute is a global attribute in HTML, that is, it could be set on any HTML element, not just <main>.

The hidden attribute serves to hide the underlying element from view completely (visually and even for screen readers).

Coming back to <main>, using hidden we can hide it from view.

But when could we need to have more than one <main> element on a webpage?

Well, honestly, it's rare. Such a need might only pop up when developing single-page applications, whereby multiple document views are presented in a single HTML document in separate <main> elements.

This is an advanced usage of HTML, which also requires a little knowledge of JavaScript, so if you want to, you can well ignore this usage of <main> for now.

Here's how to make the code above semantically valid:

<main>
   <p>The first main section.</p>
</main>

<!-- This works now, all thanks to `hidden`. -->
<main hidden>
   <p>The second main section.</p>
</main>

When we view the output, the second element isn't shown, as you can confirm below:

Live Example

Anyways, compactly, it can be said that we can't have more than one active <main> element on a webpage; the rest of the <main> elements must have hidden set on them.

<main> doesn't classify as sectioning content

As per the current HTML standard, there are only four elements in HTML that fall under the category of sectioning content: <article>, <section>, <aside> and <nav>.

And again as per the standard, sectioning content basically represents an element that defines the scope of <header> and <footer>.

Without anything to give scope to <header> and <footer>, as we learnt in the Semantic HTML — Headers and Footers chapter, both of these elements simply apply to the <body> element.

Talking about <main>, since it doesn't classify as sectioning content, there's no point of nesting <header> and <footer> inside <main> — they both, regardless, would NOT be taken as the header and footer of the <main> section but rather as the header and footer of the containing sectioning element.

Speaking of this in terms of code, the following isn't really sensible HTML, although not semantically invalid:

<main>
<header>The header</header> <!-- Shouldn't be here! --> <section> <h1>Learning HTML</h1> <p>Learning HTML is easy, right?</p> </section> </main>

We have nested <header> inside <main> which, as we just learnt above, is not technically rational.

It's better to take the <header> out of <main>, as follows:

<header>The header</header> <!-- Better now! --> <main> <section> <h1>Learning HTML</h1> <p>Learning HTML is easy, right?</p> </section> </main>

Now, the code is both valid and sensible.

<main> should be hierarchically correct

Returning to the HTML standard as before, which is always our primary point of reference, we see that it states that each <main> element in an HTML document should be hierarchically correct.

So what does this mean?

According to the standard, the <main> element can NOT come inside every other element; it can only be nested inside <html>, <body>, <div>, and <form> without an accessible name (which we shall explore later on in this course); this renders it to be hierarchically correct.

If <main> is nested inside any other element besides these, it won't count as being hierarchically correct which would ultimately make the HTML semantically invalid.

Henceforth, the following HTML is not ideal:

<article> <!-- <article> can't contain <main> --> <main> <h1>Learning HTML</h1> <p>Learning HTML is easy, right?</p> </main> </article>

The <main> element comes inside the <article> element, but because <main> can only come inside <html>, <body>, <div>, and <form>, this is semantically invalid.

Further reading

The <main> element, although pretty simple theoretically, has many aspects to cover in order to warrant a thorough understanding of it.

While we've tried our level best to cover as much information as we could've to help you understand what exactly is <main>, when to use it, and how to use it, there's still something to learn from some other amazing resources.

Below, we've linked to some of them. There all worth a read:

"I created Codeguage to save you from falling into the same learning conundrums that I fell into."

— Bilal Adnan, Founder of Codeguage