Skip to content

[css-position-3] Absolute positioning - Is the new inset & auto-size behaviour web-compatible? #11195

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
dshin-moz opened this issue Nov 13, 2024 · 17 comments

Comments

@dshin-moz
Copy link

dshin-moz commented Nov 13, 2024

Implementing justify-self & align-self for abs-positioned elements, we ran into:

Which has something to the effect of:

<!DOCTYPE html>
<style>
.abs {
  position: absolute;
  align-self: stretch;
  height: auto;
  top: auto;
  bottom: auto;
  background: lime;
}
</style>
<div class="abs">Test</div>

align-self: stretch should be a no-op (At least for absolute elements not within flex/grid context) in the old behaviour, but seems to be used by websites in the wild anyway in the linked bugs:

  • Virustotal: <uno-navbar>'s shadow-root child
  • SAP: opblock-summary-method

As per the new absolute-positioning steps:

  1. Calculate inset-modified containing block:
  2. Resolving sizes: Definite available size is viewport, no min/max height is given, and since self-alignment is stretch, auto size is stretch size.
  3. Auto margins: N/A
  4. Alignment: Fits exactly in the available space

As per the old steps

  1. Everything is auto, margins zeroed out, top takes its static position value, which is zero
  2. Height is Auto heights for block formatting context roots - Distance between top of the topmost line box and bottom of the bottommost line box, so auto size is basically a shrink-fit size.
  3. Solve for bottom, taking up whatever empty space
@emilio emilio added the Agenda+ label Nov 13, 2024
@emilio
Copy link
Collaborator

emilio commented Nov 13, 2024

@dshin-moz you're probably missing a position: absolute in your test-case as well, right?

cc @fantasai @tabatkins

@dshin-moz
Copy link
Author

Fixed. Thanks!

@Loirooriol Loirooriol added the css-position-3 Current Work label Nov 13, 2024
@Loirooriol
Copy link
Contributor

Better add some background to the testcase to be able to see the size.
2 broken sites found in 6 days is not looking very good... Why are they using stretch if they don't want to stretch 🤦

@Loirooriol
Copy link
Contributor

Actually, the default is align-self: auto, which behaves as normal, which behaves as stretch.

So this means that you should get this behavior even without align-self: stretch, which is obviously wrong.

@dshin-moz
Copy link
Author

dshin-moz commented Nov 14, 2024

You're right that align-self: auto -> normal, but then:

Or if it is normal [...] has no auto inset in the relevant axis
Its automatic size is its stretch-fit size.

So given that the testcase has auto insets, it ends up being content-fit size, I think

EDIT: Ah, I see you've filed #11215 regarding that.

@astearns astearns moved this to FTF agenda items in CSSWG January 2025 meeting Jan 22, 2025
@astearns astearns moved this from FTF agenda items to Regular agenda items in CSSWG January 2025 meeting Jan 22, 2025
@astearns astearns moved this to Regular agenda in CSSWG April 2025 meeting agenda Mar 27, 2025
@bfgeek
Copy link

bfgeek commented Apr 3, 2025

So FWIW chrome didn't change static-pos'd abspos for this reason. We had a look at it, and determined that it wasn't web-compatible (sorry we should have filed an issue at that time).

@Loirooriol
Copy link
Contributor

Yeah, in Servo we tried a few testcases on major browsers, and came to the conclusion that the automatic size of an abspos needs to be fit-content when one or both insets are auto, even if the self-alignment property is stretch.
https://github.com/servo/servo/blob/da4ea0f0965414733f0352e76ff416b1ded75a08/components/layout_2020/positioned.rs#L821,L829

Authors can still use height: stretch if they really want to stretch.

@Loirooriol
Copy link
Contributor

Actually, it has already been fixed in the spec (#11902): https://drafts.csswg.org/css-position-3/#abspos-auto-size

The automatic size of an absolutely positioned box is resolved against its inset-modified containing block as follows:

If its self-alignment property in the relevant axis is stretch and neither of its inset properties nor margins in that axis are auto

Or if it is normal and the box is non-replaced, not a table wrapper box, and has no auto inset in the relevant axis

Its automatic size is its stretch-fit size.

Otherwise

Its automatic size is its fit-content size.

Well, the "nor margins in that axis are auto" is wrong: browsers still allow stretching.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-position-3] Absolute positioning - Is the new inset & auto-size behaviour web-compatible?, and agreed to the following:

  • RESOLVED: Adopt spec text as quoted, i.e. no change to spec.
The full IRC log of that discussion <ydaniv> emilio: still one issue in spec - margin auto preventing stretching
<ydaniv> ... need oriol to take this properly
<ydaniv> astearns: can we resolve on omitting this clause?
<ydaniv> emilio: to change the text to refer to inset properties
<astearns> ack fantasai
<ydaniv> fantasai: issue with web compat, more general
<ydaniv> ... applying alignment where insets were auto
<ydaniv> ... I think it would be ideal if we apply <missed> to flexbox and grid
<ydaniv> ... auto affecting stretch is not impacted by web compat
<fantasai> https://software.hixie.ch/utilities/js/live-dom-viewer/?%3C!DOCTYPE%20html%3E%0A%3Cdiv%20style%3D%22border%3A%20solid%3B%20display%3A%20flex%3B%20height%3A%20100px%22%3E%0A%20%20%3Cdiv%20style%3D%22background%3A%20orange%3B%20align-self%3A%20stretch%3B%20margin-top%3A%20auto%22%3Ex%3C%2Fdiv%3E%0A%3C%2Fdiv%3E
<ydaniv> fantasai: in flexbox margin win over streching
<ydaniv> ... AFAICT
<ydaniv> astearns: only in flexbox?
<fantasai> https://www.w3.org/TR/css-flexbox-1/#valdef-align-items-stretch
<ydaniv> fantasai: I believe grid is the same
<ydaniv> ... so when alignment is normal we should do ...
<ydaniv> ... but for strech should be compatible with what we do
<ydaniv> ... the alignment property didn't have any effect until recently
<ydaniv> ... normal should be resolve margins to 0
<ydaniv> ... auto margins don't win over the strechy behavior
<ydaniv> ... so for stretch alignment the auto margins should win
<ydaniv> ... just set to 0
<ydaniv> astearns: you're suggesing we need a change for normal?
<ydaniv> fantasai: no, the auto value already is correct
<ydaniv> astearns: maybe we need to take this back to issue?
<ydaniv> fantasai: oriol is describing what browsers do currently
<ydaniv> ... the questions is what the specs should specify
<fantasai> Current spec says that if alignment is normal and margins are auto, we stretch
<fantasai> If alignment is 'stretch' and margins are auto, we don't stretch
<bradk> +1 to usefulness of auto margin winning for stretch, like flex and grid.
<ydaniv> fantasai: if author says stretch they want it more, but compat with CSS 2 we can't change it, but can make it more like flexbox and grid
<fantasai> s/change it/change normal alignment/
<ydaniv> iank_: so this might be orthogonal
<fantasai> s/can make it/can make stretch alignment/
<ydaniv> ... changing anything for the double auto set case is not web compat
<ydaniv> fantasai: last comment was that this was fixed in spec
<ydaniv> astearns: anyone wants to argue that stretchy things would be different?
<ydaniv> iank_: could we add examples of who is doing what and what is intended behavior?
<ydaniv> fantasai: we have non-replace element, with insets set on both sides, has auto margins, has either no alignment or normal
<ydaniv> ... what wins? stretch? or margins?
<ydaniv> ... on normal behavior strech behavior wins
<ydaniv> ... that needs to be how we define normal
<iank_> https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=13699
<iank_> this case?
<ydaniv> ... what I'm arguing is for stretch alignment when we have room to make adjustments we
<fantasai> ... for stretch, s/when/where/
<ydaniv> ... be compat with flexbox and grid
<ydaniv> iank_: seems fine
<ydaniv> fantasai: proposal is to adopt spec as quoted and not as suggested
<ydaniv> astearns: suggest to close and open only if spec text on stretch turns wrong
<fantasai> PROPOSED: Adopt spec text as quoted, i.e. no change to spec.
<emilio> sgtm
<fantasai> RESOLVED: Adopt spec text as quoted, i.e. no change to spec.

aarongable pushed a commit to chromium/chromium that referenced this issue Apr 30, 2025
As discussed in:
w3c/csswg-drafts#11195 (comment)
(See detailed discussion).

Fixed: 413018662
Change-Id: I97951025fb6711f2470a6271ed86ca8523bf9bee
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6499966
Reviewed-by: David Grogan <dgrogan@chromium.org>
Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org>
Commit-Queue: David Grogan <dgrogan@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1453678}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Apr 30, 2025
As discussed in:
w3c/csswg-drafts#11195 (comment)
(See detailed discussion).

Fixed: 413018662
Change-Id: I97951025fb6711f2470a6271ed86ca8523bf9bee
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6499966
Reviewed-by: David Grogan <dgrogan@chromium.org>
Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org>
Commit-Queue: David Grogan <dgrogan@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1453678}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Apr 30, 2025
As discussed in:
w3c/csswg-drafts#11195 (comment)
(See detailed discussion).

Fixed: 413018662
Change-Id: I97951025fb6711f2470a6271ed86ca8523bf9bee
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6499966
Reviewed-by: David Grogan <dgrogan@chromium.org>
Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org>
Commit-Queue: David Grogan <dgrogan@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1453678}
@Loirooriol
Copy link
Contributor

I think it's completely nonsensical that place-self: stretch does NOT stretch when place-self: normal DOES stretch!

<!DOCTYPE html>
<style>
.container {
  position: relative;
  width: 100px;
  height: 100px;
  border: solid;
}
.abspos {
  position: absolute;
  inset: 0;
  margin: auto;
  border: solid magenta;
}
</style>
<div class="container">
  <div class="abspos" style="place-self: normal">foo bar</div>
</div>
<div class="container">
  <div class="abspos" style="place-self: stretch">foo bar</div>
</div>

Sure, auto margins win in other layouts, but they win over both normal and stretch alignments.
I prefer abspos layout to be self-consistent rather than making only a few corner cases consistent with other layouts.

lando-prod-mozilla bot pushed a commit to mozilla-firefox/firefox that referenced this issue May 12, 2025
…to margins.,

Automatic update from web-platform-tests
[abspos] Only stretch when we have no auto margins.

As discussed in:
w3c/csswg-drafts#11195 (comment)
(See detailed discussion).

Fixed: 413018662
Change-Id: I97951025fb6711f2470a6271ed86ca8523bf9bee
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6499966
Reviewed-by: David Grogan <dgrogan@chromium.org>
Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org>
Commit-Queue: David Grogan <dgrogan@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1453678}

--

wpt-commits: 8034ca8ebef89fb611ef9c31ac7cb63ad675cbd2
wpt-pr: 52261

Differential Revision: https://phabricator.services.mozilla.com/D248749
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue May 12, 2025
…to margins.,

Automatic update from web-platform-tests
[abspos] Only stretch when we have no auto margins.

As discussed in:
w3c/csswg-drafts#11195 (comment)
(See detailed discussion).

Fixed: 413018662
Change-Id: I97951025fb6711f2470a6271ed86ca8523bf9bee
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6499966
Reviewed-by: David Grogan <dgrogan@chromium.org>
Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org>
Commit-Queue: David Grogan <dgrogan@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1453678}

--

wpt-commits: 8034ca8ebef89fb611ef9c31ac7cb63ad675cbd2
wpt-pr: 52261

Differential Revision: https://phabricator.services.mozilla.com/D248749
@fantasai
Copy link
Collaborator

I prefer abspos layout to be self-consistent rather than making only a few corner cases consistent with other layouts.

If we make stretch win over auto margins, then it becomes inconsistent with all of the other alignment values which do not win over auto margins.

If we make all alignment values win over auto margins, then we make alignment vs margins inconsistent between abspos and all other layout models (not just a few corner cases).

The last option is the one we have here, which is that auto margins consistently win over alignment values, except that normal behavior is weird.

There is no fully consistent behavior, so the question is, which is the one we want?

@Loirooriol
Copy link
Contributor

it becomes inconsistent with all of the other alignment values which do not win over auto margins.

You can see it in a different way. Ignoring float details from #9963,

  • Self-alignment properties can have 2 different effects:
    • They can force the automatic size to be fit-content
    • They align the margin box
  • Auto margins can have 2 different effects:
    • They can force the automatic size to be fit-content
    • They align the border box by modifying the size of the margin box

So it's not really a matter of which wins. If neither stretch alignment nor auto margins force a fit-content size, then neither alignment effect will be observable. If other alignment values force a fit-content size, then auto margins can take the free space, and then aligning the margin box is not observable. Doesn't seem self-inconsistent to me.

inconsistent between abspos and all other layout models

It would be consistent with block-level layout, where auto margins do not prevent justify-self: normal/stretch from stretching.

For other values it needs to be confirmed in #12102, but I would say that again abspos and block-level layouts should be consistent.

gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this issue May 14, 2025
…to margins.,

Automatic update from web-platform-tests
[abspos] Only stretch when we have no auto margins.

As discussed in:
w3c/csswg-drafts#11195 (comment)
(See detailed discussion).

Fixed: 413018662
Change-Id: I97951025fb6711f2470a6271ed86ca8523bf9bee
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6499966
Reviewed-by: David Grogan <dgroganchromium.org>
Commit-Queue: Ian Kilpatrick <ikilpatrickchromium.org>
Commit-Queue: David Grogan <dgroganchromium.org>
Cr-Commit-Position: refs/heads/main{#1453678}

--

wpt-commits: 8034ca8ebef89fb611ef9c31ac7cb63ad675cbd2
wpt-pr: 52261

Differential Revision: https://phabricator.services.mozilla.com/D248749

UltraBlame original commit: 2f47362523d8963bdfd33d327ed3ae6626e077d8
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this issue May 14, 2025
…to margins.,

Automatic update from web-platform-tests
[abspos] Only stretch when we have no auto margins.

As discussed in:
w3c/csswg-drafts#11195 (comment)
(See detailed discussion).

Fixed: 413018662
Change-Id: I97951025fb6711f2470a6271ed86ca8523bf9bee
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6499966
Reviewed-by: David Grogan <dgroganchromium.org>
Commit-Queue: Ian Kilpatrick <ikilpatrickchromium.org>
Commit-Queue: David Grogan <dgroganchromium.org>
Cr-Commit-Position: refs/heads/main{#1453678}

--

wpt-commits: 8034ca8ebef89fb611ef9c31ac7cb63ad675cbd2
wpt-pr: 52261

Differential Revision: https://phabricator.services.mozilla.com/D248749

UltraBlame original commit: 2f47362523d8963bdfd33d327ed3ae6626e077d8
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this issue May 14, 2025
…to margins.,

Automatic update from web-platform-tests
[abspos] Only stretch when we have no auto margins.

As discussed in:
w3c/csswg-drafts#11195 (comment)
(See detailed discussion).

Fixed: 413018662
Change-Id: I97951025fb6711f2470a6271ed86ca8523bf9bee
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6499966
Reviewed-by: David Grogan <dgroganchromium.org>
Commit-Queue: Ian Kilpatrick <ikilpatrickchromium.org>
Commit-Queue: David Grogan <dgroganchromium.org>
Cr-Commit-Position: refs/heads/main{#1453678}

--

wpt-commits: 8034ca8ebef89fb611ef9c31ac7cb63ad675cbd2
wpt-pr: 52261

Differential Revision: https://phabricator.services.mozilla.com/D248749

UltraBlame original commit: 2f47362523d8963bdfd33d327ed3ae6626e077d8
@fantasai
Copy link
Collaborator

If neither stretch alignment nor auto margins force a fit-content size, then neither alignment effect will be observable.

This is not true. The box may have a non-stretch-fit size, in which case alignment is observable.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-position-3] Absolute positioning - Is the new inset & auto-size behaviour web-compatible?, and agreed to the following:

  • RESOLVED: change stretch alignment case to allow the size to stretch when the normal alignment case allows stretching
The full IRC log of that discussion <emilio> oriol: this was discussed a few weeks ago and I couldn't attend
<emilio> ... not sure if the consequences of the resolution were fully understood
<miriam> present
<emilio> ... the implication is that you can have an abspos with auto margins that if it has normal alignment it'd stretch, but if you change self-alignment to be stretch, then it will stop stretching
<emilio> ... I think that doesn't really make sense and would just cause confusion
<emilio> ... in flex and grid auto margins don't stretch even if they have stretch alignment
<emilio> ... but this happens both for stretch and normal alignment
<emilio> ... so I think it's better to have abspos be consistent
<emilio> ... and avoid having the align-self: stretch align with flex / grid
<emilio> ... also the argument for making consistent with flex/grid feels weak
<emilio> ... in block layout auto margins don't prevent block level items
<emilio> ... from stretching
<emilio> ... so I'd like to change the previous resolution
<emilio> ... so that if they stretch with normal alignment they also stretch with stretch alignment
<emilio> fantasai: whichever way we go we are going to introduce inconsistencies
<emilio> ... in terms of alignment I think being consistent with flex/grid is more important because that's what authors are used to
<emilio> ... in block layout only blink has implemented and it's very recent so we can probably change it
<emilio> ... for normal we're stuck with css2, but for the other keywords it'd introduce inconsistencies
<emilio> ... are you proposing that auto margins are stronger than centering in flex/grid but not abspos? That seems like a bad idea
<emilio> ... I think maybe changing stretch only is better than the current situation, I admit it's quite weird that stretch is less stretchy than normal
<fantasai> s/I think//
<emilio> oriol: not sure the right way to look at this is props winning over other
<emilio> ... the way i see it is both margin and alignment have some effect simultaneously
<emilio> ... e.g. both may affect the auto size to be fit-content
<emilio> ... also auto-margins work by changing the margin box and alignment works in terms of that box
<emilio> ... so if you have auto margins that fills the whole container alignment won't do anything, but it's not like it is disabled
<emilio> ... it's more like it doesn't matter which value you use
<emilio> ... whether we decide that self-alignment forces auto size to be fit-content or auto margins do that I think it's independent decisions
<emilio> ... and it's not like some values win and they don't
<emilio> s/they/don't
<emilio> s/they/some
<emilio> ... e.g. even tho in flex and grid auto margins prevent stretching
<emilio> ... then center alignment could prevent stretching even with a 0 margin
<emilio> ... so we could say that center alignment is "winning" over the 0 margin
<emilio> ... so what wins and loses can be subjective
<emilio> ... I prefer seeing it as different things applying simultaneously
<emilio> fantasai: so iiuc, if you have auto margins and stretch, the first thing you do is stretch
<emilio> ... then auto margins end up having no effect (unless max-size is involved)
<emilio> oriol: exactly
<emilio> ... so in this case for abspos neither auto margins nor stretch alignment force fit-content size (so it can stretch)
<emilio> ... typically alignments won't matter because auto margins will resolve to 0 and then alignment would do nothing
<emilio> ... but if you have a max-size then you can align stuff using the alignment properties
<emilio> fantasai: I think that makes sense. There's a weird clause about negative and auto in this case, need to go back and check, but should be fine
<emilio> astearns: so prev resolution is no change to the spec, what should the spec say
<emilio> oriol: a way to word could be "change stretch alignment case to allow the size to stretch when the normal alignment case allows stretching"
<emilio> astearns: makes sense, wdyt fantasai?
<emilio> fantasai: yeah
<emilio> +1
<emilio> RESOLVED: change stretch alignment case to allow the size to stretch when the normal alignment case allows stretching

@bfgeek
Copy link

bfgeek commented May 14, 2025

@fantasai @Loirooriol - Is it correct under the above resolution, tables should have the old behaviour? E.g.

https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=13785

<!DOCTYPE html>
<style>
.cb {
  width: 100px;
  height: 100px;
  display: inline-block;
  position: relative;
  border: solid 3px;
}
table {
  position: absolute;
  min-width: 20px;
  min-height: 20px;
  background: lime;
  margin: auto;
  inset: 0;
}
</style>
<div class="cb">
  <table style="align-self: normal; justify-self: normal;"></table>
</div>
<div class="cb">
  <table style="align-self: stretch; justify-self: stretch;"></table>
</div>

@Loirooriol
Copy link
Contributor

Oh, yeah, I failed to consider tables and replaced elements when summarizing the proposed resolution, but I guess they should be covered too.

So basically https://drafts.csswg.org/css-position/#abspos-auto-size should be changed as follows:

The automatic size of an absolutely positioned box is resolved against its inset-modified containing block as follows:

If its self-alignment property in the relevant axis is stretch and neither of its inset properties nor margins in that axis are auto

Or if it is normal and the box is non-replaced, not a table wrapper box, and has no auto inset in the relevant axis

Its automatic size is its stretch-fit size.

Otherwise

Its automatic size is its fit-content size.

@bfgeek
Copy link

bfgeek commented May 14, 2025

Sounds good. Tables stretching is this case is more consistent IMO.

i3roly pushed a commit to i3roly/firefox-dynasty that referenced this issue May 15, 2025
…to margins.,

Automatic update from web-platform-tests
[abspos] Only stretch when we have no auto margins.

As discussed in:
w3c/csswg-drafts#11195 (comment)
(See detailed discussion).

Fixed: 413018662
Change-Id: I97951025fb6711f2470a6271ed86ca8523bf9bee
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6499966
Reviewed-by: David Grogan <dgrogan@chromium.org>
Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org>
Commit-Queue: David Grogan <dgrogan@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1453678}

--

wpt-commits: 8034ca8ebef89fb611ef9c31ac7cb63ad675cbd2
wpt-pr: 52261

Differential Revision: https://phabricator.services.mozilla.com/D248749
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Regular agenda
Status: Regular agenda items
Development

No branches or pull requests

7 participants