Open void

One of the biggest advantages of web components is that they extend existing web standards, they build on top of core technologies. As an added benefit, they help you improve what you know about the underlying tech, HTML, CSS and JS, even without sampling the entire buffet.

Let me feed you an example.

In a curious project I explored the option of adding some markup in a shadow root, in the shadow DOM.

shadowRoot.innerHTML = `
<slot />
<span>...</span>
`;

Without turning this discussion into a deep dive of the topic, the shadow DOM gives you the option to author the markup in a separate document tree. In the context of custom elements, then, the slot element offers one way to take content from the light DOM and place it to the dark tree.

<tool-tip>Hi there</tool-tip>

With the code, I decided to continue the markup with a span element, with the goal of pairing the input with the additional label.

Inspector Hi there <span>...</span>

But unfortunately, I stumbled on the consequences of bad-mannered code. The browser did show the text from outside, but not the label, which was simply lost. The reason: a not-so self-closing tag.

As detailed the HTML specification, you can categorize elements in six groups. A handful of these are known as void elements, they don’t expect children nodes and can be written with just an opening tag. An editor might courteously try to add a slash character and signal the end of the node, but this is ultimately unnecessary.

Hi
<br>
there

There are also normal elements, a catch-all category with a very different behavior. These elements can wrap around additional nodes, and to avoid any doubt you need to express both tags; the opening tag and right after, a matching, closing one. You can attest this even without web components, for that matter, with a trivial div and a paragraph, following a solitary opening tag.

<div>
<p>Hi there</p>

Style the generic element with CSS.

div {
	color: white;
	background-color: black;
}

And you’ll see that the changes affect the paragraph as well. For now a good reason: the paragraph is marked up in the container. This explains the change in style and also the hiccup with the custom element. slot is also a normal element, and in the snippet, it gobbles up the markup which follows — it swallows the label in one byte.

Inspector <slot> <span>...</span> </slot>

As soon as you replace the slot from outside, the span element is also removed in favor of the light text. The fix, now obvious, is to just close the node.

-<slot />
+<slot></slot>

And delight in knowing something more about something widespread.

Sorry I'm Not closed

If you are familiar with SVG and writing vector graphics in a code editor, you might have drawn elements with self-closing tags, and enjoyed the more succinct syntax without side effects.

<rect fill="hsl(35 74% 83%)" x="-77" y="-33" width="154" height="110" rx="10" />
<circle fill="hsl(352 60% 20%)" r="3" cx="-67" cy="-23" />

Well, perhaps without knowing, you are able to do so because SVG elements fall in a different category altogether; coming from a separate specification, they are foreign nodes. You can therefore close circles and rectangles without fail. The browser will take care of closing the tag, and everybody will be able to feast on the impressive result.