I believe strongly that the common standard of formatting void elements in HTML using />
is a mistake. Here's why.
First, we need to establish an important distinction; HTML is not XML. They share a very common syntax, but HTML has branched off into its own specification and no longer follows the rules of XML. That's a good thing; XML is inherently very strict about what is allowed and what is not, whereas HTML, being served to browsers, is better off being more lenient (handling errors more gracefully) so that website visitors at least get something if the website owner has made some oversights in their HTML.
The />
self-closing tag syntax comes from XML. In XML, void tags don't exist; every single tag needs an opening and closing tag. Self-closing tags are shortcut syntax for elements that don't have any content; <abc/>
is exactly equivalent to <abc></abc>
.
HTML, on the other hand, doesn't have such a shorthand. It has some special cases where the closing tag may be omitted entirely (such as a <li>
element followed by another one) but XML's self-closing syntax does not work in HTML. In fact, the slash in <div/>
is ignored entirely. That means that <div/>
is equivalent to <div>
- that's right, it does not close the element! When you write <div/>foo
, the foo
is nested within the div
. Most definitely not what the author intended when writing <div/>
. Additionally, a developer coming from XML might think that e.g. <hr/>
is short for <hr></hr>
, whereas really it's long for <hr>
.
The fact that those slashes are ignored means that void elements can be written as if they are self-closing elements in XML. A break tag can be written as <br/>
and still be perfectly valid. This makes it easier to write HTML in such a way that it is simultaneously valid XML. But unless XHTML (HTML's XML-friendly sibling) is a specific requirement, writing XML-compliant HTML is fairly pointless. I would even go as far as to say, it's confusing. Once again; HTML is not XML, and there are things that are valid in HTML but not in XML, and vice versa. Treat them as equivalent, and inevitably you'll run into problems.
HTML doesn't always have the same syntactical rules across the entire document. There is special handling for "foreign content", the most common example being inline SVGs. As a standalone format, SVG is specified in terms of XML. The HTML specification has catered to this somewhat, presumably to make it easier to port standalone SVGs to inlined ones. So, within an inline SVG (that is part of an HTML document), HTML applies special rules; and this includes />
having the meaning of "empty element", as it does in XML. That means that, within foreign content, suddenly things like <path/>
have the meaning of <path></path>
rather than <path>
. This can be especially confusing if you've learned that />
is closing a "void element", because SVG (being XML) doesn't have any of those. In other words, using <path/>
might cause one to think that path
is a void element, which can then subsequently be contradicted when suddenly encountering <path>
elements that are closed with </path>
(either because formatted to be written as such, or because they contain e.g. an <animate/>
node as content).
Of course, we try to use mental models that require the least amount of knowledge, as a form of simplicity. Unfortunately, in this case, that doesn't really work. We are essentially forced to remember which HTML elements are void elements either way; even if we close them with />
, we need to remember that that same syntax does not close other element types. We subsequently also need to know that these constructs do work within XML and inline foreign content. In my opinion, the "simplest" way to go here is to maximize the distiction between HTML and XML(-like) syntax, to avoid being confused by their (unnecessary) similarities.