Open mstensho opened 6 years ago
Seems like the example got lost, presumably because github strips html.
I think you need to wrap the examples in triple quotes like:
```html
<div></div>
\```
(without that backslash). Which will render as:
<div></div>
Agh, I keep forgetting that. Thanks for pointing it out! Comment updated and fixed.
am I holding the specs wrong?
No, I agree with the way you're reading this.
For percentage resolution and auto margin resolution, this seems to be what browsers do.
A quick bit of testing seems to show that all browsers do convert percentages to pixels, but that there isn't interop on auto. Chrome/Safari/Edge gives out the expected number of px, but Firefox resolves auto to 0px
regardless of the actual size.
However, nobody behaves according to spec in over-constrained situations
That does match my testing.
Since we don't have full interop on the resolved value of auto
, we probably have some degree of choice. There is partial interop, since nobody actually returns auto
as a keyword and everybody returns pixels, so we probably have to keep that. There does seem to be a majority (in UA numbers and market share) in favor the true used value, so I'd favor keeping the spec as is treating the Firefox behavior as a bug.
For the rest, there does seem to be agreement that what getComputedStyle returns is the computed value converted to pixels, not the used value. Given that we have interop, the spec is probably what should be fixed. But that's not consistent with the previous point, so I'd prefer if we could go the other way around, and make everybody match the spec.
Have you looked into other properties, to see if they actually return the used value, or merely the computed value with percentages converted to lengths?
Right, Firefox doesn't resolve auto. I somehow failed to realize that.
One problem here is that, in order to honor the spec, user agents need to calculate values that the layout engine typically never uses. E.g. for a regular block in LTR, you never need to bother with the right margin at all. Just get the left margin correct. Still, the spec currently requires us to calculate a value for margin-right, so that we satisfy the constraint (width + fluff == containing block width).
Here's a more interesting test:
<div style="width: 400px;">
<div style="float:left; width:100px; height:10px;"></div>
<div id="elm" style="overflow:hidden; margin:auto; width:100px;"></div>
</div>
What's the used/resolved margin-left and margin-right here? We have a float that pushes #elm 100px to the right before we apply auto margins. So we have this: 100px of float, 100px of left margin, 100px of #elm border box and, finally 100px of margin right.
To satisfy the constraint, the sum of the used margins and the border box need to equal the width of the containing block, i.e. 400px. So it seems to me that the correct implementation would be to calculate a used margin-left of 200px and used margin-right of 100px. I've found no browser that does this. Chrome has margin-left:100px and margin-right:200px (weird!), while Edge pretends that the float isn't there (for the sake of getComputedStyle()) and has margin-left:150px and margin-right:150px. I guess this just goes to show that the current spec forces browsers to calculate values that are not needed by layout.
I think margins are really special here (due to 'auto' and over-constrainedness), and that it doesn't make sense to see how other properties are treated and compare with that.
This bit me while trying to implement an optimization in Firefox. Firefox returns what I think is the correct value in these test-cases:
```
One WPT relies on us not doing this, and returning the pixel value as-is. My patch "fixed" the WPT, but given this issue I think I'm going to keep our behavior untouched for now, and reference this issue from the code. Also maybe fix the WPT, which is a rather naive one that isn't testing this in particular (http://w3c-test.org/css/css-box/parsing/margin-computed.html)
https://bugzilla.mozilla.org/show_bug.cgi?id=1404140 is the bug I was working on when fixing this, https://bugzilla.mozilla.org/show_bug.cgi?id=1570759 is the bug tracking potentially changing the behavior, since the Firefox behavior is inconsistent depending on whether we have percentage margins or not.
This appeared during the discussion of #9174. CSS Align mandates a deviation from CSS2: https://drafts.csswg.org/css-align/#justify-block
In terms of CSS2.1 block-level formatting [CSS2], the rules for “over-constrained” computations in section 10.3.3 are ignored in favor of alignment as specified here and the used value of the margin properties are therefore not adjusted to correct for the over-constraint.
I'm looking into how Window.getComputedStyle() behaves for margins.
https://drafts.csswg.org/cssom/#resolved-values
So the resolved value for margins is typically the used value. For percentage resolution and auto margin resolution, this seems to be what browsers do. However, nobody behaves according to spec in over-constrained situations:
https://www.w3.org/TR/CSS22/visudet.html#blockwidth
The spec says that the used value of either margin-left or margin-right should be changed to satisfy the constraint (margin + border + padding + width == containing block width).
Instead, all browsers just use the computed value of the margin property that should be overridden.
Example:
The used value of #elm's margin-right should be 300px, but getComputedStyle(elm).marginRight returns 10px in both Chrome, Edge and Firefox.
Should this be considered browser bugs, or should the spec be fixed, or am I holding the specs wrong?