Skip to content

Semantic HTML

The conventional definition

Semantic HTML is the use of HTML markup to reinforce the semantics, or meaning, of the information in webpages and web applications rather than merely to define its presentation or look. Semantic HTML is processed by traditional web browsers as well as by many other user agents. CSS is used to suggest its presentation to human users. — Wikipedia

TLDR: DIV tags don't convey much meaning. Instead, use semantic elements that do. This makes your markup easier to read by other developers, and improves the SEO.

Semantic elements include:

  • address
  • article
  • aside
  • blockquote
  • cite
  • details
  • em
  • figcaption
  • figure
  • footer
  • h1, h2, h3, h4, h5, h6
  • header
  • main
  • mark
  • nav
  • section
  • string
  • summary
  • time

Read also:

You will note that these sites disagree as to the proper use of some of the semantic tags (eg section and article). Ultimately, you will have to use your judgment as to what is the most appropriate markup structure for the site.

Extended definition

Since we develop web apps rather than web sites, the semantic elements are not always much use to us when we want to display a concept from the app's business domain.

We therefore like to extend the definition of semantic HTML as being the markup structure that best conveys the data structure. This means that even if using DIV elements, their nesting should somehow reflect the structure of the data they display.

Best practices

Use semantic elements

Always use semantic elements where possible. These mainly have to do with the layout of the page.

Avoid styled elements

Some very old elements pre-date CSS and include style. They MUST be avoided. Use a proper semantic tag instead of use CSS.

Do not use Use instead
b strong
i em
br CSS padding/margin
hr CSS border

Do not use h* tags for styling

h* tags represent headers, ie titles of different sections. Browsers give them a special style by default (eg larger font, bold, etc.). Do not use them because you want to show some text in bold or in a larger font. For this, use CSS.

Nest h* tags properly

The h1 tag is used for the page title. There should only ever be 1 h1 tag on a page. Google will lower the ranking of page with no or multiple h1 tags.

Use h2 tags as the title/header for the top sections of the page, then h3 tags for the title of the sub-sections within each top section, then h4 tags for sub-sub-sections, etc.

<main>
  <h1>Page title</h1>

  <section>
    <h2>Section 1 title</h2>

    <section>
      <h3>Section 1.1 title</h3>
      ...
    </section>

    <section>
      <h3>Section 1.2 title</h3>
      ...
    </section>
  </section>

  <section>
    <h2>Section 2 title</h2>
    ...
  </section>

Avoid divs without a class attribute

A div element MUST always have a class attribute. A div without a class attribute is a sign of a bad markup structure and/or bad CSS. There is always a better way to do whatever you are trying to do.

Group and nest pieces of information logically

As an example, say you want to display a user's profile, including their address. The address should be wrapped inside an address element. This properly reflects the data structure of an Address object as a property of the User object.

<div class="user">
  ...
  <address>
  ...
  </address>
</div>

Use CSS for styling

Since HTML5, the presentation layer (styling) is the responsibility of CSS. Avoid attributes that imply styling (eg align or width). These are deprecated anyway and should not be used anymore.

Avoid inline CSS

Do not clutter your markup with style attributes. CSS should be defined as classes in a stylesheet; then set the appropriate class(es) on your HTML elements.