Useragent-like Initial Styling for Custom Elements

It occurred to me that when making Custom Elements, I’d like for them to have default styling that is easy to override (i.e. the styling has least priority, i.e. the styling is first in the CSS cascade just like useragent styling).

Is this possible? Is the best we currently have to use <style>/<link> elements at the top of the page and/or to put <style>/<link> elements inside shadow roots?

1 Like

What would the default styling be? I’m quite fond of the fact that there’s nothing I have to override, but newer devs might not feel the same.

The default style might be anything that a Custom Element author wants.

In my case, I want to ship elements to end users, for those elements to have certain initial styling, and for the end user to be able to easily override the styles as if they are top level useragent styles.

More specifically, in my case, the custom elements are used in 3D scenes, and they have default styling like transform-style: preserve-3d; position: absolute; among other styles. These styles are the default styles that give the elements their some of their default rendering functionality.

Currently, I style these elements via the style="" attribute because otherwise styles in the top-level document won’t bleed into shadow roots. But the problem is these styles have the highest specificity and require !important to override which makes managing styles more difficult for the end user. I could inject <style> elements into all of the end user’s shadow roots, but that adds much unwanted complexity to my library code and unideal side effects to the user’s environment.

Useragent styles bleed into shadow roots, which is a nice way of having default styles across a whole app for all builtin elements. It’d be great to have this sort of least-specific styling for Custom Element authors’ elements.

Do you get what I mean?

Ah, yes. I misread what you stated and thought you were proposing browser defaults.

I think this could be resolved with the now-deprecated “shadow piercing” selector (>>>), though I may be missing something obvious. It would also let you use the same stylesheet, naturally.

The piercing selector might be the best current option if it wasn’t deprecated, but maybe we should think about allowing Custom Element authors to provide default styles for all instances of their elements across the whole app while not allowing end users to be able to add rogue styling to component internals.

It seems like useragent styling is a good example.

1 Like

This is not ideal, but once :is() is implemented, you can provide styles with very little specificity, so that they are easy to override. We still need a proper solution for this though.

1 Like

You might want to check out the Constructable Stylesheets proposal. There’s a comment on providing custom elements with UA-like styles:

1 Like

That would certainly be better than what we have now. I would totally like to use that right now.

Also, please note the Default Stylesheets proposal for Web Components, which was made a while ago.