-
Notifications
You must be signed in to change notification settings - Fork 765
Description
Spec: CSS Properties and Values API Level 1
Summary
This is a proposal to add a JavaScript API that allows developers to introspect all registered custom properties, whether defined via the @Property rule in CSS or through CSS.registerProperty() in JavaScript.
The API should allow querying within a specific context, such as a Document, ShadowRoot, or Element, to support use cases in Shadow DOM or when scoped style registration is in use.
Motivation
Currently, there is no way to retrieve a list of registered custom properties from JavaScript. This limits the ability to:
-
Build tooling (devtools, linters, inspectors) that visualize or validate registered properties.
-
Implement dynamic components or design systems that need to adapt based on property metadata.
-
Debug and profile property usage, inheritance, or incorrect/duplicate registrations.
-
Understand which properties are active inside a Shadow DOM vs. global scope.
While both @Property and CSS.registerProperty() are widely supported in modern browsers, the registration data is not exposed through any DOM or CSSOM APIs.
Proposed API
// Returns all custom properties registered in a given context
CSS.getRegisteredProperties(context?: Document | ShadowRoot | Element): RegisteredProperty[];
Where each RegisteredProperty object could have the following shape:
interface RegisteredProperty {
name: string; // e.g. "--my-color"
syntax: string; // e.g. "<color>"
inherits: boolean;
initialValue: string;
source: "css" | "js"; // indicates @property vs CSS.registerProperty()
}
Context Handling
-
If context is omitted, the function returns global (document-level) registrations.
-
If a ShadowRoot is passed, the function returns properties registered in that shadow scope, including via constructable stylesheets or scoped APIs.
-
If an Element is passed, it resolves to its root node (getRootNode()) to determine scope.
-
This aligns with the inheritance model of CSS custom properties and Shadow DOM boundaries.
Example
// Document-wide registrations
CSS.getRegisteredProperties(document);
// Registrations inside a web component's shadow root
CSS.getRegisteredProperties(myComponent.shadowRoot);
// Automatically resolves the root scope from an element
CSS.getRegisteredProperties(myComponent);
Benefits
-
Improves developer ergonomics and debugging of registered custom properties.
-
Enables introspection for Shadow DOM components using scoped styling.
-
Facilitates dynamic behavior in runtime libraries and design systems.
-
Mirrors existing reflective patterns in the platform, like CSS.supports() and getComputedStyle().
Precedents & Related Concepts
-
CSS.supports() provides runtime feature testing.
-
getComputedStyle() exposes computed values of custom properties but not their registration metadata.
-
Developer tools (e.g., Chrome DevTools) already inspect this information internally.
-
This proposal extends the capabilities of the CSS Properties and Values API Level 1 by making registration metadata accessible.
Considerations
-
Should the returned list include invalid/ignored registrations? (Probably not.)
-
Should we include additional metadata like registration source location or stylesheet reference?
-
In the future, if custom property registration becomes localizable to @scope or similar constructs, this API should be designed with extensibility in mind.
Conclusion
A contextual API to introspect registered custom properties, from both @Property and CSS.registerProperty, would bridge a critical observability gap in the current CSSOM. It enables a new class of developer tools, runtime behavior, and styling diagnostics—especially important as adoption of Web Components, Shadow DOM, and design tokens continues to grow.