-
Notifications
You must be signed in to change notification settings - Fork 759
Description
https://drafts.csswg.org/css2/#inline-replaced-width
If height and width both have computed values of auto and the element has an intrinsic ratio but no intrinsic height or width, then the used value of width is undefined in CSS 2. However, it is suggested that, if the containing block’s width does not itself depend on the replaced element’s width, then the used value of width is calculated from the constraint equation used for block-level, non-replaced elements in normal flow.
This doesn't explain how min-content and friends are supposed to behave.
Testcase
<!DOCTYPE html>
<style>svg { display: block; outline: 3px solid; margin: 12px 0; }</style>
<div style="width: 100px">
<svg viewbox="0 0 1 1" style="width: auto"></svg>
<svg viewbox="0 0 1 1" style="width: min-content"></svg>
<svg viewbox="0 0 1 1" style="width: fit-content"></svg>
<svg viewbox="0 0 1 1" style="width: max-content"></svg>
<svg viewbox="0 0 1 1" style="width: 0; min-width: min-content"></svg>
<svg viewbox="0 0 1 1" style="width: 0; min-width: fit-content"></svg>
<svg viewbox="0 0 1 1" style="width: 0; min-width: max-content"></svg>
<svg viewbox="0 0 1 1" style="width: 200px; max-width: min-content"></svg>
<svg viewbox="0 0 1 1" style="width: 200px; max-width: fit-content"></svg>
<svg viewbox="0 0 1 1" style="width: 200px; max-width: max-content"></svg>
<hr>
<svg viewbox="0 0 1 1" style="height: 50px; width: auto"></svg>
<svg viewbox="0 0 1 1" style="height: 50px; width: min-content"></svg>
<svg viewbox="0 0 1 1" style="height: 50px; width: fit-content"></svg>
<svg viewbox="0 0 1 1" style="height: 50px; width: max-content"></svg>
<svg viewbox="0 0 1 1" style="height: 50px; width: 0; min-width: min-content"></svg>
<svg viewbox="0 0 1 1" style="height: 50px; width: 0; min-width: fit-content"></svg>
<svg viewbox="0 0 1 1" style="height: 50px; width: 0; min-width: max-content"></svg>
<svg viewbox="0 0 1 1" style="height: 50px; width: 200px; max-width: min-content"></svg>
<svg viewbox="0 0 1 1" style="height: 50px; width: 200px; max-width: fit-content"></svg>
<svg viewbox="0 0 1 1" style="height: 50px; width: 200px; max-width: max-content"></svg>
<hr>
<svg viewbox="0 0 1 1" style="min-height: 150px; width: auto"></svg>
<svg viewbox="0 0 1 1" style="min-height: 150px; width: min-content"></svg>
<svg viewbox="0 0 1 1" style="min-height: 150px; width: fit-content"></svg>
<svg viewbox="0 0 1 1" style="min-height: 150px; width: max-content"></svg>
<svg viewbox="0 0 1 1" style="min-height: 150px; width: 0; min-width: min-content"></svg>
<svg viewbox="0 0 1 1" style="min-height: 150px; width: 0; min-width: fit-content"></svg>
<svg viewbox="0 0 1 1" style="min-height: 150px; width: 0; min-width: max-content"></svg>
<svg viewbox="0 0 1 1" style="min-height: 150px; width: 200px; max-width: min-content"></svg>
<svg viewbox="0 0 1 1" style="min-height: 150px; width: 200px; max-width: fit-content"></svg>
<svg viewbox="0 0 1 1" style="min-height: 150px; width: 200px; max-width: max-content"></svg>
<hr>
<svg viewbox="0 0 1 1" style="max-height: 50px; width: auto"></svg>
<svg viewbox="0 0 1 1" style="max-height: 50px; width: min-content"></svg>
<svg viewbox="0 0 1 1" style="max-height: 50px; width: fit-content"></svg>
<svg viewbox="0 0 1 1" style="max-height: 50px; width: max-content"></svg>
<svg viewbox="0 0 1 1" style="max-height: 50px; width: 0; min-width: min-content"></svg>
<svg viewbox="0 0 1 1" style="max-height: 50px; width: 0; min-width: fit-content"></svg>
<svg viewbox="0 0 1 1" style="max-height: 50px; width: 0; min-width: max-content"></svg>
<svg viewbox="0 0 1 1" style="max-height: 50px; width: 200px; max-width: min-content"></svg>
<svg viewbox="0 0 1 1" style="max-height: 50px; width: 200px; max-width: fit-content"></svg>
<svg viewbox="0 0 1 1" style="max-height: 50px; width: 200px; max-width: max-content"></svg>
<hr>
<svg viewbox="0 0 1 1" style="min-height: 50px; max-height: 150px; width: auto"></svg>
<svg viewbox="0 0 1 1" style="min-height: 50px; max-height: 150px; width: min-content"></svg>
<svg viewbox="0 0 1 1" style="min-height: 50px; max-height: 150px; width: fit-content"></svg>
<svg viewbox="0 0 1 1" style="min-height: 50px; max-height: 150px; width: max-content"></svg>
<svg viewbox="0 0 1 1" style="min-height: 50px; max-height: 150px; width: 0; min-width: min-content"></svg>
<svg viewbox="0 0 1 1" style="min-height: 50px; max-height: 150px; width: 0; min-width: fit-content"></svg>
<svg viewbox="0 0 1 1" style="min-height: 50px; max-height: 150px; width: 0; min-width: max-content"></svg>
<svg viewbox="0 0 1 1" style="min-height: 50px; max-height: 150px; width: 200px; max-width: min-content"></svg>
<svg viewbox="0 0 1 1" style="min-height: 50px; max-height: 150px; width: 200px; max-width: fit-content"></svg>
<svg viewbox="0 0 1 1" style="min-height: 50px; max-height: 150px; width: 200px; max-width: max-content"></svg>
</div>
<script>
for (let el of document.querySelector("div").children) {
if (el.tagName === "svg") {
document.body.append(el.clientWidth + "x" + el.clientHeight, document.createElement("br"));
} else {
document.body.append(el.cloneNode());
}
}
</script>Results
| Style | Gecko | Blink | WebKit |
|---|---|---|---|
width: auto |
100x100 | 100x100 | 100x100 |
width: min-content |
0x0 | 100x100 | 300x300 |
width: fit-content |
0x0 | 100x100 | 300x300 |
width: max-content |
100x100 | 100x100 | 300x300 |
width: 0; min-width: min-content |
0x0 | 0x0 | 300x300 |
width: 0; min-width: fit-content |
0x0 | 0x0 | 300x300 |
width: 0; min-width: max-content |
0x0 | 0x0 | 300x300 |
width: 200px; max-width: min-content |
0x0 | 200x200 | 200x200 |
width: 200px; max-width: fit-content |
0x0 | 200x200 | 200x200 |
width: 200px; max-width: max-content |
0x0 | 200x200 | 200x200 |
height: 50px; width: auto |
50x50 | 50x50 | 50x50 |
height: 50px; width: min-content |
50x50 | 50x50 | 300x50 |
height: 50px; width: fit-content |
50x50 | 50x50 | 300x50 |
height: 50px; width: max-content |
50x50 | 50x50 | 300x50 |
height: 50px; width: 0; min-width: min-content |
50x50 | 50x50 | 300x50 |
height: 50px; width: 0; min-width: fit-content |
50x50 | 50x50 | 300x50 |
height: 50px; width: 0; min-width: max-content |
50x50 | 50x50 | 300x50 |
height: 50px; width: 200px; max-width: min-content |
50x50 | 50x50 | 200x50 |
height: 50px; width: 200px; max-width: fit-content |
50x50 | 50x50 | 200x50 |
height: 50px; width: 200px; max-width: max-content |
50x50 | 50x50 | 200x50 |
min-height: 150px; width: auto |
150x150 | 150x150 | 150x150 |
min-height: 150px; width: min-content |
0x150 | 150x150 | 300x300 |
min-height: 150px; width: fit-content |
0x150 | 150x150 | 300x300 |
min-height: 150px; width: max-content |
150x150 | 150x150 | 300x300 |
min-height: 150px; width: 0; min-width: min-content |
0x150 | 150x150 | 300x300 |
min-height: 150px; width: 0; min-width: fit-content |
0x150 | 150x150 | 300x300 |
min-height: 150px; width: 0; min-width: max-content |
0x150 | 150x150 | 300x300 |
min-height: 150px; width: 200px; max-width: min-content |
0x150 | 200x200 | 200x200 |
min-height: 150px; width: 200px; max-width: fit-content |
0x150 | 200x200 | 200x200 |
min-height: 150px; width: 200px; max-width: max-content |
0x150 | 200x200 | 200x200 |
max-height: 50px; width: auto |
50x50 | 50x50 | 150x50 |
max-height: 50px; width: min-content |
0x0 | 50x50 | 300x50 |
max-height: 50px; width: fit-content |
0x0 | 50x50 | 300x50 |
max-height: 50px; width: max-content |
50x50 | 50x50 | 300x50 |
max-height: 50px; width: 0; min-width: min-content |
0x0 | 0x0 | 300x50 |
max-height: 50px; width: 0; min-width: fit-content |
0x0 | 0x0 | 300x50 |
max-height: 50px; width: 0; min-width: max-content |
0x0 | 0x0 | 300x50 |
max-height: 50px; width: 200px; max-width: min-content |
0x0 | 50x50 | 200x50 |
max-height: 50px; width: 200px; max-width: fit-content |
0x0 | 50x50 | 200x50 |
max-height: 50px; width: 200px; max-width: max-content |
0x0 | 50x50 | 200x50 |
min-height: 50px; max-height: 150px; width: auto |
100x100 | 100x100 | 50x50 |
min-height: 50px; max-height: 150px; width: min-content |
0x50 | 100x100 | 300x150 |
min-height: 50px; max-height: 150px; width: fit-content |
0x50 | 100x100 | 300x150 |
min-height: 50px; max-height: 150px; width: max-content |
100x100 | 100x100 | 300x150 |
min-height: 50px; max-height: 150px; width: 0; min-width: min-content |
0x50 | 50x50 | 300x150 |
min-height: 50px; max-height: 150px; width: 0; min-width: fit-content |
0x50 | 50x50 | 300x150 |
min-height: 50px; max-height: 150px; width: 0; min-width: max-content |
0x50 | 50x50 | 300x150 |
min-height: 50px; max-height: 150px; width: 200px; max-width: min-content |
0x50 | 150x150 | 200x150 |
min-height: 50px; max-height: 150px; width: 200px; max-width: fit-content |
0x50 | 150x150 | 200x150 |
min-height: 50px; max-height: 150px; width: 200px; max-width: max-content |
0x50 | 150x150 | 200x150 |
Gecko and WebKit don't seem to make much sense to me.
I think what I would expect is:
- The automatic size is
fit-content(as usual for replaced elements) - The
min-contentsize is0px - The
max-contentsize iscalc(1px / 0) - Thus
fit-contentstretches to the container
But letting max-content explode isn't great and maybe not web compatible.
Blink seems to do:
- If the height is definite, the min/max-content sizes are the height (clamped between min/max-height) transferred thru the aspect ratio (as usual).
- Otherwise, the min/max-content sizes are indefinite. The keywords behave as such:
- In
min-width, they behave as the min-height transferred thru the aspect ratio - In
max-width, they behave as the max-height (floored by the min-height) transferred thru the aspect ratio - In
width, they behave as the stretch size (or zero when computing the intrinsic contributions), clamped by the transferred min/max-height
- In
I'm not a fan of these keywords having different behaviors on different properties. I would rather use the width behavior is min-width and max-width too.