Missing definition
Among the two types of custom elements, customized built-in elements give you the option to elevate valid markup. With them you are able to provide additional features on top of elements which are already understood by browsers, with native functionalities and semantics. You could, for instance, take a regular button with an “on” and “off” label.
<button>
<span>On</span>
<span>Off</span>
</button> And augment the control to become a full-blown toggle.
After you build the class to manage the toggle-like interaction, after you find a label for the custom element, you expand the button element with the is attribute.
<button is="toggle-button">
<span>On</span>
<span>Off</span>
</button> When the script runs, then, the task is complete. You can satisfy the need for a pointless switch.
When the script runs, however. If the script ever runs. Up until that point the button still lives on the page. You might want to preclude this, to show the element only after it is upgraded in full.
In terms of custom elements, CSS offers a solution with the :defined pseudo class. Target a custom element and you can check when the same has been defined.
custom-element-name:defined {
/* ... */
} With the :not function you can then test the opposite, when the element has yet to be resolved.
custom-element-name:not(:defined) {
/* ... */
} For customized built-in elements this poses a challenge. You can’t find the node with the invented name.
toggle-button:not(:defined) {
/* ... */
} The snippet won’t work, and to be fair, it would be surprising if it did. As far the browser, CSS, and even HTML are concerned, there’s no such thing in the document. There would be if you were to build an autonomous custom element, and spell out the matching tags.
<toggle-button>
<!-- ... -->
</toggle-button> Luckily, there is a solution considering one important fact. Some features, like the :host pseudo class, are exclusive to custom elements. Outside of the specification, they serve no use. But other features, like :defined, have a larger scope, and are applicable to the wider document. This means one of two things:
you can technically target any standard HTML element with the
:definedsuffix*:defined { /* ... */ }It would be close to pointless, however, as the condition would always match.
you can solve the issue at hand
If you enjoy CSS selectors, then, you can even refine the code to consider only the toggle, only the element with the chosen
isattribute[is='toggle-button']:not(:defined) { /* ... */ }Once you do, you can hide the content with ease.
[is='toggle-button']:not(:defined) { display: none; }Without the script, the element is pointless, and fittingly hidden. With it, it might still be pointless, or of a much greater use. Either way, you’ll have something to click.