Fix alignment of abspos child of flexbox with flipped direction (#34426)

The containing block for the static position of an absolutely positioned
element in flex layout is established by the flex container. However, if
the flex container has static position, the actual containing block will
be established by another ancestor.

If the flex container and the containing block have different directions,
the static position needs especial handling when aligning the abspos.
We were already trying to do so with the `flip_anchor` flag, but there
were bugs.

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Oriol Brufau 2024-11-30 15:25:10 +01:00 committed by GitHub
parent 3b5ffabbca
commit f2b5f515d7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 66 additions and 374 deletions

View file

@ -833,7 +833,11 @@ impl<'a> AbsoluteAxisSolver<'a> {
self.box_offsets.end.non_auto(), self.box_offsets.end.non_auto(),
) { ) {
(None, None) => solve_for_anchor(if self.flip_anchor { (None, None) => solve_for_anchor(if self.flip_anchor {
Anchor::End(self.containing_size - self.static_position_rect_axis.origin) Anchor::End(
self.containing_size -
self.static_position_rect_axis.origin -
self.static_position_rect_axis.length,
)
} else { } else {
Anchor::Start(self.static_position_rect_axis.origin) Anchor::Start(self.static_position_rect_axis.origin)
}), }),
@ -911,40 +915,58 @@ impl<'a> AbsoluteAxisSolver<'a> {
} }
fn origin_for_alignment_or_justification(&self, margin_box_axis: RectAxis) -> Option<Au> { fn origin_for_alignment_or_justification(&self, margin_box_axis: RectAxis) -> Option<Au> {
let alignment_container = match ( let (alignment_container, flip_anchor) = match (
self.box_offsets.start.non_auto(), self.box_offsets.start.non_auto(),
self.box_offsets.end.non_auto(), self.box_offsets.end.non_auto(),
) { ) {
(None, None) => self.static_position_rect_axis, (None, None) => (self.static_position_rect_axis, self.flip_anchor),
(Some(start), Some(end)) => { (Some(start), Some(end)) => {
let start = start.to_used_value(self.containing_size); let start = start.to_used_value(self.containing_size);
let end = end.to_used_value(self.containing_size); let end = end.to_used_value(self.containing_size);
let alignment_container = RectAxis {
RectAxis {
origin: start, origin: start,
length: self.containing_size - (end + start), length: self.containing_size - (end + start),
} };
(alignment_container, false)
}, },
_ => return None, _ => return None,
}; };
let mut value_after_safety = self.alignment.value(); // Here we resolve the alignment to either start, center, or end.
if self.alignment.flags() == AlignFlags::SAFE && // Note we need to handle both self-alignment values (when some inset isn't auto)
margin_box_axis.length > alignment_container.length // and distributed alignment values (when both insets are auto).
// The latter are treated as their fallback alignment.
let alignment = match self.alignment.value() {
// https://drafts.csswg.org/css-align/#valdef-self-position-end
// https://drafts.csswg.org/css-align/#valdef-self-position-flex-end
AlignFlags::END | AlignFlags::FLEX_END => AlignFlags::END,
// https://drafts.csswg.org/css-align/#valdef-self-position-center
// https://drafts.csswg.org/css-align/#valdef-align-content-space-around
// https://drafts.csswg.org/css-align/#valdef-align-content-space-evenly
AlignFlags::CENTER | AlignFlags::SPACE_AROUND | AlignFlags::SPACE_EVENLY => {
AlignFlags::CENTER
},
// TODO(#34282): handle missing values: self-start, self-end, left, right.
_ => AlignFlags::START,
};
if alignment == AlignFlags::START ||
self.alignment.flags() == AlignFlags::SAFE &&
margin_box_axis.length > alignment_container.length
{ {
value_after_safety = AlignFlags::START; // Aligning to start is no-op, so just return `None`. This should be equivalent
// to returning `Some(alignment_container.origin + free_space)` if `flip_anchor`,
// or `Some(alignment_container.origin)` otherwise.
return None;
} }
match value_after_safety { let free_space = alignment_container.length - margin_box_axis.length;
AlignFlags::CENTER | AlignFlags::SPACE_AROUND | AlignFlags::SPACE_EVENLY => Some( Some(match alignment {
alignment_container.origin + AlignFlags::CENTER => alignment_container.origin + free_space / 2,
((alignment_container.length - margin_box_axis.length) / 2), AlignFlags::END if flip_anchor => alignment_container.origin,
), AlignFlags::END => alignment_container.origin + free_space,
AlignFlags::FLEX_END | AlignFlags::END => Some( _ => unreachable!(),
alignment_container.origin + alignment_container.length - margin_box_axis.length, })
),
_ => None,
}
} }
fn solve_alignment( fn solve_alignment(

View file

@ -8,12 +8,6 @@
[.flexbox 37] [.flexbox 37]
expected: FAIL expected: FAIL
[.flexbox 30]
expected: FAIL
[.flexbox 32]
expected: FAIL
[.flexbox 33] [.flexbox 33]
expected: FAIL expected: FAIL
@ -32,24 +26,9 @@
[.flexbox 85] [.flexbox 85]
expected: FAIL expected: FAIL
[.flexbox 86]
expected: FAIL
[.flexbox 16]
expected: FAIL
[.flexbox 14]
expected: FAIL
[.flexbox 13]
expected: FAIL
[.flexbox 96] [.flexbox 96]
expected: FAIL expected: FAIL
[.flexbox 94]
expected: FAIL
[.flexbox 93] [.flexbox 93]
expected: FAIL expected: FAIL
@ -74,9 +53,6 @@
[.flexbox 69] [.flexbox 69]
expected: FAIL expected: FAIL
[.flexbox 70]
expected: FAIL
[.flexbox 72] [.flexbox 72]
expected: FAIL expected: FAIL
@ -89,9 +65,6 @@
[.flexbox 77] [.flexbox 77]
expected: FAIL expected: FAIL
[.flexbox 78]
expected: FAIL
[.flexbox 45] [.flexbox 45]
expected: FAIL expected: FAIL
@ -107,15 +80,6 @@
[.flexbox 49] [.flexbox 49]
expected: FAIL expected: FAIL
[.flexbox 5]
expected: FAIL
[.flexbox 6]
expected: FAIL
[.flexbox 8]
expected: FAIL
[.flexbox 59] [.flexbox 59]
expected: FAIL expected: FAIL
@ -131,30 +95,6 @@
[.flexbox 57] [.flexbox 57]
expected: FAIL expected: FAIL
[.flexbox 29]
expected: FAIL
[.flexbox 24]
expected: FAIL
[.flexbox 22]
expected: FAIL
[.flexbox 21]
expected: FAIL
[.flexbox 7]
expected: FAIL
[.flexbox 15]
expected: FAIL
[.flexbox 23]
expected: FAIL
[.flexbox 31]
expected: FAIL
[.flexbox 34] [.flexbox 34]
expected: FAIL expected: FAIL
@ -179,16 +119,16 @@
[.flexbox 64] [.flexbox 64]
expected: FAIL expected: FAIL
[.flexbox 71] [.flexbox 39]
expected: FAIL expected: FAIL
[.flexbox 79] [.flexbox 47]
expected: FAIL expected: FAIL
[.flexbox 87] [.flexbox 55]
expected: FAIL expected: FAIL
[.flexbox 95] [.flexbox 63]
expected: FAIL expected: FAIL
[.flexbox 38] [.flexbox 38]

View file

@ -14,18 +14,6 @@
[.flexbox 306] [.flexbox 306]
expected: FAIL expected: FAIL
[.flexbox 34]
expected: FAIL
[.flexbox 35]
expected: FAIL
[.flexbox 36]
expected: FAIL
[.flexbox 32]
expected: FAIL
[.flexbox 396] [.flexbox 396]
expected: FAIL expected: FAIL
@ -38,12 +26,6 @@
[.flexbox 392] [.flexbox 392]
expected: FAIL expected: FAIL
[.flexbox 393]
expected: FAIL
[.flexbox 391]
expected: FAIL
[.flexbox 399] [.flexbox 399]
expected: FAIL expected: FAIL
@ -68,18 +50,6 @@
[.flexbox 373] [.flexbox 373]
expected: FAIL expected: FAIL
[.flexbox 80]
expected: FAIL
[.flexbox 83]
expected: FAIL
[.flexbox 82]
expected: FAIL
[.flexbox 84]
expected: FAIL
[.flexbox 182] [.flexbox 182]
expected: FAIL expected: FAIL
@ -95,15 +65,6 @@
[.flexbox 184] [.flexbox 184]
expected: FAIL expected: FAIL
[.flexbox 118]
expected: FAIL
[.flexbox 119]
expected: FAIL
[.flexbox 116]
expected: FAIL
[.flexbox 238] [.flexbox 238]
expected: FAIL expected: FAIL
@ -119,15 +80,9 @@
[.flexbox 234] [.flexbox 234]
expected: FAIL expected: FAIL
[.flexbox 331]
expected: FAIL
[.flexbox 332] [.flexbox 332]
expected: FAIL expected: FAIL
[.flexbox 333]
expected: FAIL
[.flexbox 334] [.flexbox 334]
expected: FAIL expected: FAIL
@ -137,21 +92,6 @@
[.flexbox 338] [.flexbox 338]
expected: FAIL expected: FAIL
[.flexbox 45]
expected: FAIL
[.flexbox 44]
expected: FAIL
[.flexbox 46]
expected: FAIL
[.flexbox 43]
expected: FAIL
[.flexbox 48]
expected: FAIL
[.flexbox 248] [.flexbox 248]
expected: FAIL expected: FAIL
@ -170,30 +110,15 @@
[.flexbox 242] [.flexbox 242]
expected: FAIL expected: FAIL
[.flexbox 379]
expected: FAIL
[.flexbox 147] [.flexbox 147]
expected: FAIL expected: FAIL
[.flexbox 145] [.flexbox 145]
expected: FAIL expected: FAIL
[.flexbox 143]
expected: FAIL
[.flexbox 141]
expected: FAIL
[.flexbox 140]
expected: FAIL
[.flexbox 419] [.flexbox 419]
expected: FAIL expected: FAIL
[.flexbox 418]
expected: FAIL
[.flexbox 149] [.flexbox 149]
expected: FAIL expected: FAIL
@ -203,12 +128,6 @@
[.flexbox 370] [.flexbox 370]
expected: FAIL expected: FAIL
[.flexbox 371]
expected: FAIL
[.flexbox 381]
expected: FAIL
[.flexbox 380] [.flexbox 380]
expected: FAIL expected: FAIL
@ -251,36 +170,9 @@
[.flexbox 361] [.flexbox 361]
expected: FAIL expected: FAIL
[.flexbox 360]
expected: FAIL
[.flexbox 96]
expected: FAIL
[.flexbox 94]
expected: FAIL
[.flexbox 92]
expected: FAIL
[.flexbox 93]
expected: FAIL
[.flexbox 91]
expected: FAIL
[.flexbox 72]
expected: FAIL
[.flexbox 428]
expected: FAIL
[.flexbox 429] [.flexbox 429]
expected: FAIL expected: FAIL
[.flexbox 420]
expected: FAIL
[.flexbox 422] [.flexbox 422]
expected: FAIL expected: FAIL
@ -293,24 +185,6 @@
[.flexbox 427] [.flexbox 427]
expected: FAIL expected: FAIL
[.flexbox 108]
expected: FAIL
[.flexbox 103]
expected: FAIL
[.flexbox 106]
expected: FAIL
[.flexbox 105]
expected: FAIL
[.flexbox 104]
expected: FAIL
[.flexbox 323]
expected: FAIL
[.flexbox 322] [.flexbox 322]
expected: FAIL expected: FAIL
@ -329,18 +203,6 @@
[.flexbox 329] [.flexbox 329]
expected: FAIL expected: FAIL
[.flexbox 59]
expected: FAIL
[.flexbox 56]
expected: FAIL
[.flexbox 57]
expected: FAIL
[.flexbox 55]
expected: FAIL
[.flexbox 258] [.flexbox 258]
expected: FAIL expected: FAIL
@ -386,12 +248,6 @@
[.flexbox 178] [.flexbox 178]
expected: FAIL expected: FAIL
[.flexbox 11]
expected: FAIL
[.flexbox 19]
expected: FAIL
[.flexbox 213] [.flexbox 213]
expected: FAIL expected: FAIL
@ -419,12 +275,6 @@
[.flexbox 355] [.flexbox 355]
expected: FAIL expected: FAIL
[.flexbox 358]
expected: FAIL
[.flexbox 67]
expected: FAIL
[.flexbox 280] [.flexbox 280]
expected: FAIL expected: FAIL
@ -446,51 +296,18 @@
[.flexbox 359] [.flexbox 359]
expected: FAIL expected: FAIL
[.flexbox 132]
expected: FAIL
[.flexbox 130]
expected: FAIL
[.flexbox 131]
expected: FAIL
[.flexbox 139]
expected: FAIL
[.flexbox 317] [.flexbox 317]
expected: FAIL expected: FAIL
[.flexbox 315] [.flexbox 315]
expected: FAIL expected: FAIL
[.flexbox 312]
expected: FAIL
[.flexbox 313] [.flexbox 313]
expected: FAIL expected: FAIL
[.flexbox 310]
expected: FAIL
[.flexbox 311] [.flexbox 311]
expected: FAIL expected: FAIL
[.flexbox 69]
expected: FAIL
[.flexbox 24]
expected: FAIL
[.flexbox 23]
expected: FAIL
[.flexbox 22]
expected: FAIL
[.flexbox 21]
expected: FAIL
[.flexbox 269] [.flexbox 269]
expected: FAIL expected: FAIL
@ -509,9 +326,6 @@
[.flexbox 406] [.flexbox 406]
expected: FAIL expected: FAIL
[.flexbox 407]
expected: FAIL
[.flexbox 404] [.flexbox 404]
expected: FAIL expected: FAIL
@ -569,9 +383,6 @@
[.flexbox 345] [.flexbox 345]
expected: FAIL expected: FAIL
[.flexbox 344]
expected: FAIL
[.flexbox 347] [.flexbox 347]
expected: FAIL expected: FAIL
@ -584,12 +395,6 @@
[.flexbox 342] [.flexbox 342]
expected: FAIL expected: FAIL
[.flexbox 70]
expected: FAIL
[.flexbox 71]
expected: FAIL
[.flexbox 299] [.flexbox 299]
expected: FAIL expected: FAIL
@ -602,9 +407,6 @@
[.flexbox 297] [.flexbox 297]
expected: FAIL expected: FAIL
[.flexbox 296]
expected: FAIL
[.flexbox 295] [.flexbox 295]
expected: FAIL expected: FAIL
@ -614,15 +416,6 @@
[.flexbox 368] [.flexbox 368]
expected: FAIL expected: FAIL
[.flexbox 7]
expected: FAIL
[.flexbox 8]
expected: FAIL
[.flexbox 9]
expected: FAIL
[.flexbox 157] [.flexbox 157]
expected: FAIL expected: FAIL
@ -644,69 +437,6 @@
[.flexbox 408] [.flexbox 408]
expected: FAIL expected: FAIL
[.flexbox 120]
expected: FAIL
[.flexbox 127]
expected: FAIL
[.flexbox 129]
expected: FAIL
[.flexbox 10]
expected: FAIL
[.flexbox 12]
expected: FAIL
[.flexbox 20]
expected: FAIL
[.flexbox 31]
expected: FAIL
[.flexbox 33]
expected: FAIL
[.flexbox 47]
expected: FAIL
[.flexbox 58]
expected: FAIL
[.flexbox 60]
expected: FAIL
[.flexbox 68]
expected: FAIL
[.flexbox 79]
expected: FAIL
[.flexbox 81]
expected: FAIL
[.flexbox 95]
expected: FAIL
[.flexbox 107]
expected: FAIL
[.flexbox 115]
expected: FAIL
[.flexbox 117]
expected: FAIL
[.flexbox 128]
expected: FAIL
[.flexbox 142]
expected: FAIL
[.flexbox 144]
expected: FAIL
[.flexbox 146] [.flexbox 146]
expected: FAIL expected: FAIL
@ -809,58 +539,55 @@
[.flexbox 285] [.flexbox 285]
expected: FAIL expected: FAIL
[.flexbox 298] [.flexbox 154]
expected: FAIL expected: FAIL
[.flexbox 300] [.flexbox 156]
expected: FAIL expected: FAIL
[.flexbox 308] [.flexbox 164]
expected: FAIL expected: FAIL
[.flexbox 319] [.flexbox 175]
expected: FAIL expected: FAIL
[.flexbox 321] [.flexbox 177]
expected: FAIL expected: FAIL
[.flexbox 335] [.flexbox 191]
expected: FAIL expected: FAIL
[.flexbox 346] [.flexbox 202]
expected: FAIL expected: FAIL
[.flexbox 348] [.flexbox 204]
expected: FAIL expected: FAIL
[.flexbox 356] [.flexbox 212]
expected: FAIL expected: FAIL
[.flexbox 367] [.flexbox 223]
expected: FAIL expected: FAIL
[.flexbox 369] [.flexbox 225]
expected: FAIL expected: FAIL
[.flexbox 383] [.flexbox 239]
expected: FAIL expected: FAIL
[.flexbox 395] [.flexbox 251]
expected: FAIL expected: FAIL
[.flexbox 403] [.flexbox 259]
expected: FAIL expected: FAIL
[.flexbox 405] [.flexbox 261]
expected: FAIL expected: FAIL
[.flexbox 416] [.flexbox 272]
expected: FAIL expected: FAIL
[.flexbox 430] [.flexbox 286]
expected: FAIL
[.flexbox 432]
expected: FAIL expected: FAIL
[.flexbox 152] [.flexbox 152]
@ -916,3 +643,6 @@
[.flexbox 284] [.flexbox 284]
expected: FAIL expected: FAIL
[.flexbox 288]
expected: FAIL