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>

Comments (10)

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 all replies
Steven Ventimiglia's photo

Front-End Developer & Creative Strategist

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?

Show all replies
Mark's photo

Currently focussed on [every programming languages and all of the projects]

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.