Well, not too long ago (12 years or so), there appeared a new HTML version. It contained lots of cool stuff. It introduced us to some new semantic elements as well.
Well, if you are anything like me, you will not blindly jump on everything new just because of how cool it sounds. Plus, there is media elements, storage, and lots of other exciting things that HTML5 brought us, so I was very busy.
However, after some time, I noticed that I was actually too busy and lazy. Those new elements could save me some work. More importantly, they can also save me some time on debugging code. At least, for me, less work is a good thing…
So, suddenly, I did not feel comfortable with the “I wrote it once, it still works, so why would I touch something that is not broken?” approach.
Want to know why? Well, I hope by the end of this article, you will understand why I find the elements so cool. Maybe, even agree with me?
What are the semantic HTML elements?
OK, so let’s talk about semantics first. Semantics simply means that an element has certain meaning in your code.
A <nav> element contains some navigation. A <button> is a button. An <article> can contain some meaningful text, like a blog post or news.
There is also <div>. I have nothing against <div>. I used plenty of them to build my small country. However, the <div> element has no semantics. It is a box.
So, for example, we can create a web page using this HTML:
<div class="page-header">...</div> <div class="main-menu">...</div> <div class="content">...</div> <div class="page-footer">...</div>
It works. It looks beautiful when we apply some CSS styles. There is nothing wrong with it.
However, we can also do the following:
<header>...</header> <nav aria-label="Main navigation">...</nav> <main>...</main> <footer>...</footer>
That will look the same when we apply CSS. The difference is that now the browser knows what kind of elements those are.
Also, we do not have to talk about the big pieces of HTML code only. The heading is a heading. List is a list. A date can go to <time> and a form field will tell the browser what type of input it expects.
You do not have to remember all of the HTML elements. I do not remember all of them. When I get a feeling that there is a better element for something, I check the MDN HTML element reference. Easier than trying to keep it in your head.
The less code – the better
Here is the part that made me change my mind about those new elements.
So, suppose we need a button to send some message. We can create it in the following way:
<div class="submit-button">Send message</div>
Then, we can add some CSS styles and make it look like a button. We can also add a click event listener and make it behave like a button. Great, right?
Well, not exactly.
Is it reachable using the keyboard? What will happen if we press Enter or Spacebar? Does it have a focus style? Can it be disabled? Will a screen reader understand that it is a button?
Well, we can fix all that. We can add tabindex, role, keyboard events, some more CSS styles, test and debug it. And, hopefully, we will end up with something that behaves like… a button.
However, there is an easier way to do that.
<button type="submit">Send message</button>
That is it. The browser already knows what this element is. It receives a keyboard focus. It behaves as expected. It can be disabled. It can submit the form. Screen readers understand it.
Sure, we may still need some CSS. The default button is not going to magically match our styles. Also, we may need some JavaScript to handle the button click event.
However, why spend time implement all of those boring features? Personally I rather delagate as much as possible to the browser.
It is also true for other HTML elements. For example, if we need to navigate to some other page, an <a> element already knows how to behave. <label> already knows how to connect to the form field. Certain type of <input> already has a better keyboard appearance on a smartphone.
Remember how we spent time building and adjusting accordions? HTML5 lets us use <details> and <summary>. These elements already known how to expand/collapse some content on a page.
Will it replace every custom control? No. However, if the standard HTML element already does what I need, I take the free help.
If you want to see the rest of the features provided by the browser, like <dialog>, <meter>, <datalist>, and a lot more, MDN has it all. It also has a nice semantic HTML introduction page. And yes, I love the little <button> element, its documentation is also worth a read. It is doing more than people think.
Not everybody uses pages the way I do
So, I spend most of the time looking at the websites on a computer screen. Usually, I also have a mouse with me. I can easily forget that not everybody uses a website in this way.
Some people use the keyboard to navigate the website. Some use screen readers. Some use voice commands. There are people who zoom the website and change its colors. And, of course, there are lots of different screens sizes.
The website is also visited by something that is not a person. Search engines read it. Browser extensions read it. Reader modes try to extract useful information from it.
Sure, they can guess what each of the <div> elements is supposed to do. Sometimes they guess correctly. I prefer not to make them guess.
So, the actual heading tells them, “I am a heading.” <nav> says, “Those links are for navigation.” <main> points to the main content of the page.
Assistive technology can convert such information into something called an accessibility tree. It is the representation of the page that emphasizes roles, names, and states rather than colors and positions.
I really like that I do not need to know which screen reader, browser, or device people will use. I only need to be honest with my content. The browser will do the rest.
Sure, this does not mean that I have to replace every <div> with something fancy. Not everything is an <article>. Not every group needs to be a <section>. Sometimes a box is a box.
If you want to know more about the structure of the webpage, W3C has a nice page structure tutorial. It explains headers, navigation, main content, and footers without making it a novel.
Accessible HTML without rewriting everything
OK, so semantic HTML will not make a website accessible just like this. I wish it were possible.
We can still forget to provide alternative text. We can still use colors that cannot be read by anybody. We can still make the form too complicated to use.
However, semantic HTML gives us a better starting point.
So, for example, I can look at a page and see big texts. It tells me where the one content ends and the other starts. A user with screen reader may see the list of headings and jump to the desired one.
However, if my “headings” are actually some styled <div> elements, they will not appear in the list of headings. They look like headings to me. To the browser, they are just boxes.
The same applies to buttons, form controls, links, and page regions. When I use the right element, a lot of useful information is automatically provided with it.
So, I can add more information to my page using ARIA attributes if needed. ARIA is cool, especially when there is some interface that HTML cannot describe properly. However, adding role="button" to a <div> does not give it all button behavior. I have to implement that part.
W3C also has more information about ARIA usage. My short version of it is this: if HTML has an element I need, I use it first.
Why should I write more code then?
How about search engines?
Sure, it can also help with search engines.
A search engine tries to understand what my page is about. Clear headings help to understand its structure. Descriptive links tell a search engine something about their destination. The text that actually exists in a webpage is easier to process than the text added with CSS or created in a canvas.
Did you know that Google recommends semantic HTML in its SEO guide for web developers?
So, does that mean that if I change several <div> elements to <section>, I will be on the top of Google tomorrow?
Unfortunately, no. I would love that too.
There are lots of things that search engines look for. Useful content is important. The titles, links, speed, and mobile optimization also matter.
Having said all that, I do not think of semantic HTML as an SEO trick. It is more like providing a cleaner copy of the page for the search engine to read. It may understand the messy version anyway. But I rather not make it work harder (afterall, I do want it to like mysite).
It helps the next developer
So, there is one more piece of equipment that has problems understanding my old code. Me.
I can return to a project after six months and not remember anything. I have to check Git, see my own name, and stop blaming somebody else.
Semantic HTML can also help here.
So, when I see <nav>, I know why those links are grouped together. I also know what <article>, <aside>, or <footer> elements tell me about the page structure.
Long stacks of nested <div> elements do not tell me anything. I have to analyze class names, CSS styles, and maybe stare at the screen for some time.
So, the elements with a meaning are like outdated comments. They will not explain everything. However, the first minutes in an old file will be less painful.
So, am I convinced?
Yes, but not because it is newer or shinier. These reasons are not convincing for me.
I use semantic HTML because it saves work. It provides me with the behavior that I do not have to write. It helps browsers, assistive technology, and search engines to understand the page better. It also makes my code a little easier to understand when I return back to it after some time.
I also use <div>. A lot. Sometimes there is no more meaningful element and that is exactly what <div> is for.
I just do not start using it immediately anymore.
Now, I stop and ask, “Does HTML have an element for this?” If it does, it will probably save me some code. And a bug as well.
So, if you are curious what your markup says, you can check it with the Nu HTML Checker. You can also check the accessibility tree in your browser’s developer tools. It is interesting to compare the page on the screen and the page the browser understands.
And this is actually my opinion on semantic HTML. It is not about using fancy tags because somebody told me they are better.
It is about letting HTML to do the job for me. After all, Less code. Less bugs. Less work. Opps, I meant more time to work on other things 😉