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, single-quoted, and double-quoted 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, <, >, ", ',, =, &, `.

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>