Respect auto margins on overflowing grid items
This commit is contained in:
1 parent
71193faddf
commit
6dec05f171
2 files changed
+130
-1
No files matched your search
@@ -10345,6 +10345,57 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn overflowing_grid_item_auto_margins_use_safe_logical_start() {
|
||||||
|
let tree = parse_html(
|
||||||
|
r#"<style>
|
||||||
|
html,body{margin:0}
|
||||||
|
.grid{display:grid;grid-template-columns:300px;grid-template-rows:20px;width:300px;position:relative}
|
||||||
|
.item{height:20px}
|
||||||
|
.wide{width:600px;height:1px}
|
||||||
|
.left{margin-left:auto}
|
||||||
|
.both{margin-left:auto;margin-right:auto}
|
||||||
|
.center{justify-self:center}
|
||||||
|
.end{justify-self:end}
|
||||||
|
.absolute{position:absolute;grid-area:1/1;width:600px;height:20px}
|
||||||
|
</style>
|
||||||
|
<div id="ltr-center-grid" class="grid"><div id="ltr-center" class="item left center"><div class="wide"></div></div></div>
|
||||||
|
<div id="ltr-end-grid" class="grid"><div id="ltr-end" class="item both end"><div class="wide"></div></div></div>
|
||||||
|
<div id="absolute-center-grid" class="grid"><div id="absolute-center" class="absolute left center"></div></div>
|
||||||
|
<div id="absolute-end-grid" class="grid"><div id="absolute-end" class="absolute left end"></div></div>"#,
|
||||||
|
);
|
||||||
|
let laid = layout_dom(&tree, (800.0, 300.0));
|
||||||
|
let rect = |id: &str| laid.rects[&tree.get_element_by_id(id).unwrap()];
|
||||||
|
|
||||||
|
for (grid_id, item_id, expected_x) in [
|
||||||
|
("ltr-center-grid", "ltr-center", 0.0),
|
||||||
|
("ltr-end-grid", "ltr-end", 0.0),
|
||||||
|
] {
|
||||||
|
let grid = rect(grid_id);
|
||||||
|
let item = rect(item_id);
|
||||||
|
assert!(
|
||||||
|
(item.width - 600.0).abs() < 0.01,
|
||||||
|
"{item_id} lost its min-content floor: {item:?}"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
(item.x - grid.x - expected_x).abs() < 0.01,
|
||||||
|
"{item_id} did not use safe logical-start overflow: grid={grid:?} item={item:?}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (grid_id, item_id, expected_x) in [
|
||||||
|
("absolute-center-grid", "absolute-center", -150.0),
|
||||||
|
("absolute-end-grid", "absolute-end", -300.0),
|
||||||
|
] {
|
||||||
|
let grid = rect(grid_id);
|
||||||
|
let item = rect(item_id);
|
||||||
|
assert!(
|
||||||
|
(item.x - grid.x - expected_x).abs() < 0.01,
|
||||||
|
"{item_id} incorrectly used the in-flow auto-margin fallback: grid={grid:?} item={item:?}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn root_and_body_inline_outer_geometry_matches_blockification_rules() {
|
fn root_and_body_inline_outer_geometry_matches_blockification_rules() {
|
||||||
for display in ["inline-block", "inline-flex", "inline-grid"] {
|
for display in ["inline-block", "inline-flex", "inline-grid"] {
|
||||||
|
|||||||
+79
-1
@@ -370,7 +370,20 @@ pub(super) fn align_item_within_area(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let overflows = resolved_size + non_auto_margin.sum() > grid_area_size;
|
let overflows = resolved_size + non_auto_margin.sum() > grid_area_size;
|
||||||
let alignment_keyword = resolve_self_alignment_safety(alignment_style, overflows);
|
// In-flow auto margins take precedence over self-alignment and are always
|
||||||
|
// safe. When the item overflows there is no positive free space for the
|
||||||
|
// auto margins to absorb, so safe alignment falls back to the logical
|
||||||
|
// start edge rather than honoring an authored unsafe center/end alignment.
|
||||||
|
// Absolutely positioned items use their authored self-alignment here;
|
||||||
|
// their auto margins are resolved by the abs-pos constraint equation.
|
||||||
|
let alignment_keyword = if position != Position::Absolute
|
||||||
|
&& auto_margin_count > 0
|
||||||
|
&& overflows
|
||||||
|
{
|
||||||
|
AlignItemsKeyword::Start
|
||||||
|
} else {
|
||||||
|
resolve_self_alignment_safety(alignment_style, overflows)
|
||||||
|
};
|
||||||
|
|
||||||
// Compute offset in the axis
|
// Compute offset in the axis
|
||||||
let alignment_based_offset = match alignment_keyword {
|
let alignment_based_offset = match alignment_keyword {
|
||||||
@@ -612,4 +625,69 @@ mod tests {
|
|||||||
);
|
);
|
||||||
assert_eq!(content_box_max, 290.0);
|
assert_eq!(content_box_max, 290.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn overflowing_auto_margins_override_unsafe_self_alignment() {
|
||||||
|
let area = Line { start: 0.0, end: 300.0 };
|
||||||
|
let oversized = 600.0;
|
||||||
|
let margin_cases = [
|
||||||
|
Line { start: None, end: Some(0.0) },
|
||||||
|
Line { start: Some(0.0), end: None },
|
||||||
|
Line { start: None, end: None },
|
||||||
|
];
|
||||||
|
|
||||||
|
for alignment in [AlignSelf::CENTER, AlignSelf::END] {
|
||||||
|
for margin in margin_cases {
|
||||||
|
let (ltr_start, ltr_margin) = super::align_item_within_area(
|
||||||
|
area,
|
||||||
|
alignment,
|
||||||
|
oversized,
|
||||||
|
Position::Relative,
|
||||||
|
Line { start: None, end: None },
|
||||||
|
margin,
|
||||||
|
0.0,
|
||||||
|
crate::Direction::Ltr,
|
||||||
|
);
|
||||||
|
assert_eq!(ltr_start, 0.0);
|
||||||
|
assert_eq!(ltr_margin, Line { start: 0.0, end: 0.0 });
|
||||||
|
|
||||||
|
let (rtl_start, rtl_margin) = super::align_item_within_area(
|
||||||
|
area,
|
||||||
|
alignment,
|
||||||
|
oversized,
|
||||||
|
Position::Relative,
|
||||||
|
Line { start: None, end: None },
|
||||||
|
margin,
|
||||||
|
0.0,
|
||||||
|
crate::Direction::Rtl,
|
||||||
|
);
|
||||||
|
assert_eq!(rtl_start, -300.0);
|
||||||
|
assert_eq!(rtl_margin, Line { start: 0.0, end: 0.0 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let (absolute_center, _) = super::align_item_within_area(
|
||||||
|
area,
|
||||||
|
AlignSelf::CENTER,
|
||||||
|
oversized,
|
||||||
|
Position::Absolute,
|
||||||
|
Line { start: None, end: None },
|
||||||
|
Line { start: None, end: Some(0.0) },
|
||||||
|
0.0,
|
||||||
|
crate::Direction::Ltr,
|
||||||
|
);
|
||||||
|
assert_eq!(absolute_center, -150.0);
|
||||||
|
|
||||||
|
let (absolute_end, _) = super::align_item_within_area(
|
||||||
|
area,
|
||||||
|
AlignSelf::END,
|
||||||
|
oversized,
|
||||||
|
Position::Absolute,
|
||||||
|
Line { start: None, end: None },
|
||||||
|
Line { start: None, end: Some(0.0) },
|
||||||
|
0.0,
|
||||||
|
crate::Direction::Ltr,
|
||||||
|
);
|
||||||
|
assert_eq!(absolute_end, -300.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user