Code That You Just Never Ever Need to Write

The aim of this blog post is to point out some of the often overlooked syntax features already present in HTML and CSS that can make writing code easier. People sometimes reach for things like preprocessors and custom syntaxes to help them with HTML and CSS before fully taking advantage of all of the flexibility present in the language already. Read on to find out how much extra code you have been writing.

HTML

Optional Start tags

Some HTML elements you don't even need to write. Many elements have a specific content model of what elements they are allowed to contain. HTML allows some elements to omit their start tag in certain situations.

Why?

Including optional tags won't cause any errors, but if you type them wrong, or put them in the wrong place you can introduce errors into your document that never needed to be there in the first place.

Guideline

Skip optional start tags except in cases where you need to add attributes to them.

Examples

  • <html> if it's not followed by a comment
  • <head> if the first thing inside is an element
  • <body> if the first thing inside is an element (with some exceptions)
  • <colgroup> if the first child is a <col>
  • <tbody> in some cases

Before:

<!DOCTYPE html>
<html>
  <head>
    <title>Example HTML Page</title>
  </head>
  <body>
    <p>This is my demo</p>
  </body>
</html>

After:

<!DOCTYPE html>
<title>Example HTML Page</title>
<p>This is my demo</p>

Optional End Tags

Just as with optional start tags, HTML also defines when an element's end tag can be omitted. This list is much longer than the list of optional start tags.

Why?

Optional end tags contribute toward to total filesize with zero technological benefit. It won't speed up how fast your HTML loads, if there's more code to parse it's probably going to load a little slower. Why do work writing code you never needed, just to slow down your loading speed a little?

Guideline

Skip optional end tags anywhere the content model of your document makes the location of the end tags predictable and obvious.

Examples

  • </html> if it isn't followed by a comment
  • </head> if it isn't followed by whitespace or a comment
  • </body> if it isn't followed by a comment
  • </p> in many cases
  • </li> if followed by an <li> tag or is the last child in its parent
  • </caption> if it isn't followed by whitespace or a comment
  • </colgroup> if it isn't followed by whitespace or a comment
  • </tbody> in some cases
  • </thead> in some cases
  • </tfoot> if it's the last child in its parent
  • </tr> if followed by <tr> or is the last child in its parent
  • </td> if followed by a <td> or <th>
  • </th> if followed by a <td> or <th>
  • </optgroup> if followed by <optgroup> or is the last child in its parent
  • </option> if followed by <option> or <optgroup> or is the last child in its parent
  • </dd> if followed by a <dd> or <dt> or is the last child in its parent
  • </dt> if followed by a <dd> or <dt> or is the last child in its parent
  • </rt> if followed by a <rt> or <rp> or is the last child in its parent
  • </rp> if followed by a <rt> or <rp> or is the last child in its parent

Before:

<table>
  <caption>Example Table</caption>
  <thead>
    <tr>
      <th>Col 1</th>
      <th>Col 2</th>
      <th>Col 3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>One</td>
      <td>Two</td>
      <td>Three</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td>Four</td>
      <td>Five</td>
      <td>Six</td>
    </tr>
  </tfoot>
</table>

After:

<table>
  <caption>Example Table
  <thead>
    <tr>
      <th>Col 1
      <th>Col 2
      <th>Col 3
  <tbody>
    <tr>
      <td>One
      <td>Two
      <td>Three
  <tfoot>
    <tr>
      <td>Four
      <td>Five
      <td>Six
</table>

Default Attribute Values

HTML elements sometimes have attributes that you can define that alter the behaviour of the element or its content. In many cases tags will have default attributes, and define what value ought to be used if the attribute isn't present on the tag.

Why?

When you redeclare a default attribute you increase the filesize, and increase the surface area for bugs. If you make a mistake or a typo re-declaring an attribute that was already set you can even break your code.

Guideline

Skip declaring default attributes.

Examples

Quoting Attribute Values

HTML defines three different parsing behaviors for parsing unquoted-state), single-quoted-state), and double-quoted-state) attribute values. As long as the attribute value does not contain the following characters, it can be parsed unquoted: tab, line feed, form feed, space, null, <, >, ", ',, =, &, <code>`</code>.

Why?

Quoting attribute values won't cause problems as long as the attribute value is properly escaped, but it increases the filesize for zero added benefit, and introduces new places where typos and errors can occur that simply never needed to exist in the first place. Adding unnecessary quotes to your HTML is the opposite of making your code more resilient.

Guideline

Skip quoting attribute values except in cases where you'll be including whitespace, or other special characters.

This can be a helpful guideline because quoting attribute values can sometimes make invalid attribute values harder to spot compared to when writing unquoted attribute values.

Example

<!-- These are all equivalent -->
<div id="example"></div>
<div id='example'></div>
<div id=example></div>

Before:

<input id="demo" class="slider" type="range" min="0" max="100" step="1" value="50">

After:

<input id=demo class=slider type=range min=0 max=100 step=1 value=50>

Trailing Slash in HTML

HTML syntax is flexible and forgiving (unlike other markup languages like XML) and it has a lot of wiggle room built into parsing to try its best to recover from what otherwise might be mistakes.

Why?

The trailing slash is something that HTML knows how to parse, probably added to the language so it could tolerate and understand XML-formatted HTML elements if they were pasted into a document with HTML syntax without causing an error. But just because you can type a few extra characters and have them safely ignored doesn't mean there's any benefit to adding them there in the first place.

Guideline

Skip trailing slashes in HTML.

Examples

Before:

<hr />
<input />
<img src=demo.gif />

After:

<hr>
<input>
<img src=demo.gif>

Learn Something New Everyday,
Connect With The Best Developers!

Sign Up Now!

& 500k+ others use Hashnode actively.

Jason Knight's photo

Speaking of returning to outdated, outmoded, HTML 3.2 style practices. Nothing like undoing 20 years of progress and everything 4 Strict was trying to drag us towards -- whilst at the same time making the parser have to work harder trying to figure out what it is you're even trying to do, so you have slower parsing and more CPU use.

The very thing 4 Strict making such things not optional was trying to improve the process on.

1996 called, it want's its markup back.

... and the trailing slash thing being 'supported' was a parsing bug. Just because it's optional in HTML 5 doesn't mean it actually should be considered valid, since it is technically invalid HTML 4. The only reason it's valid as part of 5 is to make the transition from the abortive XHTML branch of doing things simpler. If all you've ever written is HTML, technically you should never have had that self-close on "empty" tags -- as prior to HTML 5 it never existed as part of the HTML specification!

That it exists at all in HTML 5, well... is part of why I really say HTML 5 is just "the new transitional" and why honestly, I have doubts that the folks at the WhatWG understood HTML 4 well enough to have been creating its successor.

Might also help if you used the correct (though confusing) terminology of "empty tags" to describe those that have the trailing slash (self closure) from XHTML... though that itself is part of why I put air quotes around the word "specification" in dripping sarcasm when it comes to HTML... since when the earlier specs talk about an "empty tag" they don't mean that it has no content, they mean that it cannot contain content.

Basically, what you've given is advice I'd suggest that nobody follow. This isn't 1995 to 1997, you're delaying the render and making the parser work harder with invalid markup.

Show +4 replies
Jason Knight's photo

The less code you use, the less there is to break

It doesn't bloat your code, and makes much more sense (to me anyway) than BEM'tastic classes like .sorryFolks__thereIsNo--ReasonFor-allofthis.

That's the kicker, most of the time I see these types of practices in a codebase, it's a bloated mess where anything they "saved" with these bad practices outnumbered 10:1 by even worse practices like endless pointless classes for nothing, endless pointless DIV for nothing, BEM, static images in the markup, static style in the markup, etc, etc.

You know, the hallmark of the train wrecks known as frameworks, pre-processors, WYSYWYGS, etc, etc, etc.

A bit like markup minification. It's laughably silly to even bother with in so many cases where maybe if people weren't using five times the markup they wouldn't need to pull such stunts. "oh but I shaved 5k off it!" -- on pages that you could shave 50k off it just by leveraging semantics, selectors, and separation of presentation from content.

But then, I'm shocked how many people seem to think that "separation of presentation from content" has nothing to do with client-side coding.

Also noticed something else banjaxed in the post -- TFOOT goes before TBODY, not after. Something else I'm always surprised so many people get wrong... Remember what TFOOT's "print" behavior is, which is part of why it exists. In order for it to do what it's designed to do, it has to come before TBODY.

Steven Ventimiglia's photo

Creative Technologist & Sr. Front-End Developer

From Development to Apple to Disney - I'm at the age where I look at things like, "You had something wonderfully interesting, and you've just gone and f*ed it all up." :P

Mark's photo

It's interesting that browsers can apparently handle this, I wasn't aware.

Though I think that humans (and IDEs?) might have some trouble with it. I would personally prefer if the developer before me typed explicit tags (or, you know, autocomplete).

So for the best of both worlds: write HTML with balanced tags, and build these rules into a minifier?

Tommy Hodgins's photo

CSS & Element Queries

Why do more work than you need to? The following are all equivalent, tell me which you'd prefer to write, and why:

<input>
<input />
<input type=text>
<input type=text />
<input type="text">
<input type="text" />

Honestly, why keep typing after you've already typed <-i-n-p-u-t->? It's already valid. Would you rather type 7 characters, or 21 characters to do the exact same thing?

Not only does it take more time, and increase the size of the file, but if you make a single mistake like typing <input tpye=text> or <input type=test> now you have introduced an error into code which never needed to exist in the first place.

Mark's photo

Pretty sure my IDE will both do most of the typing, and give me a warning about typos like that.

It feels much more likely that I follow an unclosed tag with one that changes the auto-closing behaviour and thus mess up my document without me noticing. Not sure IDE will warn about that, especially if the there's another valid interpretation.

Overall I might be more favourable towards redundancy and explicitness than most developers though. In my experience, typing more takes much less time than fixing bugs introduced by small mistakes.

I don't write that much HTML honestly. But I always e.g. add {..} around then-blocks even if there's only one statement, and I'd rather write text.split(",", maxsplit=1) than text.split(",", 1) in Python. Explicitness is good, sometimes.