6 HTML Bad Coding Habits

melnik909 profile image Stas Melnikov ・3 min read

We can found bad practices of almost any programming language in Google. But I can't say that about HTML. I haven't been able to find really important bad examples. So I'll tell about 6 bad coding habits that you can use.

The main element is missing

Every web-page has main content but developers forget about it somehow. They don't use the main element. So assistive technologies think web-pages don't has main content.

Don't do it

<div class="main-content">
  <!-- main content is here -->

You can use it instead

<main class="main-content">
  <!-- main content is here -->

The h1-h6 elements not for headings

The h1-h6 elements help assistive technologies detect headings on the web-page. Also users of screen readers can use it to navigate on the web-page faster. If the h1-h6 is used not for headings then that prevents people. So it is really bad practice

Don't do it

<h2>iPhone 11</h2>
<h3>Just the right amount of everything.</h3>

You can use it instead

<span>iPhone 11</span>
<span>Just the right amount of everything.</span>

The alt attribute has incorrect values

The alt attribute can be very useful if developers use it correctly. Unfortunately, a lot of them don't try to describe images so that people with visual disabilities could understand what's on the picture.

Don't do it

<img src="picture.jpg" alt="adidas Originals Superstar">

You can use it instead

<img src="picture.jpg" alt="adidas Originals Superstar Bold platform trainers in black and white">

The div element to markup text

That is my top mistake that I see on large number of websites. In the spec there is following description of the div element:

The div element has no special meaning at all. It represents its children. It can be used with the class, lang, and title attributes to mark up semantics common to a group of consecutive elements.

Contexts in which this element can be used: where flow content is expected and as a child of a dl element.

The flow content is most elements that are used in the body of documents and applications. That isn't text.

The span element is the best element to markup text without special meaning. It has following description in the spec:

The span element doesn't mean anything on its own, but can be useful when used together with the global attributes, e.g. class, lang, or dir. It represents its children.

Contexts in which this element can be used: where phrasing content is expected.

Phrasing content is the text of the document, as well as elements that mark up that text at the intra-paragraph level.

Don't do it

<div>some text</div>

You can use it instead

<span>some text</span>

Empty elements

Empty HTML elements don't affect accessibility and user experience. But when I see them I think, "Why developers don't use CSS". In the most cases empty HTML elements can be replaced by the CSS pseudo-elements ::before and ::after.

Don't do it

<h2 class="heading">
  <span class="heading-text">The section heading</span>
  <span class="heading-line"></span>
.heading {
  position: relative;
  padding-bottom: 1rem;

.heading-line {
  width: 3rem;
  height: 3px;
  background-color: purple;
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);

You can use it instead

<h2 class="heading">The section heading</h2>
.heading {
  position: relative;
  padding-bottom: 1rem;

.heading::after {
  content: "";
  width: 3rem;
  height: 3px;
  background-color: purple;
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);

Icon fonts

The icon font is really problem because while icon font isn't loaded users see empty squares instead of icons. So SVG is the best thing in 2020.

Don't do it

<i class="fal fa-quidditch"></i>

You can use it instead

<svg viewBox="0 0 56 56">
  <path d="..." />

P.S. This post was written with the support of my patrons: Ashlea Gable, Tatiana Ten, Claire Collins, Ben Rinehart.

Posted on by:

melnik909 profile

Stas Melnikov


I help people to learn new things about HTML and CSS on Patreon platform


Editor guide

Great content! The only part I am confused by is in the h1-h6 section you have the h# tags as "Don't Use" and span tags as "Use instead". Are they flipped or am I just misunderstanding what you meant in the preceding paragraph?


If the h1-h6 is used not for headings then that prevents people.

In other words, the h* only for headings. If you read text in my example you hardly what section is. But if this text was heading you could do it. You would understand content that is related with the heading.


I think what he meant is that we shouldn't use h tags for things that are not intended to be wrapped in h tags (like a span, for example).


Same question here


Headings should be used to define hierarchy in your webpage, and should never be used for styling purposes.


People (especially those that use WordPress and themes) will often put whole paragraphs of text inside of a h* because their theme doesn't use classes to manipulate CSS properties, but relies on attaching those CSS properties via the h* selectors.

Meaning, for example that h1 is big and blue, while h3 is a bit smaller and yellow. So someone comes along and says "this bit of text [imagine a long sentance]" needs to be a bit larger and yellow, and they will then proceed to put that very long text (which obviously is not a heading) inside a h3 tag, just for the looks.


It's good to publish your recommendations on improving HTML - thank you :-)

There is one thing I disagree with though - and that is the use of <span></span> for text - as I don't think that this has a proper semantic meaning.

In my opinion, you should use <p>A complete block of text, also known as a sentence.</p> as the paragraph-tag has semantic meaning for text. The main issue is that many webdevs hate the default browser spacing around paragraphs. (hint: use CSS!)

For me, <span></span> is for a text fragment in some unusual non-semantic context. For example: <p>I was walking down the hill, and my feet hit a <span style='position:relative;top:-0.2em'>bump</span> that caused me to stumble.</p>. In this example, the complete sentence is enclosed in paragraph-tags showing that it make a semantic whole, and the span-tag is just used for visual effect (no semantic meaning).

One of the historic issues with HTML is the over-focus on appearance, and the low priority given to semantics.

Just my $0.02 - thank you for the article, it is good to improve the world's HTML :-)


A text fragment hasn't limits on words. Thus we can use the span for any text. The p is paragraph. The problem is we don't have single opinion what a paragraph is. I think a paragraph is sequence of text blocks that are united by one meaning.


I mostly agree with you.

I think there is an even higher zeroth law for HTML goodness, which is something like:

Always use accurate SEMANTIC HTML wherever possible

This article explains it better than I can: w3schools.com/html/html5_semantic_...

When we do our HTML code reviews, we count the non-semantic tags like <span> - they are are considered a code-smell - that indicates something might be going wrong...

Semantic-HTML is good for the soul. Namaste.

The span is the same semantic element like other

No its not :-)

Check the w3schools intro to semantics - right at the top, around the 3rd line...

Examples of non-semantic elements: <div> and <span> - Tells nothing about its content.

is a non-semantic element.

The fact that you say the span isn't semantic element is the span is semantic element because if it don't have semantic (meaning) you can't do it. And just read specs


I would like to point that on the first example you must use IDs, as I assume it's not intended to be two main-contents on the same view.

<main id="main-content">
  <!-- main content is here -->

Now you can scope your CSS/SCSS and your JS inside #main-content instead seeking across all DOM elements in search of the main-content class usage.

For example using ID you'll ensure the interpreter stops when finding the element with this ID, making it much more efficient than using unscoped classes.

That's why people using invalid html struggles like on this SO question .

Best regards


The WHATWG spec allows to use a few main elements on one page. But only one of them must be visible. So if you think that you can use IDs only because the main is an unique element is a mistake. Also you can find enough articles why using IDs in CSS is a not good idea.

All the best


More or less the same amount of articles about why articles telling people not to use IDs are opinionated and a nonsense.
IDs have a reason to be and must be used for this reason. This includes scoping CSS and JavaScript, which increases your site performance.
You can have more than a main element, of course (which is kinda contradictory semantically) but this doesn't lead you for not adding a proper id to each one.
Oh and... Spoiler alert: standards on web are not standard, welcome to web dev world!
So devs must do what it's intended on an engineering: create what is better for the purpose with the knowledge on how things work, not blind following the opinion or reasons for some statements if it doesn't fit on a context or if it evolved faster than the "standard" did (which is tiredly common on IT development, specially front end). It's science after all, if you want to follow the rules without digging deeper and being comfortable with that there are other non-scientific careers out there.

In a single document, rather than multiple <main></main> elements, wouldn't it make more semantic sense to use multiple <article></article> blocks? That's what I tend to do when there is not one <main>...

Yes, of course. Remember that articles are meant to be children of a . You can also use depending on context (not all content fits well semantically inside an article).


These are really great points!

What do you think about the redundancy of
<main class='main-content'>? That could probably be more meaningful - or left off completely - if no meaning. Also, sometimes those things in your heading examples ARE headings / and should be written like that.

Very happy to see someone fighting the evil:
<i class="fal fa-quidditch"></i>


Thank you.

"What do you think about the redundancy of <main class='main-content'>? "

That's just example. The "content" is a good class name also.

"Also, sometimes those things in your heading examples ARE headings / and should be written like that."

That is problem that developers use headings where they don't exist. If you read text in my example you hardly what section is. But if this text was heading you could do it. You would understand content that is related with the heading.


Great post. Here are two more issues that I see often:

  1. If you have to use Font Awesome or any other font icon, avoid the <i> element, which is meant to represent a range of text that is set off from the normal text for some reason, such as idiomatic text, technical terms, taxonomical designations, among others. For that reason, it fails on the WCAG validation. Instead, use <span>, which is semantically neutral and therefore the most appropriate tag for the occasion.
  2. Avoid using <a> elements with empty hrefs as menu togglers and use <button> instead.

Great points!
Lately, I've been thinking in this kind of things (I even just posted some thoughts in my blog) and I think we as developers not always use HTML as we should or as we use other languages, for me, HTML is about describing your content and use the appropriate elements...


I don't use FontAwesome anymore to reduce bloated load time.


What are the alternatives you're currently using?


Nice article! I've a question about semantically use classes to define unique wrappers on the layout.
I assume you will have only a "main-content" per view so why don't use an id instead on a global class?
You can use the same id on different views but nor repeating ids on the same, so you can attach the styling you want for being common on #main-content instead making it global using a class.
Ids Are useful to scope JavaScript and CSS being not applicable on a different scope and making it to run efficiently (and faster btw).


There is typo in img tag
You forgot to add quotes after src

You can use it instead

<img src="picture.jpg alt="adidas Originals Superstar Bold platform trainers in black and white">

Thank you for bringing up these ideas about accessibility. I am just starting to use HTML myself and was not familiar with the main tag. Is there a standard for what should be included in the main content? How would it differ from the body tag?


There is only one HTML standard now. You can read description of body and main elements in him. Also, please, check your Linkedin profile. I connected with you so that you will not miss new tips from me


Last one little confuse, how can we use fontawesome icon to svg ? though very useful post.


Great content! Thank you!


Don't use H1-H6 headers? Using ::after selectors instead of a simple and basic CSS cascading rules? Spamming the alt tags with as much bloat as possible? These aren't good ideas at all.


I don't think that's what he means at all. He's advising to not use headings for non-heading content. The examples aren't the best, but the meaning is clear if you read the rest of that section.

He uses pseudo elements to draw non-content visual items. That's absolutely fine. We shouldn't use extra HTML markup to achieve this sort of thing.

The alt attributes (not tags) aren't being stuffed with bloat. Those attributes should be a replacement for the image when it cannot be seen (such as for blind users, or those on slow/metered connections). By not putting an accurate replacement in here is doing your visitors a disservice. It's important to note that alt text is not the same thing as a description. A good test is to remove the image from the content, replace it with the alt attribute text, and see if the overall content still makes sense. If the replaced image content doesn't, you probably need to fix it.