diff --git a/components/style/dom.rs b/components/style/dom.rs
index 3f0924cf77e..1cdac5089b3 100644
--- a/components/style/dom.rs
+++ b/components/style/dom.rs
@@ -19,6 +19,7 @@ use crate::shared_lock::{Locked, SharedRwLock};
use crate::stylist::CascadeData;
use crate::traversal_flags::TraversalFlags;
use crate::values::AtomIdent;
+use crate::values::computed::Display;
use crate::{LocalName, Namespace, WeakAtom};
use atomic_refcell::{AtomicRef, AtomicRefMut};
use selectors::matching::{QuirksMode, VisitedHandlingMode};
@@ -946,7 +947,7 @@ pub trait TElement:
/// Returns the size of the element to be used in container size queries.
/// This will usually be the size of the content area of the primary box,
/// but can be None if there is no box or if some axis lacks size containment.
- fn query_container_size(&self) -> euclid::default::Size2D>;
+ fn query_container_size(&self, display: &Display) -> euclid::default::Size2D >;
}
/// TNode and TElement aren't Send because we want to be careful and explicit
diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs
index 69272b15417..bf06761d6f0 100644
--- a/components/style/gecko/wrapper.rs
+++ b/components/style/gecko/wrapper.rs
@@ -63,6 +63,7 @@ use crate::shared_lock::{Locked, SharedRwLock};
use crate::string_cache::{Atom, Namespace, WeakAtom, WeakNamespace};
use crate::stylist::CascadeData;
use crate::values::{AtomIdent, AtomString};
+use crate::values::computed::Display;
use crate::CaseSensitivityExt;
use crate::LocalName;
use app_units::Au;
@@ -1036,7 +1037,14 @@ impl<'le> TElement for GeckoElement<'le> {
}
#[inline]
- fn query_container_size(&self) -> Size2D > {
+ fn query_container_size(&self, display: &Display) -> Size2D > {
+ // If an element gets 'display: contents' and its nsIFrame has not been removed yet,
+ // Gecko_GetQueryContainerSize will not notice that it can't have size containment.
+ // Other cases like 'display: inline' will be handled once the new nsIFrame is created.
+ if display.is_contents() {
+ return Size2D::new(None, None);
+ }
+
let mut width = -1;
let mut height = -1;
unsafe {
diff --git a/components/style/matching.rs b/components/style/matching.rs
index 0534d1ad0c5..a22dba26808 100644
--- a/components/style/matching.rs
+++ b/components/style/matching.rs
@@ -981,6 +981,13 @@ pub trait MatchMethods: TElement {
// Stopped being a size container. Re-evaluate container queries and units on all our descendants.
// Changes into and between different size containment is handled in `UpdateContainerQueryStyles`.
restyle_requirement = ChildRestyleRequirement::MustMatchDescendants;
+ } else if old_container_type.is_size_container_type() &&
+ !old_primary_style.is_display_contents() &&
+ new_primary_style.is_display_contents()
+ {
+ // Also re-evaluate when a container gets 'display: contents', since size queries will now evaluate to unknown.
+ // Other displays like 'inline' will keep generating a box, so they are handled in `UpdateContainerQueryStyles`.
+ restyle_requirement = ChildRestyleRequirement::MustMatchDescendants;
}
restyle_requirement = cmp::max(
diff --git a/components/style/stylesheets/container_rule.rs b/components/style/stylesheets/container_rule.rs
index 8e9babff28c..8badfb80536 100644
--- a/components/style/stylesheets/container_rule.rs
+++ b/components/style/stylesheets/container_rule.rs
@@ -201,7 +201,7 @@ impl ContainerCondition {
}
}
- let size = potential_container.query_container_size();
+ let size = potential_container.query_container_size(&box_style.clone_display());
let style = style.clone();
TraversalResult::Done(ContainerLookupResult {
element: potential_container,
@@ -464,7 +464,7 @@ impl<'a> ContainerSizeQuery<'a> {
let box_style = style.get_box();
let container_type = box_style.clone_container_type();
- let size = e.query_container_size();
+ let size = e.query_container_size(&box_style.clone_display());
match container_type {
ContainerType::Size => {
TraversalResult::Done(