diff --git a/files/en-us/web/css/_colon_defined/index.md b/files/en-us/web/css/_colon_defined/index.md index 3cc04966a8058d0..9ce7472ac53fd11 100644 --- a/files/en-us/web/css/_colon_defined/index.md +++ b/files/en-us/web/css/_colon_defined/index.md @@ -7,7 +7,7 @@ browser-compat: css.selectors.defined {{CSSRef}} -The **`:defined`** [CSS](/en-US/docs/Web/CSS) [pseudo-class](/en-US/docs/Web/CSS/Pseudo-classes) represents any element that has been defined. This includes any standard element built in to the browser, and custom elements that have been successfully defined (i.e. with the {{domxref("CustomElementRegistry.define()")}} method). +The **`:defined`** [CSS](/en-US/docs/Web/CSS) [pseudo-class](/en-US/docs/Web/CSS/Pseudo-classes) represents any element that has been defined. This includes any standard element built into the browser and custom elements that have been successfully defined (i.e. with the {{domxref("CustomElementRegistry.define()")}} method). ```css /* Selects any defined element */ @@ -33,65 +33,95 @@ simple-custom:defined { ### Hiding elements until they are defined -The following snippets are taken from our [defined-pseudo-class](https://github.com/mdn/web-components-examples/tree/main/defined-pseudo-class) demo ([see it live also](https://mdn.github.io/web-components-examples/defined-pseudo-class/)). +In this demo, we define a basic custom element named `` and use the `:not(:defined)` and `:defined` selectors to style the element before and after it is defined. This is useful if you have a complex custom element that takes a while to load into the page — you might want to hide instances of the element until the definition is complete so that you don't end up with flashes of ugly unstyled elements on the page. -In this demo we define a very simple trivial custom element: +#### HTML -```js -customElements.define( - "simple-custom", - class extends HTMLElement { - constructor() { - super(); - - let divElem = document.createElement("div"); - divElem.textContent = this.getAttribute("text"); - - let shadowRoot = this.attachShadow({ mode: "open" }).appendChild(divElem); - } - }, -); -``` - -Then insert a copy of this element into the document, along with a standard `

`: +The following HTML code uses the custom element but the element hasn't been defined yet. We also include a {{htmlelement("button")}} that will define the custom element when clicked, allowing you to see its state before and after definition. ```html - - -

Standard paragraph example text

+ +

+ Loaded content: Lorem ipsum tel sed tellus eiusmod tellus. Aenean. Semper + dolor sit nisi. Elit porttitor nisi sit vivamus. +

+
+ + ``` -In the CSS we first include the following rules: +#### CSS -```css -/* Give the two elements distinctive backgrounds */ -p { - background: yellow; +```css hidden +custom-element { + display: block; + border: 5px dashed grey; + border-radius: 1rem; + height: 100px; + width: 400px; + padding: 1rem; + position: relative; + user-select: none; } -simple-custom { - background: cyan; +code { + background: #ccc; } -/* Both the custom and the built-in element are given italic text */ -:defined { - font-style: italic; +#btn { + margin-top: 1rem; + cursor: pointer; } ``` -Then provide the following two rules to hide any instances of our custom element that are not defined, and display instances that are defined as block level elements: +In the following CSS, we use the `custom-element:not(:defined)` selector to select the element and color it grey while it is not defined and the `custom-element:defined` selector to select the element and color it black after it is defined. ```css -simple-custom:not(:defined) { - display: none; +custom-element:not(:defined) { + border-color: grey; + color: grey; } -simple-custom:defined { - display: block; +custom-element:defined { + background-color: wheat; + border-color: black; + color: black; } + +/* show loading message */ +custom-element:not(:defined)::before { + content: "Loading..."; + position: absolute; + inset: 0 0 0 0; + align-content: center; + text-align: center; + font-size: 2rem; + background-color: white; + border-radius: 1rem; +} + +/* remove the loading message */ +custom-element:defined::before { + content: ""; +} +``` + +We have also used the [`::before`](/en-US/docs/Web/CSS/::before) pseudo-element to show a "Loading..." overlay message until the element is defined. After definition, it is removed by setting the [`content`](/en-US/docs/Web/CSS/content) to an empty string. + +The following JavaScript has been used to define the custom element. To allow you to see the state of the custom element before and after definition we run the {{domxref("CustomElementRegistry.define", "define()")}} method when the button is clicked. + +```js +const btn = document.querySelector("#btn"); + +btn.addEventListener("click", () => { + customElements.define("custom-element", class extends HTMLElement {}); + btn.remove(); +}); ``` -This is useful if you have a complex custom element that takes a while to load into the page — you might want to hide instances of the element until definition is complete, so that you don't end up with flashes of ugly unstyled elements on the page +#### Result + +{{EmbedLiveSample("Hiding elements until they are defined", "100%", "230")}} ## Specifications