A semantically correct HTML tag informs the browser and the developer about its content. It also helps keyboards and assistive technologies to navigate through a website.
There are more than 100 HTML tags, but which ones are semantic and which are not?
Non-semantic elements: div and span, etc. Unlike semantic elements, these are not holding any extra information about their content.
Semantic elements: header, main, footer, article, img, p, h1, etc.
When you create a new HTML file, you have something like this:
<html>
<head>
...
</head>
<body>
...
</body>
</html>
I will focus on what's inside the body element and name only the most important tags.
The HTML tags can be separated into different groups and it helped me to understand the whole concept and I think this is the best way to explain it, so let's start.
Content sectioning or landmarks
The layout of the main page of my blog looks like this:
header and nav
In my <header>
, you can find the logo, which is a link and it leads to the main page and <nav>
element which contains the links to my other pages.
You can also put here some introduction about the page, a search bar, or other elements.
main
The <main>
element holds different content on each page. This holds the primary information of the current page or the main functionality of an application.
footer
The <footer>
tag creates a footer for a section or for the whole document. You can have multiple <footer>
elements in one page, which typically contains data, like: contact info to the author, copyrigt information, related links etc.
aside
You can also find the <aside>
on the right side of my page. It holds complementary content. If I remove it, nothing will be missing from the primary content. You can put here for example table of contents, related posts, etc.
section
Inside my <main>
element, you can find the <section>
tag. If there isn't a more specific HTML element for a part of your document, you can group related elements with this tag. This element should always have a heading.
h1 - h6
Heading elements: <h1>
<h2>
<h3>
<h4>
<h5>
and <h6>
, are the titles of the different sections. <h1>
is the highest level of the headings, and it is necessary to have one on each page but there should be only one per page. <h6>
is the lowest. If you run out of headings, there is another option: the 7th heading
The reason you should use landmarks is that screen readers and other assistive technologies can jump back and forth between these elements.
For example, all the pages have the same header with the same logo, the same navigation, but with a keyboard shortcut, you can jump over them and start with the content of the main tag.
Text content elements
These can help you organize the written content on your pages and give information about the content to search engines and screen readers.
P
<p>
stands for paragraph. In other words, a block of text. You will use it a lot for wrapping your text content with it.
ul, ol, li
<ul>
- unordered list, <ol>
- ordered list, <li>
- list elements of the two kind of lists. If you need to create a list you have to use them.
List items are wrapped in <ul>
, if the order is not important. It will put bullet points before each list item.
Choose <ol>
, if the order of your list items is important. By default, it will put a number before each item in ascending order.
Figure, figcaption, blockquote, cite
I will explain all of them with one example. Look at this block of code:
<figure>
<blockquote cite="https://www.htmhell.dev/24-a-placeholder-is-not-a-label/">
Every form input element needs a label.
</blockquote>
<figcaption>Manuel Matuzović, <cite>A placeholder is not a label - HTMHell</cite></figcaption>
</figure>
<figure>
and <figcaption>
go hand in hand
The <figure>
is a self-contained element optionally, but usually with a caption. This caption is the <figcaption>
element.
<blockquote>
is for quotations, where you want to indicate the author, the source, etc. (You can use the cite attribute on this tag to give the URL of the source of this quotation).
<cite>
element is holding the reference to a quoted content. Name of the author, title of the cited material, etc. and this is the first element of our next group, the inline text elements.
Inline text elements
You can wrap smaller parts of text like words, sentences, etc into different tags to define its style, meaning, or structure.
a
<a>
or anchor elements are links, which have a href attribute, which leads to other web pages, files, email addresses, phone numbers, or a location on the same page.
em
Use this element to emphasize any text content. Screen readers read this part of a text in a different way. Browsers render the content of this text in italic font style but don't use it only for styling.
strong
Use this element to mark content, which is more important than the rest of the text. Screen readers read this part of a text in a different way. Browsers render the content of this text in bold font style but don't use it only for styling.
q
A short inline quotation, which doesn't need an entire paragraph. (You can use the cite attribute on this tag to give the URL of the source of this quotation)
Image and multimedia
audio
audio is used to embed sound into your website.
img
img is used to embed an image into your website.
video
video is used to embed a video into your website.
Table content
I think an example is the easiest way to explain these elements:
table
<table>
creates a two-dimensional table with rows and columns
thead
<thead>
is a row or rows that define the column heading
th
<th>
is a single cell as a header of a group of cells. This group of cells can be a column or a row, and you have to define it by the scope attribute. The scope attribute can have the value of col or row.
tbody
<tbody>
wraps the main content of our table, which is usually between the thead and the tfoot elements.
tr
<tr>
defines a row of cells in a table.
td
<td>
stands for table data. This is a single cell that holds the information.
tfoot
This is a row at the end of the table, that summarizes its content.
Forms
form
<form>
element wraps the entire form that users can use to enter their data and submit it to the server.
fieldset
<fieldset>
groups related inputs in a form. Fieldsets need a caption and this caption is the legend element. For example, if you have a form with a shipping address and billing address, you can create two groups of inputs with the fieldset element.
legend
<legend>
element defines a caption for the fieldset.
input
Users can interact with <input>
elements to enter their data. There are many different kinds of input fields for different types of information, like text, color, file, etc.
label
Every <input>
field needs a caption and this caption is the <label>
element. You can't replace the <label>
tag with the placeholder attribute.
select and option
<select>
is a special kind of input field, with a dropdown menu. This dropdown menu contains <option>
tags.
textarea
Users can enter multiple lines of text in this field
button
The <button>
tag creates a clickable element, which looks like a button. It is used to submit forms.
Others
iframe
You can embed other HTML files into your website with the <iframe>
element. For example, you can insert a song from Spotify or a video from YouTube into your website.
picture
<picture>
has almost the same purpose as the <img>
element, but you can specify more sources and browsers decide, which is the best for them. If you want to use a new image format, like .avif, (which is not yet widely supported at the time I write this post), you should give the image in another format, like png with the <source>
tag.
source
With this element you can specify multiple sources for the <picture>
, the <audio>
, and <video>
elements, like this:
<picture>
<source srcset="image.png">
<source srcset="image.webp">
<img src="image.avif" alt="" />
</picture>
svg
I could describe it in a more complicated way, but <svg>
is mostly used to display a vector graphic image, that you can enlarge or reduce to any size without becoming pixelated.
Learn by playing
Paul Foster built this awesome memory game. Test yourself and beat your score tomorrow.
If you pick the correct elements, your code will be easier to read by other developers,
it will be easier for assistive technology users to use your website,
the search engines will rank your website higher (SEO).
Sometimes you should stop and think about whether there is a better HTML element than the one you want to use.
If you are missing something or find any inaccuracies, please let me know and I will add or correct it as soon as I can.
Originally posted on Use Less Divs
Top comments (9)
Not sure I understand what you mean by "a non-semantic tag"? Does that mean this is an optional tag to use?
It is a semantic element.
developer.mozilla.org/en-US/docs/G...
Thank you for pointing it out and sorry for the mistake. I fixed it. :)
Otherwise excellent article but
Do not use tags for styling. Semantically <ol> is for lists whose sequence cannot be changed without changing the information. Numbering - or not - is a default style.
You're absolutely right. Thank you for bringing it to my attention. :)
Cool stuff but about h1 "there should be only one per page".
It's no longer true since HTML5
That's interesting, thank you for bringing it to my attention. I did a quick search and you are right, but it was written in a few different sources, that best practice is still to use only one per page. Tomorrow I will dive deeper in this topic. :)
Well for instance it would make sense to me if in the layout you've shown the articles had an h1 for header as their title.
Also in today component oriented world we create component HTML structure independantly from where it's gonna end up. :)
EDIT: I was wrong
I don't understand. I thought it be body, Because I see main instead.