w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.42k stars 648 forks source link

[cssom] getComputedStyle and/or computedStyleMap to return authored value #10002

Open NickGard opened 6 months ago

NickGard commented 6 months ago

Hello, I'm an engineer at Webflow, a tool that helps users build websites without having to know all of the CSS/HTML/JS that goes into it. I'm working on part of the tool that checks for accessibility issues and a problem I've run into recently is that I can't get the authored styles for font-size using either getComputedStyle or computedStyleMap. I'd like to know that the user hasn't set the font-size for an element in px units, or that they're at least partially set with rem units, like calc(2vw + 0.5rem). When I use the CSSOM APIs to check the style, I only get the resolved size in px units.

Is there any way to change this to report the user-authored value? Or can we create another API to do that, like getAuthoredStyle?

Loirooriol commented 6 months ago

Lengths are absolutized at computed value time, so you want the specified value.

bramus commented 6 months ago

This becomes a need when creating developer tooling, something I ran into before myself: https://github.com/bramus/scroll-driven-animations-debugger-extension/issues/17

So that’s a +1 from me :)

This would require a new API like Oriol said. Something like getSpecifiedStyle(Element elt, optional CSSOMString? pseudoElt) perhaps?

NickGard commented 6 months ago

Lengths are absolutized at computed value time, so you want the specified value.

Yes, that's exactly it! As far as I can tell, the CSSOM offers no API to retrieve this value. I've seen CSS polyfills that parse style tags and linked style files, but they don't account for inlined styles or styles set via DOM APIs. Since the browser has already done the work of parsing and resolving specification, it would be helpful to have access to the applied specified value.

NickGard commented 6 months ago

getSpecifiedStyle(Element elt, optional CSSOMString? pseudoElt)

Would (or should) this also encompass pseudo states? I could imagine wanting to know the specified styles for hover and there's no way to trigger that state that I'm aware of. Focus, valid, invalid, disabled and most other states could be triggered programmatically but that might not be desired, since that would involve a change to the DOM.

bramus commented 6 months ago

The second argument is pseudo-element, not pseudo-class (or state). This similar to getComputedStyle that also has this.

frivoal commented 6 months ago

While not being an expert in the matter, I remember this class of problem being discussed at length in the CSSWG in the past, and this being quite the rabit hole of complexity. @therealglazou would know much more…

bramus commented 2 months ago

Do you recall the rabbit hole Florian is talking about here, @therealglazou?

therealglazou commented 2 months ago

hey @frivoal ! (I'm missing a bit the good ol'CSS days)

Sooooo... This opens a can of worms, guys, and this is exactly the kind of things I needed (and had to implement by myself because rendering engines don't offer such API) in BlueGriffon.

In short, getting the specified value is very far from enough. Suppose the specified value is a calc() calling user-defined properties (aka variables) or for instance a color gradient. You do NOT want to parse that by yourself, you want a parsed version of the specified value. In most cases, the unparsed specified value is of no use at all or, to be more precise, the probability you'll make errors re-implementing value parsing if you get the string only is high.

Suppose you succeed and you finally get that specified value and you get it parsed. If you're building any kind of content editor, what you also want to know is if that value specification can be overridden, what other values it overrides, etc. In summary, accessing the winner of the Cascade is not enough, you also want to access the whole Cascade.

But wait. If you access the whole Cascade and all declarations applying to a given element, you want to have a parsed version of selectors too. Because if you happen to have to create a new selector, you absolutely need to know what's going to be the effect on existing declarations.

All in all, editing capabilities inside a browser require either to downgrade CSS to a subset of restricted selectors but then you can't edit any arbitrary Web page, or to implement a ton of stuff that are missing from CSSOM right now. Since CSSOM is very poorly extensible, you will eventually (like I did) write your own CSS parser and OM.

Hope that helps :-)

bramus commented 2 months ago

In short, getting the specified value is very far from enough.

I’m not sure I agree with this premise. For the use-cases I am thinking of, getting the specified value is sufficient:

The further processing of the specified value can be offloaded to another future API or a userland library. E.g. for calc() specifically the simplification process is well described so you’d be able to get that calc(0% + 10px) value.