HTML tags and trailing slashes

XML's foray into HTML, XHTML, has long ended but left a confusing detritus of trailing slashes and their legality behind. The smog of JSX compounds visibility. But once we leave behind the rubble and the haze, the situation is clear.

HTML has only two† kinds of elements††:

  1. Normal elements. These must have a closing tag, even if they have no child content.
    <div></div>
    <button></button>
    
  2. Void elements. This should not have a closing tag, since they can not have any content.
    <img>
    <br>
    

† to first approximation. The spec lists 6.

†† elements are the things themselves, while tags delimit their start and end.

The self closing shortcut for elements without child content, e.g. <div /> is not valid even if it may work.

tldr If you're writing HTML, close your tags (explicitly, not self-closingly), even if there is no content, unless it is a void element.

These are the void elements:

area, base, br, col, embed, hr, img, input, link, meta, source, track, wbr