You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[CSS2][css-position-3] Negative containing blocks and auto margins #11478
Alan Baradlay noticed that we have an incompatibility between browsers in the case of a negative containing block and block-axis auto margins. Example:
This creates a 20px orange abspos inside a 100x100 containing block, with auto margins on all sides.
But the insets are 90px, which means the inset-modified containing block would be a negative size.
CSS2 defines the vertical-axis positioning rules in terms of an equation in section 10.6.4, which results in this box being centered.
Position 3 defines a slightly different behavior. First, the negative-size IMCB is adjusted to zero-size by altering the weaker inset in section 3.5.1. Then, auto margins get an equal negative size, centering the element on the IMCB in section 4.2. (In the inline axis the spec instead start-aligns the item into the IMCB, presumably to match the asymmetry of CSS2.)
WebKit currently exhibits the CSS2 behavior, while Firefox and Chrome exhibit the css-position-3 behavior.
The difference between the two specs was not intentional. What should we do?
The Houdini Task Force just discussed [CSS2][css-position-3] Negative containing blocks and `auto` margins, and agreed to the following:
RESOLVED: the IMCB size is floored at zero by adjusting weaker inset
RESOLVED: we center in block axis and safe align in inline axis
The full IRC log of that discussion
<alisonmaher> TabAtkins: if your CB is negatively sized
<alisonmaher> ...how does it interact with auto margins and sizes
<alisonmaher> ...CSS2 definition is bad and inconsistent implementations
<alisonmaher> ...what do we want?
<alisonmaher> ...CSS2 has diff behavior dependinding on H/V axis. We think that was an accident. Copy and paste error?
<alisonmaher> iank_: the diff is with auto margins in one axis is safe, and other axis is not
<alisonmaher> iank_: required by web compat
<oriol> q+
<alisonmaher> TabAtkins: maybe, but not consistent across browsers
<alisonmaher> oriol: prob web compat. If IMCB is negative ?? if abspos is big enough, then all browser agree
<alisonmaher> ...in the case where subtract index, the IMCB can be negative, servo and blink disagree. blink clamps
<alisonmaher> ...I could align with either. Ian doesn't want it to go negative
<alisonmaher> ...ok with that
<alisonmaher> TabAtkins: cool with clamping sizes to not be negative
<alisonmaher> PROPOSED: the IMCB size is floored at zero by adjusting weaker axis
<fantasai> s/axis/inset
<alisonmaher> iank_: agree, a mess otherwise
<alisonmaher> TabAtkins: objections?
<alisonmaher> RESOLVED: the IMCB size is floored at zero by adjusting weaker inset
<alisonmaher> TabAtkins: if the CB is positive but too small, there is interop
<alisonmaher> oriol: I believe so
<alisonmaher> ....you may have IMCB that is non-negative, but abspos overflows, in one axis you do one thing and another in the other
<alisonmaher> ...I recall an issue when inconsistency between browsers with orthogonal flows but eventually agree
<alisonmaher> fantasai: weaker in block axis?
<alisonmaher> ...shouldn't depend on direction. Should be inline vs block
<fantasai> s/direction/physical axis/
<alisonmaher> TabAtkins: we center in block axis and safe align in inline axis
<alisonmaher> RESOLVED: we center in block axis and safe align in inline axis
<oriol> https://github.com//issues/5374
the IMCB size is floored at zero by adjusting weaker inset
This made me think that I had only considered sizing, not alignment. And turns out we will need to discuss this again, because Blink is only flooring the IMCB by zero when resolving auto margins or auto sizes. But it's not doing so when aligning:
The CSS Working Group just discussed [CSS2][css-position-3] Negative containing blocks and `auto` margins, and agreed to the following:
RESOLVED: close with previous resolution accepted
The full IRC log of that discussion
<noamr> oriol: we resolved this issue in Paris. when the inset is big enough so that the containing block is negative, what should happen? browsers seem inconsistent. Servo allows it to have a negative size. We resolved to go with the blink way. but we implemented it in servo we realized that blink it does this for sizing, auto sizing and margin, but for alignment it uses negative size inset-modified containing block
<noamr> iank_: it's not what's happening in blink
<noamr> iank_: it's a bug in blink. when we clamp the IMCP we have 3 options. adjust end inset, start inset, or both
<noamr> iank_: we shift the inset based on alignment to be negative
<noamr> iank_: the other option is to take the dominant side and always do that. blink always has a positive IMCP for alignment
<noamr> iank_: the other option is just to take the dominant side based on writing mode and direction. I think we resolved on that.
<noamr> oriol: we resolved on aligning with blink and then I found a case where this is different. no strong opinion
<noamr> iank_: I am fine with changing this
<astearns> ack fantasai
<noamr> fantasai: between blink and resolved behavior, no strong opinion. unlikely people would intentionally run into this. intuition from authoring perspective anyone?
<noamr> iank_: I want to clamp the negative size to non-negative
<noamr> astearns: keep resolution and consider it a bug in blink; or amend it slightly to specify blink's current behavior
<noamr> PROPOSED RESOLUTION: close with previous resolution accepted
<noamr> RESOLVED: close with previous resolution accepted
Activity
Loirooriol commentedon Jan 10, 2025
I'm seeing something different:
bfgeek commentedon Jan 13, 2025
The difference in axis behaviour in Blink is due to the (compat required) difference in auto margins. See:
https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/layout/absolute_utils.cc;l=276-279?q=is_block_direction&ss=chromium
(In the block-direction of the child auto-margins are "unsafe", in the inline-direction they are "safe").
https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=13386
Gecko & Blink match behaviour in the above case, Firefox appears to change its behaviour based on if the width/height & min-width/min-height are auto. E.g.
https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=13387
Safari starts to match Servo in the above case.
Blink is consistent in behaviour across the different cases.
Loirooriol commentedon Jan 13, 2025
Gecko
Servo
Loirooriol commentedon Aug 5, 2025
It's not just
automargins, it's also not interoperable what happens with a negative inset-modified cb andautosizes.Aligning Servo with Blink is quite straightforward, just a matter of flooring the size of the IMCB so that it doesn't get negative.
Other browsers seem less consistent, so I prefer either the Servo or the Blink behaviors.
1 remaining item
css-meeting-bot commentedon Aug 21, 2025
The Houdini Task Force just discussed
[CSS2][css-position-3] Negative containing blocks and `auto` margins, and agreed to the following:RESOLVED: the IMCB size is floored at zero by adjusting weaker insetRESOLVED: we center in block axis and safe align in inline axisThe full IRC log of that discussion
<alisonmaher> TabAtkins: if your CB is negatively sized<alisonmaher> ...how does it interact with auto margins and sizes
<alisonmaher> ...CSS2 definition is bad and inconsistent implementations
<alisonmaher> ...what do we want?
<alisonmaher> ...CSS2 has diff behavior dependinding on H/V axis. We think that was an accident. Copy and paste error?
<alisonmaher> iank_: the diff is with auto margins in one axis is safe, and other axis is not
<alisonmaher> iank_: required by web compat
<oriol> q+
<alisonmaher> TabAtkins: maybe, but not consistent across browsers
<alisonmaher> oriol: prob web compat. If IMCB is negative ?? if abspos is big enough, then all browser agree
<alisonmaher> ...in the case where subtract index, the IMCB can be negative, servo and blink disagree. blink clamps
<alisonmaher> ...I could align with either. Ian doesn't want it to go negative
<alisonmaher> ...ok with that
<alisonmaher> TabAtkins: cool with clamping sizes to not be negative
<alisonmaher> PROPOSED: the IMCB size is floored at zero by adjusting weaker axis
<fantasai> s/axis/inset
<alisonmaher> iank_: agree, a mess otherwise
<alisonmaher> TabAtkins: objections?
<alisonmaher> RESOLVED: the IMCB size is floored at zero by adjusting weaker inset
<alisonmaher> TabAtkins: if the CB is positive but too small, there is interop
<alisonmaher> oriol: I believe so
<alisonmaher> ....you may have IMCB that is non-negative, but abspos overflows, in one axis you do one thing and another in the other
<alisonmaher> ...I recall an issue when inconsistency between browsers with orthogonal flows but eventually agree
<alisonmaher> fantasai: weaker in block axis?
<alisonmaher> ...shouldn't depend on direction. Should be inline vs block
<fantasai> s/direction/physical axis/
<alisonmaher> TabAtkins: we center in block axis and safe align in inline axis
<alisonmaher> RESOLVED: we center in block axis and safe align in inline axis
<oriol> https://github.com//issues/5374
Loirooriol commentedon Aug 22, 2025
This made me think that I had only considered sizing, not alignment. And turns out we will need to discuss this again, because Blink is only flooring the IMCB by zero when resolving auto margins or auto sizes. But it's not doing so when aligning:
So arguably the only self-consistent browser is Servo.
css-meeting-bot commentedon Nov 14, 2025
The CSS Working Group just discussed
[CSS2][css-position-3] Negative containing blocks and `auto` margins, and agreed to the following:RESOLVED: close with previous resolution acceptedThe full IRC log of that discussion
<noamr> oriol: we resolved this issue in Paris. when the inset is big enough so that the containing block is negative, what should happen? browsers seem inconsistent. Servo allows it to have a negative size. We resolved to go with the blink way. but we implemented it in servo we realized that blink it does this for sizing, auto sizing and margin, but for alignment it uses negative size inset-modified containing block<noamr> iank_: it's not what's happening in blink
<noamr> iank_: it's a bug in blink. when we clamp the IMCP we have 3 options. adjust end inset, start inset, or both
<noamr> iank_: we shift the inset based on alignment to be negative
<noamr> iank_: the other option is to take the dominant side and always do that. blink always has a positive IMCP for alignment
<noamr> iank_: the other option is just to take the dominant side based on writing mode and direction. I think we resolved on that.
<noamr> oriol: we resolved on aligning with blink and then I found a case where this is different. no strong opinion
<noamr> iank_: I am fine with changing this
<astearns> ack fantasai
<noamr> fantasai: between blink and resolved behavior, no strong opinion. unlikely people would intentionally run into this. intuition from authoring perspective anyone?
<noamr> iank_: I want to clamp the negative size to non-negative
<noamr> astearns: keep resolution and consider it a bug in blink; or amend it slightly to specify blink's current behavior
<noamr> PROPOSED RESOLUTION: close with previous resolution accepted
<noamr> RESOLVED: close with previous resolution accepted
layout: Adjust inset-modified containing block to have non-negative s…
layout: Adjust inset-modified containing block to have non-negative s…
[css-position-3] Clarify that the IMCB size is floored to 0. #11478