CSS Portal

:defined CSS Pseudo Class

If this site has been useful, we’d love your support! Consider buying us a coffee to keep things going strong!

Description

The :defined pseudo-class targets custom elements that have been successfully defined and registered with the browser’s Custom Elements Registry. It is part of the Web Components specification and is mainly used to detect when a custom element has finished upgrading from an unknown HTML element into a fully functional component with its associated class, lifecycle callbacks, and behavior.

When a custom element is first encountered in the DOM, the browser may not yet know how to interpret it. Until the element is defined using customElements.define(), it is considered undefined. Once the definition is registered, the element becomes defined, and the :defined pseudo-class begins to match it. This makes the pseudo-class especially useful for preventing unstyled or partially initialized components from appearing on the page.

Why :defined matters

The :defined pseudo-class is commonly used to control visibility, layout, or animation timing for custom elements. Without it, users might briefly see raw markup or fallback content before JavaScript finishes loading. By pairing :defined with default hidden styles, developers can ensure a smoother visual experience.

It also pairs naturally with the concept of progressive enhancement. You can style elements differently before and after definition, enabling graceful degradation when JavaScript fails or is delayed.

Relationship to other concepts

Custom elements rely on the template tag for defining reusable markup structures, and the :defined pseudo-class acts as a signal that those structures are now active. This is especially helpful when working with Shadow DOM–based components or design systems that load asynchronously.

Basic example

HTML

<my-card>Loading...</my-card>

JavaScript

class MyCard extends HTMLElement {
  connectedCallback() {
    this.innerHTML = "<strong>Card loaded!</strong>";
  }
}

customElements.define("my-card", MyCard);

CSS

my-card {
  opacity: 0;
}

my-card:defined {
  opacity: 1;
  transition: opacity 0.3s ease;
}

In this example, the element is invisible until it becomes defined. Once the browser recognizes <my-card> as a valid custom element, the :defined selector applies and fades it in.

Combining with other selectors

You can also combine :defined with structural selectors to create more refined styling logic:

section my-widget:defined {
  border: 2px solid green;
}

This ensures that only fully initialized components inside a specific layout are styled.

Practical use case: hiding uninitialized content

my-widget:not(:defined) {
  display: none;
}

my-widget:defined {
  display: block;
}

This pattern is commonly used to avoid flashes of unstyled content (FOUC) while scripts load.

Syntax

:defined {
  /* ... */
}

Example

<my-alert>Loading component…</my-alert>

<script>
class MyAlert extends HTMLElement {
connectedCallback() {
this.innerHTML = "<strong>Component loaded successfully!</strong>";
}
}

customElements.define("my-alert", MyAlert);
</script>
/* Hide the element before it is defined */
my-alert {
opacity: 0;
}

/* Show the element once it becomes defined */
my-alert:defined {
opacity: 1;
transition: opacity 0.3s ease;
}

Browser Support

The following information will show you the current browser support for the CSS :defined pseudo class. Hover over a browser icon to see the version that first introduced support for this CSS psuedo class.

This psuedo class is supported by all modern browsers.
Desktop
Chrome
Edge
Firefox
Opera
Safari
Tablets & Mobile
Chrome Android
Firefox Android
Opera Android
Safari iOS
Samsung Internet
Android WebView
-

Last updated by CSSPortal on: 31st December 2025

If this site has been useful, we’d love your support! Consider buying us a coffee to keep things going strong!