diff --git a/components/layout/block.rs b/components/layout/block.rs index e5ef740132c2..e0dcc4b68c7d 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -1989,12 +1989,12 @@ impl Flow for BlockFlow { // For relatively-positioned descendants, the containing block formed by a block is just // the content box. The containing block for absolutely-positioned descendants, on the - // other hand, is only established if we are positioned. + // other hand, is established in other circumstances (see `is_absolute_containing_block'). let relative_offset = self.fragment.relative_position(&self.base .early_absolute_position_info .relative_containing_block_size); - if self.contains_positioned_fragments() { + if self.is_absolute_containing_block() { let border_box_origin = (self.fragment.border_box - self.fragment.style.logical_border_width()).start; self.base @@ -2013,14 +2013,15 @@ impl Flow for BlockFlow { logical_border_width.inline_start, logical_border_width.block_start); let position = position.to_physical(self.base.writing_mode, container_size); - if self.contains_positioned_fragments() { + + // Some blocks establish a stacking context, but not a containing block for + // absolutely positioned elements. An example of this might be a block that has + // `position: static` and `opacity` set. In these cases, absolutely-positioned + // children will not be positioned relative to us but will instead be positioned + // relative to our containing block. + if self.is_absolute_containing_block() { position } else { - // We establish a stacking context but are not positioned. (This will happen - // if, for example, the element has `position: static` but has `opacity` or - // `transform` set.) In this case, absolutely-positioned children will not be - // positioned relative to us but will instead be positioned relative to our - // containing block. position - self.base.stacking_relative_position } } else { @@ -2105,10 +2106,6 @@ impl Flow for BlockFlow { (self.fragment.border_box - self.fragment.style().logical_border_width()).size } - fn is_absolute_containing_block(&self) -> bool { - self.contains_positioned_fragments() - } - fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) { if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) && self.fragment.style().logical_position().inline_start == diff --git a/components/layout/construct.rs b/components/layout/construct.rs index 7e49784479ca..502f21b36f91 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -616,14 +616,12 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> flow.finish(); // Set up the absolute descendants. - let contains_positioned_fragments = flow.contains_positioned_fragments(); - let is_absolutely_positioned = flow::base(&*flow).flags.contains(IS_ABSOLUTELY_POSITIONED); - if contains_positioned_fragments { + if flow.is_absolute_containing_block() { // This is the containing block for all the absolute descendants. flow.set_absolute_descendants(abs_descendants); abs_descendants = AbsoluteDescendants::new(); - if is_absolutely_positioned { + if flow::base(&*flow).flags.contains(IS_ABSOLUTELY_POSITIONED) { // This is now the only absolute flow in the subtree which hasn't yet // reached its CB. abs_descendants.push(flow.clone()); @@ -1060,16 +1058,13 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> // The flow is done. flow.finish(); - let contains_positioned_fragments = flow.contains_positioned_fragments(); - if contains_positioned_fragments { + if flow.is_absolute_containing_block() { // This is the containing block for all the absolute descendants. flow.set_absolute_descendants(abs_descendants); abs_descendants = AbsoluteDescendants::new(); - let is_absolutely_positioned = - flow::base(&*flow).flags.contains(IS_ABSOLUTELY_POSITIONED); - if is_absolutely_positioned { + if flow::base(&*flow).flags.contains(IS_ABSOLUTELY_POSITIONED) { // This is now the only absolute flow in the subtree which hasn't yet // reached its containing block. abs_descendants.push(flow.clone()); @@ -1134,16 +1129,13 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> legalizer.finish(&mut wrapper_flow); wrapper_flow.finish(); - let contains_positioned_fragments = wrapper_flow.contains_positioned_fragments(); - if contains_positioned_fragments { + if wrapper_flow.is_absolute_containing_block() { // This is the containing block for all the absolute descendants. wrapper_flow.set_absolute_descendants(abs_descendants); abs_descendants = AbsoluteDescendants::new(); - let is_absolutely_positioned = - flow::base(&*wrapper_flow).flags.contains(IS_ABSOLUTELY_POSITIONED); - if is_absolutely_positioned { + if flow::base(&*wrapper_flow).flags.contains(IS_ABSOLUTELY_POSITIONED) { // This is now the only absolute flow in the subtree which hasn't yet // reached its containing block. abs_descendants.push(wrapper_flow.clone()); diff --git a/components/layout/flow.rs b/components/layout/flow.rs index e40b1b3cdc21..d4716fb02a90 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -404,7 +404,7 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static { /// Returns true if this is an absolute containing block. fn is_absolute_containing_block(&self) -> bool { - false + self.contains_positioned_fragments() } /// Updates the inline position of a child flow during the assign-height traversal. At present, diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 663d85095161..2a1aa3075f2a 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -1486,7 +1486,7 @@ impl Flow for InlineFlow { indentation = Au(0) } - if self.contains_positioned_fragments() { + if self.is_absolute_containing_block() { // Assign block-sizes for all flows in this absolute flow tree. // This is preorder because the block-size of an absolute flow may depend on // the block-size of its containing block, which may also be an absolute flow.