Open frivoal opened 3 years ago
I think the WebKit implementation is just an artifact of how fragmentation works on WebKit. cc @bfgeek, is LayoutNG different in this case?
@emilio @frivoal Its different, but there is a (slightly) larger larger question around what non-fragment aware geometry APIs should return in general. E.g. what does clientWidth/clientHeight return?
We are currently building the capability to have different inline-sized fragments. An answer which may make sense is:
gCS(elem).width == std::max(fragments_inline_sizes);
gCS(elem).height == sum_fragments_block_sizes;
Similar for clientWidth/clientHeight/scrollWidth/scrollHeight/etc.
gCS(elem).width/height
doesn't return the used width for non-replaced inline elements, so I think it doesn't matter for that specific case, fwiw.
I think doing first-fragment is the easiest. Lots of these APIs weren't thought with fragmentation in mind and trying to retroactively support it is probably not a great idea / use of our time.
APIs like ResizeObserver
/ getClientRects
/ are meant to provide per-fragment sizes, so I don't think we need new APIs even.
In general, I agree with @emilio, and we should have fragment-aware APIs to properly investigate fragment specific questions, and return something simple here, since we cannot do it perfectly anyway. But we might not be able to return the value of the first fragment in all cases, due to compat concerns. For instance, I suspect (though I don't know for sure) that for padding-bottom, there might be an expectation to return the value of the last fragment, not the first one. But this would have to be investigated on a property by property basis.
How about we spec that the value returned should be based on the first fragment, except in explicitly listed cases where we define exactly what happens, and we add to that list as we discover good reasons to make exceptions.
Maybe properties that relate to the 'end' directions (in LTR: bottom and right) should be last-fragment, and all other properties should be the first fragment?
The CSS Working Group just discussed [cssom][css-break] getComputedStyle and fragmentation
.
In general I think we should discourage use of getComputedStyle
for asking questions about geometry.
In general I think we should discourage use of getComputedStyle for asking questions about geometry.
Agreed, and it seemed to me that returning a not-too-smart but simple answer (like "always first fragment") is kind of going in that direction, but on the call, we did seem to want to try a bit harder and get something roughly sensible, for the sake of people who do geometry with it.
The growing proposal seems to be:
(for non-replaced inlines, it's already defined to return the computed value, not used value, so don't try to do any math on that.)
For everything else, it doesn't seem to make a difference until we introduce the ability to style differently per fragment. Except arguably, we already have the ability to style different fragment differently, though in a limited and quirky fashion :(
<p><span id=nowwhat>a sufficiently long piece of text that takes up more than one line and wraps</span>
p::first-line { font-weight: 800; }
p { font-weight: 100;}
console.log(getComputedStyle(document.getElementById("nowwhat")).fontWeight);
But ::first-line
and first-letter
are plenty quirky, so I'd be tempted to not generalize from them, and to the extend that something needs to be specified for them, I'd go with a specific rule that covers them and them only (possibly hosted in css-pseudo), and not try to address them via something generic about fragmentation.
Or maybe it's just block-end on the last fragment, and inline-end stays on the first for margins / borders / paddings / offsets
Borders already return computed values, iirc, so I'd rather not make them return used values now.
I could not find a defintion that states how
getComputedStyle()
is supposed to work for fragmented elements.getComputedStyle()
returns the resolved value. In some cases, that corresponds to the computed value, and in some cases that corresponds to the used value. Even when an element is fragmented, the computed value is clearly a per-element thing, but the way the used value is calculated from the computed value as part of layout and can, in some cases, differ per fragment. In such cases, I could not find any spec that says what getComputedStyle() is supposed to return.For many properties, the used value is equal to the computed value anyway, so for them there's no problem, but that's not always true. Most prominently, what about the
width
andheight
of fragmented block elements: should the used value of the height property be the height of the first fragment, or the sum of the height of all fragments (or something else)? Should the used value of the width be the that of the first fragment, or the sum, or the average? Should potentially orthogonal writing-modes make a difference? Should a different display type make a difference? More properties may have answers that vary per fragment, maybe due to percentages (see https://github.com/w3c/csswg-drafts/issues/6512) or tobox-decoration-break
.I think the only answer we can consistently apply to all properties and all display types, regardless of writing-mode, box-decoration-break, etc, is to return the used value on the first fragment. We could special-case some situations to get sums or averages or other computations to derive one value from several, but that seems like a lot corner-case handling for no clear use-case.
In terms of current implementations, as far as I can tell Firefox does just return the values of the first fragment in all cases. Chrome and Safari seem to have special cased
block-size
(and whichever ofwidth
andheight
it maps to) to return a sum of all fragments.If there's no compat constraint, I'd suggest standardizing on the simpler behavior of only taking into account the first fragment. If we do want to special case some properties, we should document them.