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 · 10 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 <[email protected]>
Commit-Queue: Ian Kilpatrick <[email protected]>
Commit-Queue: David Grogan <[email protected]>
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 <[email protected]>
Commit-Queue: Ian Kilpatrick <[email protected]>
Commit-Queue: David Grogan <[email protected]>
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 <[email protected]>
Commit-Queue: Ian Kilpatrick <[email protected]>
Commit-Queue: David Grogan <[email protected]>
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.

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

6 participants