HTML abuse guide

Much has been said about the abuse of HTML tables. And if you're reading this, you probably have an opinion about that too. However, tables are not the only HTML element that can be abused! Therefore I've put together this document in which I collect some other examples of element abuse that I've encountered in the wild.

Hope it's of some use.

Bad uses for elements

If you want to avoid abusing elements, the first (and one of the easier) things you can do is remember not to call them tags. They hate that. They're elements! Sure there's such a thing as a tag, but an element is so much more than a tag. Tags are nothing but delimiters for elements, and most self respecting elements therefore have two tags: one at the start and one at the end. Remember that.

<a> as anchor

In the old days, the <a> element had two uses: as a link, and as an anchor. In fact, the name <a> is short for anchor. However, its use as anchor has been deprecated; you can use any element as an anchor now by giving it an id. So <h3><a name="part2"></a>Part 2</h3> is out. <h3 id="part2">Part 2</h3> is the way to go!

<b>

<b> is not even properly deprecated, did you know that? However, to emphasize something, <strong> is better. If you don't want to emphasize, but just want to change how the text looks, you should use CSS.
If it helps, imagine your text being spoken out loud. The things you can hear, those are the things that should be in the markup of your document. If you can't hear them, they shouldn't be. If a word should be emphasised, you can put that in the markup. If a line is an introductory title to the paragraph that follows, that should be in the markup. But words that just happen to be bold or coloured, just like borders, decorations and so on have no effect on how the text is spoken and should be part of the stylesheet, not part of the markup.
Note that HTML5 has changed the meaning of this element to something resembling <mark>, but I'm not sure about the usefulness of such a move. I mean, then what do we have <mark> for?

<base>

Better not use this one. First of all, not all browsers agree that it is an void element. That is, some browsers want you to write <base></base>. And it changes the behaviour of links like href="#fragment" too much.

<big>

Purely for giving a text a different size, this element does not have any meaning. If you want to give a text a different size, think of a reason you might want to, give the element a class name that is the reason and put CSS for the new size in the stylesheet.
I also sometimes see nested <big>s in some documents, meant to make text even larger. Now if you're thinking of replacing those by nested <span>s all with the same style, don't. Just don't.

<blink>

This is not just abusing HTML, this is abusing the user. Get out of here.
Oh, have you heard the news? There are no longer any browsers that support this, so the joke's on you.

<blockquote> for indenting

<blockquote> is a means for quoting a text, and although the default display is with wide left and right margins (not in all browsers though), indenting is not the primary meaning for this often abused element. Don't do this! It's a quotation, not an indentation! Don't use <blockquote> for indenting, ever! Don't ever even think of using a <blockquote> for anything but quoting a block of text, ever!
Except in e-mail.

<br> for blank space

<br>
<br>
<br>
<br>

That is abuse! Unless you mean 4 lines of text that happen to have no content, don't do this. Put a top margin on the next element, or a bottom margin on the previous one. Or if you do need to put a separator in the text, make it one element, maybe a <hr> with the proper styling or a <div> with a specific height.
(And if you think that's abuse too, you're right, but it's only 14 as bad!)

<div> as an inline element

All too often I see things like <div> with a style of display:inline, that make me want to cry. <div>s are block elements! That's what they do! They don't have any other features, no semantic meaning, nothing. All they can do is be a block. And then even that is taken away from them.
So don't do this. If you want to have an inline element, use a <span>. Please.

<div> for headers, footers, sections, main blocks, navigation blocks, etc.

I'm on the fence about this one. It goes without saying that using the semantic elements is better, that div should only be used in cases where none of these semantic elements would work.
But that's the problem: what about browsers where those elements don't work?
For instance, the relatively new <main> element wasn't recognised by browsers until 2013. If you use <main> in Firefox 20, Chrome 25 or Opera 15, the result looks different than if you use <div id="main">. Unless you take measures like adding main{display:block} to your CSS and document.createElement('main'); to your JavaScript.
So, maybe we can forgive the use of <div> in these cases for now.

<em> for italic text

<em> is meant for emphasising text. However, people are using it simply to make text italic. And unless you really want to make the text stand out, that is not what this element is for! In that case, even <i> would be better, since <i> doesn't have a meaning. (Many people believe that <em> is always better than <i>, with no other reasoning than "<i> is bad and <em> is good". Poor misguided souls.)
But of course, to simply change the style of a piece of text without changing the semantics, what you really should use is CSS.

<font>

The normal use of this element has been deprecated. Use styles instead.
If changing the font of a word doesn't change the meaning, e.g. if you just want to give a word a different colour and nothing else, use a <span>. If the change in font does have a reason - e.g. you want to mark the word, have it stand out - use a <mark>.
However, the real abuse doesn't come from just having <font> in your HTML. The real abuse is using <font> with no face and color attributes, but with a style attribute!
What possesses people to do this? How come that people who are knowledgeable enough to have heard about style attributes, don't realise that <font> should not be used any more? I don't get it.

Early HTML5 drafts undeprecated <font>, but fortunately it was redeprecated later.

<h1> .. <h6> to change text size

If you have a line of text that you simply want to change the size of, use CSS.
<h1> through <h6> are headers, which provide the title to the document (in the case of <h1>) or to subsections of the document (for <h2> through <h6>). They are not meant merely to change the font size. In fact, the font size is almost inconsequential; if you change all their sizes to 1em using a stylesheet, they still function as headers!

Another issue I frequently encounter is multiple <h1>s. This header is not meant to give titles to random blocks of text; the <h1>'s sole purpose is to provide a title to the entire page or section. So there should be only one!
This restriction does not apply to <h2> through <h2>; those can be used multiple times in the same section for block headers.

<i> for italic

Although <i> was never really deprecated, it is discouraged in favour of <em> for emphasis, or CSS for plain italic.
Some sources reason you can use <i> for things like titles of books or names of publications or things like that, like "<i>Dune<i> by Frank Herbert", but I can't really recommend that. If you want to show that you mention something by name, use <var>, <dfn> or <cite> or even <span> with a descriptive class.

<i> for icons

You know that <i> doesn't really mean "icon", right? Yes you do.
The semantic meaning of <i> is not "here is an icon", it's "here's some italic text". Or to put it another way, there is no such thing as an italic icon.

<img> for backgrounds

<img> elements are meant to insert pictures in your content. If the picture is part of what you have to say, if your text is incomplete without it, use <img>. But they are not meant to add pictures as decoration, borders, backgrounds, separators etc. For that, use CSS.
Another way of going about this is if you can't think of anything to put in the alt attribute, maybe you shouldn't be using img either

<img alt...>

This practice has become less widespread, but I still see people do it: using the alt attribute in an <img> as if it were the title attribute. Well, those are different things! A title is meant to convey extra information about the visible picture. The alt is meant to replace the visible picture! So don't mix those up. Yes, we all know that one particular browser, at least in Quirks mode, shows the content of the alt attribute in a tooltip if there is no title attribute, but that doesn't mean you can mix them up.

<label> for just text

People often use <label> to, well, label things. Captions to images, subtexts, introductory notes etc. This will not do. As with all semantic elements, <label>s have one specific function, and that is as labels for controls. Using them elsewhere, even if the validator does not complain, should be avoided!

<section> as simply a block

<section>s are meant to be stand-alone parts of the document. However, I see lots of pages where sections are used simply as blocks, in places where <div>s would be more appropriate. This is probably caused by people misreading the guidelines about proper use of HTML5 elements and how elements with semantic meanings should be preferred over unsemantic elements, without giving any thought to the actual meaning.

<small>

Is purely a presentational element. If you want to give something a different font size, try to think of a reason for doing so and then give the element that reason as a class name and put the new size in the stylesheet.
This way, you force yourself to think about the structure of your document. A reason such as "I just want this smaller, OK" is not very good; "unimportant" is much better. Works better as a class name too.

In HTML5, this element is not deprecated any more, but its definition has changed: it now has the meaning "small print". But as there is no symmetry with the corresponding <big>, I cannot recommend this use wholeheartedly.

<span> as a block element

All too often I see things like a <span> with a style of display:block, which make me cringe. If you want a block, then why don't you use a block element! <div> is available and better suited for this purpose, and you don't need to give it a style explicitly!

<strong>

Traditionally this meant strong emphasis; the equivalent of raising your voice. Nowadays it means a phrase of strong importance, that is meant to catch the user's attention.
However, people are still using it simply to make text bold. And unless you really want to make the text stand out, that is not what this element is for! In that case, even <b> would be better, since <b> doesn't have a meaning. (Many people believe that <strong> is always better than <b>, with no other reasoning than "<b> is bad and <strong> is good". Poor misguided souls.)
But of course, to simply change the style of a piece of text without changing the semantics, what you really should use is CSS.

<table> for lists

You can read all over the web how you shouldn't use tables. This, however, is a misconception that has no basis in reality. The official recommendation is that you shouldn't use tables purely for layout purposes. You can use tables, however, for laying out data and things in any meaningful manner.
But if you have a list of items, even if it has multiple columns, use a real list.

<table> for backgrounds

In the bad old days before CSS, a table was the only way to give a background to your text, because only tables and table cells supported the background attribute. However, these days (only since 1996) it's no longer reserved for tables alone; you can use the CSS background property on all elements.
The odd thing is that these days I still often see tables used for no other purpose than putting backgrounds in, but people now use tables with inline styles instead of those attributes! Not sure about the reasoning behind that.

<table> for columns

Use the CSS property columns. Or use floating blocks. Or absolute positioned blocks. Or inline-blocks. Or cleverly placed negative margins. Or flexboxes. Or if you can't get any of these to work, display:table.

<table> for vertical centering

By now, you should get the point: to achieve certain display features, use CSS, not tables. Even if you know that a table can do this. Don't use tables to perform cheap tricks; that's not their purpose in life.

<tt>

This is purely presentational. Depending on what you want to show, you can use <code>, <samp>, <kbd>, <pre> or a style.

Note that on some browsers, this element does not necessarily look the same as giving an element font-family:monospace. If the way it comes out is very important, make sure you write out the styles you need explicitly.

<u>

Presentational. You should replace this with a style, but when you do so, make sure you're not making the text look like a link. People are used to underlined words being links.
Note that HTML5 has changed the meaning of this element to something resembling <mark>, but I'm not sure about the usefulness of such a move.

And finally, making up your own HTML elements

Yes, I actually see this: people creating their own HTML elements. Why they do this, I'll never know. If confronted with their errors, they mumble something about having a good reason, for instance that tables are evil and that you should avoid them at all costs and that they therefore invented new tag names such as <grid>, <row> and <cell>, and they think they're clever and they're oh so smug about it and they think that as long they're not using tables, they can break all the rules in the book, because, you know, who cares for the rules, as long as you avoid tables.
One reason why inventing new elements is bad is because those elements may get officially defined later on. For example, if you used an element named picture, you could get away with that a few years ago, but your webpage will look different now that it did then. Had you stuck by the rules, that wouldn't have happened.