Open annevk opened 7 months ago
"may disregard some CSS properties"
To me this means engines need to be able to adjust both computed & used styles. @zcorpan interpretation I'm guessing was that the computed style would remain untouched but the used style may not match.
So it seems like we need to clarify the language computed vs. used style.
I think we should allow adjusting both computed & used styles, mainly because auto appearance may have different layout than none appearance (due to platform framework restrictions) and having that reflected in the computed style is helpful for web developers. min-height is adjusted for WebKit buttons for instance, it would be confusing if web developers didn't see it.
The CSS Working Group just discussed [css-ui] Clarify scope of implementation-defined behavior for native appearance (and primitive appearance)
, and agreed to the following:
RESOLVED: Disregarding CSS properties on widgets with native appearance must not affect computed values (unless required for Web-compat)
What does this resolution mean for width
and height
?
cc @emilio @bfgeek @frivoal
@annevk The point of this resolution is that "disregarding" a property means that the user agent is free to render the widget in a way that possibly disagrees with the value of the property.
The main motivation is that the widget may be rendered in a way that isn't even possible to represent in CSS. It's not about being allowed to override the value specified by the author with some other value, but being allowed to ignore the property entirely. So even if the value would be representable in css (and just happen to disagree with the author styles), that's considered an implementation detail: if the UA is doing something else, it's doing something else, and that's not observable via the computed value.
width
and height
are not special here, and the result is that they're (allowed to be) the handled same as what would happen on a <span>
or some other non-replaced inline: they don't apply, don't have an effect, and the UA figures out the size of the widget some other way. But just because it does so doesn't mean that all of sudden the computed value is changed. So for instance, if some child element of the the widget has height: inherit
that'll get the original value.
I think @fantasai mentioned that width
and height
are always defined to be the used value in CSSOM, which is what makes it special in this case. Firefox / Chrome don't have to think about this given those match regardless of the appearance, but it's not unreasonable for system frameworks to force a different layout and reflect that in the computed style?
It would be misleading if the size wasn't reflected in this case in the computed style, especially if that size is bigger.
I think @fantasai mentioned that width and height are always defined to be the used value in CSSOM, which is what makes it special in this case.
The resolution is about the computed value, not about the used value, nor about the result of the getComputedStyle() method, which, confusingly, doesn't always return computed values.
Conceptually, the same arguments could apply to the used value as well, but the discussion didn't explore that too much, and there was a sense that this may be more challenging from an implementation point of view, so that is currently left undefined.
It would be misleading if the size wasn't reflected in this case in the computed style
<style>span { width: 3px; }</style>
<span id=test>supercallifragilisticexpialidocious</span>
<script>console.log(getComputedStyle(test).width);</script>
This will yield "3px", even thought the span is bigger then 3px, because width
and height
don't apply to non-replaced inlines. Same thing here.
(I used getComputedStyle()
for simplicity here, and in does in this case return the computed value. You could observe the computed value some other way, it would still be 3px.)
it's not unreasonable for system frameworks to force a different layout and reflect that in the computed style?
The idea is that it's not always doable when you're choosing to have a non-css based appearance, so we should not try to reflect the value even if we could do it some of the time. Let's say that the border property has been set to 3px solid black
, but your widget looks like this:
Or maybe it has a border that looks like that:
There's no value you can put in the border
property that will do this. So you leave the property's value be 3px solid black
, you ignore it, and you paint the lovely eye candy. If instead if your native appearance happens to have a 5px solid purple border, you don't pipe that back into the property just because this one could be represented in CSS. If you're doing something custom that's different from what the author asked, you're doing something different, and it's not reflected back.
Border widths are not returned as used values in getComputedStyle()
, so if border widths differ between specified style and used style, the actual layout and the values given by getComputedStyle()
don't match.
Border width affects the used value of height
here because form controls have box-sizing: border-box
in the UA stylesheet: https://html.spec.whatwg.org/multipage/rendering.html#form-controls
This is the current situation in WebKit, if I understand correctly.
Demo: https://software.hixie.ch/utilities/js/live-dom-viewer/saved/12396
I think the options for WebKit are, to conform to the WG resolution:
getComputedStyle()
values not match up with the actual layout.border-width
be 2px. This will change the actual layout for native appearance (but the visual border can be painted the same as today).Both of these have non-zero web compat risk. Option 2 I think matches Chromium and Gecko and seems less confusing for authors.
I gave border just as an example that's easy to talk about, but this isn't specifically about borders (or width, or height), but about the general principle: UAs are allowed to treat some properties as if they didn't apply, which is different from treating them as if they did apply but had a special value magically appear from somewhere.
The resolution also carves out a possible exception for compat reasons: though it seemed preferable to the WG to treat the native appearance as an encapsulated concept whose details don't leak back through the computed values of properties, if there are requirements derived from compatibility needs, we can spec those explicitly. But until a specific case has been made about specific properties, the expectation is as I described above.
@zcorpan I'm not sure I understand how 1 and 2 are different.
I had forgotten that the resolved value for height
and width
is the used value, so it seems from that perspective it's in order. (The size of the box is already very much observable so not exposing that seemed a bit backwards, but it seems that's not the intent or at least not the outcome of the proposal.)
I think we should then update the tests such that we essentially expect initial values for all properties, except for those explicitly defined in the user agent style sheet.
It's also not clear to me this problem is unique to WebKit, e.g., https://software.hixie.ch/utilities/js/live-dom-viewer/?%3C!DOCTYPE%20html%3E%3Cinput%20type%3Dcheckbox%3E%3Cscript%3Ew(getComputedStyle(document.querySelector(%22input%22)).borderRightWidth)%3C%2Fscript%3E returns 2px in Gecko.
Border returns used values in Gecko only due to this: https://searchfox.org/mozilla-central/rev/c26f7461fc2a51196b7f517c7f98a1e271dc9ec0/layout/style/nsComputedDOMStyle.cpp#949-959
@annevk
I'm not sure I understand how 1 and 2 are different.
For (1) there would still be a layout difference between native appearance and primitive appearance.
I think we should then update the tests such that we essentially expect initial values for all properties, except for those explicitly defined in the user agent style sheet.
This would fail to test the primitive vs native rendering when there's some particular author-level style, which is the point of the tests in question. https://drafts.csswg.org/css-ui-4/#appearance-disabling-properties
It seems good to test both (and note that the tests also encompass non-devolvable widgets which have different expectations (though end up being a bit confusing as it's not clearly called out)).
While discussing https://github.com/web-platform-tests/wpt/pull/44138 via email with @zcorpan he raised this point:
As an example, for the switch control the native appearance uses
display:inline-grid
(thoughdisplay:block
and the like will compute todisplay:grid
). But when you change to the primitive appearance it'll always havedisplay:initial
. (When this was discussed during a WHATNOT call that was what the people attending preferred.)Being able to change properties (as well as some other things) in this way will also be essential for the inevitable
appearance:base-bikeshed
.cc @nt1m