diff --git a/components/layout_2020/taffy/layout.rs b/components/layout_2020/taffy/layout.rs index e5e27ffbf59..217a2a7f5de 100644 --- a/components/layout_2020/taffy/layout.rs +++ b/components/layout_2020/taffy/layout.rs @@ -27,7 +27,7 @@ use crate::geom::{ }; use crate::positioned::{AbsolutelyPositionedBox, PositioningContext, PositioningContextLength}; use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult}; -use crate::style_ext::LayoutStyle; +use crate::style_ext::{ComputedValuesExt, LayoutStyle}; use crate::{ConstraintSpace, ContainingBlock, ContainingBlockSize}; const DUMMY_NODE_ID: taffy::NodeId = taffy::NodeId::new(u64::MAX); @@ -67,7 +67,7 @@ struct TaffyContainerContext<'a> { style: &'a ComputedValues, specific_layout_info: Option, - /// Temporary location for children detailed info, which will be moved into child fragments + /// Temporary location for children specific info, which will be moved into child fragments child_specific_layout_infos: Vec>, } @@ -248,12 +248,15 @@ impl taffy::LayoutPartialTree for TaffyContainerContext<'_> { }, style, }; - let layout = { - let mut child_positioning_context = PositioningContext::new_for_subtree( - self.positioning_context - .collects_for_nearest_positioned_ancestor(), - ); + let mut child_positioning_context = + PositioningContext::new_for_style(style).unwrap_or_else(|| { + PositioningContext::new_for_subtree( + self.positioning_context + .collects_for_nearest_positioned_ancestor(), + ) + }); + let layout = non_replaced.layout( self.layout_context, &mut child_positioning_context, @@ -544,26 +547,44 @@ impl TaffyContainer { let child_specific_layout_info: Option = std::mem::take(&mut container_ctx.child_specific_layout_infos[child_id]); + let establishes_containing_block_for_absolute_descendants = + if let TaffyItemBoxInner::InFlowBox(independent_box) = &child.taffy_level_box { + child + .style + .establishes_containing_block_for_absolute_descendants( + independent_box.base_fragment_info().flags, + ) + } else { + false + }; + match &mut child.taffy_level_box { TaffyItemBoxInner::InFlowBox(independent_box) => { - let fragment = Fragment::Box(ArcRefCell::new( - BoxFragment::new( - independent_box.base_fragment_info(), - independent_box.style().clone(), - std::mem::take(&mut child.child_fragments), - content_size, - padding, - border, - margin, - None, /* clearance */ - collapsed_margin, - ) - .with_baselines(Baselines { - first: output.first_baselines.y.map(Au::from_f32_px), - last: None, - }) - .with_specific_layout_info(child_specific_layout_info), - )); + let mut box_fragment = BoxFragment::new( + independent_box.base_fragment_info(), + independent_box.style().clone(), + std::mem::take(&mut child.child_fragments), + content_size, + padding, + border, + margin, + None, /* clearance */ + collapsed_margin, + ) + .with_baselines(Baselines { + first: output.first_baselines.y.map(Au::from_f32_px), + last: None, + }) + .with_specific_layout_info(child_specific_layout_info); + + if establishes_containing_block_for_absolute_descendants { + child.positioning_context.layout_collected_children( + container_ctx.layout_context, + &mut box_fragment, + ); + } + + let fragment = Fragment::Box(ArcRefCell::new(box_fragment)); child .positioning_context diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json index 1c40da89e12..17c100c8ffd 100644 --- a/tests/wpt/meta/MANIFEST.json +++ b/tests/wpt/meta/MANIFEST.json @@ -189310,6 +189310,84 @@ {} ] ], + "grid-items-relative-positioned-containing-block-001.html": [ + "7683e485c05caea40361416bc533dc95fbfcd837", + [ + "css/css-grid/grid-items/grid-items-relative-positioned-containing-block-001.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "grid-items-relative-positioned-containing-block-002.html": [ + "1e7a754f74da30e327feb06e05527012d1a3917d", + [ + "css/css-grid/grid-items/grid-items-relative-positioned-containing-block-002.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "grid-items-relative-positioned-containing-block-003.html": [ + "be0305181914e9b872d0ef1bdc801f974c5918f7", + [ + "css/css-grid/grid-items/grid-items-relative-positioned-containing-block-003.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "grid-items-relative-positioned-containing-block-004.html": [ + "61d50a10c10290b55a7439d6b59528f01accc4bf", + [ + "css/css-grid/grid-items/grid-items-relative-positioned-containing-block-004.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "grid-items-relative-positioned-containing-block-005.html": [ + "4473cb8d2ba4ea847669cde34ce10e27e6bfb001", + [ + "css/css-grid/grid-items/grid-items-relative-positioned-containing-block-005.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "grid-items-relative-positioned-containing-block-006.html": [ + "79350eac516f2850545a6446f570c6c7778a4e3b", + [ + "css/css-grid/grid-items/grid-items-relative-positioned-containing-block-006.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "grid-items-sizing-alignment-001.html": [ "033d292ce61026251ada1812d195412e5d0f5672", [ @@ -425295,6 +425373,10 @@ "50x50-green.png": [ "f709bf09e5ae6bf48911b69691b0acb5c6f2760e", [] + ], + "grid-items-relative-positioned-containing-block.css": [ + "ccdecf612d65a6de843046a3a81b4a5488c3b4f3", + [] ] }, "whitespace-in-grid-item-001-ref.html": [ diff --git a/tests/wpt/tests/css/css-grid/grid-items/grid-items-relative-positioned-containing-block-001.html b/tests/wpt/tests/css/css-grid/grid-items/grid-items-relative-positioned-containing-block-001.html new file mode 100644 index 00000000000..7683e485c05 --- /dev/null +++ b/tests/wpt/tests/css/css-grid/grid-items/grid-items-relative-positioned-containing-block-001.html @@ -0,0 +1,20 @@ + + +CSS Grid Layout Test: Relative Positioned Grid Items as a Containing Block of Absolute Positioned Descendant + + + + + + + + + +

Test passes if there is a filled green square and no red.

+ +
+
+
+
+
+
diff --git a/tests/wpt/tests/css/css-grid/grid-items/grid-items-relative-positioned-containing-block-002.html b/tests/wpt/tests/css/css-grid/grid-items/grid-items-relative-positioned-containing-block-002.html new file mode 100644 index 00000000000..1e7a754f74d --- /dev/null +++ b/tests/wpt/tests/css/css-grid/grid-items/grid-items-relative-positioned-containing-block-002.html @@ -0,0 +1,24 @@ + + +CSS Grid Layout Test: Relative Positioned Grid Items as a Containing Block of Absolute Positioned Descendant + + + + + + + + + +

Test passes if there is a filled green square and no red.

+ +
+
+
+ +
+
+
+
+
+
diff --git a/tests/wpt/tests/css/css-grid/grid-items/grid-items-relative-positioned-containing-block-003.html b/tests/wpt/tests/css/css-grid/grid-items/grid-items-relative-positioned-containing-block-003.html new file mode 100644 index 00000000000..be030518191 --- /dev/null +++ b/tests/wpt/tests/css/css-grid/grid-items/grid-items-relative-positioned-containing-block-003.html @@ -0,0 +1,20 @@ + + +CSS Grid Layout Test: Relative Positioned Grid Items as a Containing Block of Absolute Positioned Descendant + + + + + + + + + +

Test passes if there is a filled green square and no red.

+ +
+
+
+
+
+
diff --git a/tests/wpt/tests/css/css-grid/grid-items/grid-items-relative-positioned-containing-block-004.html b/tests/wpt/tests/css/css-grid/grid-items/grid-items-relative-positioned-containing-block-004.html new file mode 100644 index 00000000000..61d50a10c10 --- /dev/null +++ b/tests/wpt/tests/css/css-grid/grid-items/grid-items-relative-positioned-containing-block-004.html @@ -0,0 +1,20 @@ + + +CSS Grid Layout Test: Relative Positioned Grid Items as a Containing Block of Fixed Positioned Descendant + + + + + + + + + +

Test passes if there is a filled green square and no red.

+ +
+
+
+
+
+
diff --git a/tests/wpt/tests/css/css-grid/grid-items/grid-items-relative-positioned-containing-block-005.html b/tests/wpt/tests/css/css-grid/grid-items/grid-items-relative-positioned-containing-block-005.html new file mode 100644 index 00000000000..4473cb8d2ba --- /dev/null +++ b/tests/wpt/tests/css/css-grid/grid-items/grid-items-relative-positioned-containing-block-005.html @@ -0,0 +1,24 @@ + + +CSS Grid Layout Test: Relative Positioned Grid Items as a Containing Block of Fixed Positioned Descendant + + + + + + + + + +

Test passes if there is a filled green square and no red.

+ +
+
+
+ +
+
+
+
+
+
diff --git a/tests/wpt/tests/css/css-grid/grid-items/grid-items-relative-positioned-containing-block-006.html b/tests/wpt/tests/css/css-grid/grid-items/grid-items-relative-positioned-containing-block-006.html new file mode 100644 index 00000000000..79350eac516 --- /dev/null +++ b/tests/wpt/tests/css/css-grid/grid-items/grid-items-relative-positioned-containing-block-006.html @@ -0,0 +1,21 @@ + + +CSS Grid Layout Test: Relative Positioned Grid Items as a Containing Block of Absolute and Fixed Positioned Descendant + + + + + + + + + +

Test passes if there is a filled green square and no red.

+ +
+
+
+
+
+
+
diff --git a/tests/wpt/tests/css/css-grid/grid-items/support/grid-items-relative-positioned-containing-block.css b/tests/wpt/tests/css/css-grid/grid-items/support/grid-items-relative-positioned-containing-block.css new file mode 100644 index 00000000000..ccdecf612d6 --- /dev/null +++ b/tests/wpt/tests/css/css-grid/grid-items/support/grid-items-relative-positioned-containing-block.css @@ -0,0 +1,32 @@ +.grid { + display: grid; + width: 100%; + grid-template-columns: 100px; + grid-template-rows: 100px; +} +.container { + position: relative; + grid-area: 1 / 1; +} +.box1 { + position: absolute; + width: 100px; + height: 100px; + grid-area: 1 / 1; +} +.box-abspos { + position: absolute; + width: 100%; + height: 100%; +} +.box-fixpos { + position: fixed; + width: 100px; + height: 100px; +} +.red { + background: red; +} +.green { + background: green; +}