29
loading...
This website collects cookies to deliver better user experience
:defined
CSS pseudo-class to "hide" custom elements that haven't been registered yet. You can scope it to specific tags or you can hide all undefined custom elements as shown below.:not(:defined) {
visibility: hidden;
}
visibility: hidden
instead of display: none
to reduce shifting as elements are registered.customElements.whenDefined()
, which returns a promise that resolves when the specified element gets registered. You'll probably want to use it with Promise.allSettled()
in case an element fails to load for some reason (thanks, Westbrook!).<body>
with opacity: 0
and add a class that fades it in as soon as all your custom elements are defined.<style>
body {
opacity: 0;
}
body.ready {
opacity: 1;
transition: .25s opacity;
}
</style>
<script type="module">
await Promise.allSettled([
customElements.whenDefined('my-button'),
customElements.whenDefined('my-card'),
customElements.whenDefined('my-rating')
]);
// Button, card, and rating are registered now! Add
// the `ready` class so the UI fades in.
document.body.classList.add('ready');
</script>
<head>
as a method of eliminating FOUCE, but that doesn't work if you're using ES modules. While the approach works for non-modules, I've removed it because it leads to poor page load times and because of the growing ubiquity of ES modules on the Web.