diff --git a/Libraries/LibWeb/Layout/Node.cpp b/Libraries/LibWeb/Layout/Node.cpp index 1c545f65afc..30a74b0e349 100644 --- a/Libraries/LibWeb/Layout/Node.cpp +++ b/Libraries/LibWeb/Layout/Node.cpp @@ -185,37 +185,50 @@ bool Node::establishes_stacking_context() const if (is_root_element()) return true; - auto position = computed_values().position(); + auto const& computed_values = this->computed_values(); + + auto position = computed_values.position(); + + // https://drafts.csswg.org/css-will-change/#will-change + // If any non-initial value of a property would create a stacking context on the element, specifying that property + // in will-change must create a stacking context on the element. + auto will_change_property = [&](CSS::PropertyID property_id) { + return computed_values.will_change().has_property(property_id); + }; + + auto has_z_index = computed_values.z_index().has_value() || will_change_property(CSS::PropertyID::ZIndex); // Element with a position value absolute or relative and z-index value other than auto. if (position == CSS::Positioning::Absolute || position == CSS::Positioning::Relative) { - if (computed_values().z_index().has_value()) { + if (has_z_index) { return true; } } // Element with a position value fixed or sticky. - if (position == CSS::Positioning::Fixed || position == CSS::Positioning::Sticky) + if (position == CSS::Positioning::Fixed || position == CSS::Positioning::Sticky + || will_change_property(CSS::PropertyID::Position)) { + return true; + } + + if (!computed_values.transformations().is_empty() || will_change_property(CSS::PropertyID::Transform)) return true; - if (!computed_values().transformations().is_empty()) + if (computed_values.translate().has_value() || will_change_property(CSS::PropertyID::Translate)) return true; - if (computed_values().translate().has_value()) + if (computed_values.rotate().has_value() || will_change_property(CSS::PropertyID::Rotate)) return true; - if (computed_values().rotate().has_value()) - return true; - - if (computed_values().scale().has_value()) + if (computed_values.scale().has_value() || will_change_property(CSS::PropertyID::Scale)) return true; // Element that is a child of a flex container, with z-index value other than auto. - if (parent() && parent()->display().is_flex_inside() && computed_values().z_index().has_value()) + if (parent() && parent()->display().is_flex_inside() && has_z_index) return true; // Element that is a child of a grid container, with z-index value other than auto. - if (parent() && parent()->display().is_grid_inside() && computed_values().z_index().has_value()) + if (parent() && parent()->display().is_grid_inside() && has_z_index) return true; // https://drafts.fxtf.org/filter-effects/#FilterProperty @@ -224,8 +237,11 @@ bool Node::establishes_stacking_context() const // [CSS21] and a Containing Block for absolute and fixed position descendants, unless the // element it applies to is a document root element in the current browsing context. // Spec Note: This rule works in the same way as for the filter property. - if (computed_values().backdrop_filter().has_value() || computed_values().filter().has_value()) + if (computed_values.backdrop_filter().has_value() || computed_values.filter().has_value() + || will_change_property(CSS::PropertyID::BackdropFilter) + || will_change_property(CSS::PropertyID::Filter)) { return true; + } // Element with any of the following properties with value other than none: // - transform @@ -234,36 +250,40 @@ bool Node::establishes_stacking_context() const // - perspective // - clip-path // - mask / mask-image / mask-border - if (computed_values().mask().has_value() || computed_values().clip_path().has_value() || computed_values().mask_image()) + if (computed_values.mask().has_value() || computed_values.clip_path().has_value() || computed_values.mask_image() + || will_change_property(CSS::PropertyID::Mask) + || will_change_property(CSS::PropertyID::ClipPath) + || will_change_property(CSS::PropertyID::MaskImage)) { return true; + } if (is_svg_foreign_object_box()) return true; // https://drafts.fxtf.org/compositing/#propdef-isolation // For CSS, setting isolation to isolate will turn the element into a stacking context. - if (computed_values().isolation() == CSS::Isolation::Isolate) + if (computed_values.isolation() == CSS::Isolation::Isolate || will_change_property(CSS::PropertyID::Isolation)) return true; // https://drafts.csswg.org/css-contain-2/#containment-types // 5. The layout containment box creates a stacking context. // 3. The paint containment box creates a stacking context. - if (has_layout_containment() || has_paint_containment()) + if (has_layout_containment() || has_paint_containment() || will_change_property(CSS::PropertyID::Contain)) return true; // https://drafts.fxtf.org/compositing/#mix-blend-mode // Applying a blendmode other than normal to the element must establish a new stacking context. - if (computed_values().mix_blend_mode() != CSS::MixBlendMode::Normal) + if (computed_values.mix_blend_mode() != CSS::MixBlendMode::Normal || will_change_property(CSS::PropertyID::MixBlendMode)) return true; // https://drafts.csswg.org/css-view-transitions-1/#named-and-transitioning // Elements captured in a view transition during a view transition or whose view-transition-name computed value is // not 'none' (at any time): // - Form a stacking context. - if (computed_values().view_transition_name().has_value()) + if (computed_values.view_transition_name().has_value() || will_change_property(CSS::PropertyID::ViewTransitionName)) return true; - return computed_values().opacity() < 1.0f; + return computed_values.opacity() < 1.0f || will_change_property(CSS::PropertyID::Opacity); } GC::Ptr Node::navigable() const diff --git a/Tests/LibWeb/Ref/expected/wpt-import/css/css-will-change/green-square-100-by-100-ref.html b/Tests/LibWeb/Ref/expected/wpt-import/css/css-will-change/green-square-100-by-100-ref.html new file mode 100644 index 00000000000..c49bf5a21db --- /dev/null +++ b/Tests/LibWeb/Ref/expected/wpt-import/css/css-will-change/green-square-100-by-100-ref.html @@ -0,0 +1,12 @@ + + +CSS will-change reference + + + + +
+ diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-backdrop-filter-1.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-backdrop-filter-1.html new file mode 100644 index 00000000000..26fe46ec1de --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-backdrop-filter-1.html @@ -0,0 +1,37 @@ + + +CSS Test: will-change: backdrop-filter should create a stacking context. + + + + + + + +
+
+ +
+
diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-clip-path-1.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-clip-path-1.html new file mode 100644 index 00000000000..09ee8278651 --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-clip-path-1.html @@ -0,0 +1,21 @@ + + +CSS will-change: 'will-change: clip-path' creates a stacking context + + + + + + + + +
+
+
+
+ diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-filter-1.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-filter-1.html new file mode 100644 index 00000000000..e68e09e86c1 --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-filter-1.html @@ -0,0 +1,21 @@ + + +CSS will-change: 'will-change: filter' creates a stacking context + + + + + + + + +
+
+
+
+ diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-isolation-1.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-isolation-1.html new file mode 100644 index 00000000000..b1b503e7611 --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-isolation-1.html @@ -0,0 +1,21 @@ + + +CSS will-change: 'will-change: isolation' creates a stacking context + + + + + + + + +
+
+
+
+ diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-mask-1.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-mask-1.html new file mode 100644 index 00000000000..25aa0714e94 --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-mask-1.html @@ -0,0 +1,21 @@ + + +CSS will-change: 'will-change: mask' creates a stacking context + + + + + + + + +
+
+
+
+ diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-mask-image-1.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-mask-image-1.html new file mode 100644 index 00000000000..faf41f5f8d7 --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-mask-image-1.html @@ -0,0 +1,19 @@ + + +CSS will-change: 'will-change: mask-image' creates a stacking context + + + + + + +
+
+
+
+ diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-mix-blend-mode-1.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-mix-blend-mode-1.html new file mode 100644 index 00000000000..e05dc802a6f --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-mix-blend-mode-1.html @@ -0,0 +1,21 @@ + + +CSS will-change: 'will-change: mix-blend-mode' creates a stacking context + + + + + + + + +
+
+
+
+ diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-opacity-1.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-opacity-1.html new file mode 100644 index 00000000000..4fddad080e2 --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-opacity-1.html @@ -0,0 +1,21 @@ + + +CSS will-change: 'will-change: opacity' creates a stacking context + + + + + + + + +
+
+
+
+ diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-position-1.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-position-1.html new file mode 100644 index 00000000000..bc6a84662ec --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-position-1.html @@ -0,0 +1,21 @@ + + +CSS will-change: 'will-change: position' creates a stacking context + + + + + + + + +
+
+
+
+ diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-transform-1.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-transform-1.html new file mode 100644 index 00000000000..f5c8a2948a8 --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-transform-1.html @@ -0,0 +1,21 @@ + + +CSS will-change: 'will-change: transform' creates a stacking context + + + + + + + + +
+
+
+
+ diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-translate-1.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-translate-1.html new file mode 100644 index 00000000000..446d4a24b76 --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-translate-1.html @@ -0,0 +1,20 @@ + + +CSS will-change: 'will-change: translate' creates a stacking context + + + + + + + +
+
+
+
+ diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-view-transition-name-1.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-view-transition-name-1.html new file mode 100644 index 00000000000..7b27d23b473 --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-view-transition-name-1.html @@ -0,0 +1,20 @@ + + +CSS will-change: 'will-change: view-transition-name' creates a stacking context + + + + + + + +
+
+
+
+ diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-z-index-1.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-z-index-1.html new file mode 100644 index 00000000000..3e34c0f94a3 --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-z-index-1.html @@ -0,0 +1,21 @@ + + +CSS will-change: 'will-change: z-index' creates a stacking context + + + + + + + + +
+
+
+
+ diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-z-index-2.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-z-index-2.html new file mode 100644 index 00000000000..51720d3209e --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-z-index-2.html @@ -0,0 +1,29 @@ + +CSS Test: `will-change: z-index` + + + + + + + +

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

+
+
+
diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-z-index-3.html b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-z-index-3.html new file mode 100644 index 00000000000..98e253af9e6 --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/css-will-change/will-change-stacking-context-z-index-3.html @@ -0,0 +1,29 @@ + +CSS Test: `will-change: z-index` + + + + + + + +

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

+
+
+
diff --git a/Tests/LibWeb/TestConfig.ini b/Tests/LibWeb/TestConfig.ini index 7640268c283..808565bb7db 100644 --- a/Tests/LibWeb/TestConfig.ini +++ b/Tests/LibWeb/TestConfig.ini @@ -333,3 +333,8 @@ Text/input/wpt-import/html/browsers/sandboxing/sandbox-navigation-timing.tentati ; Not a ref test, but a subfile of the sandbox-parse-noscript ref test Ref/input/wpt-import/html/browsers/sandboxing/noscript-iframe.html + +; This test fails because we don't establish a stacking context when stacking context creating properties are animated +; with @keyframes. +; https://github.com/LadybirdBrowser/ladybird/issues/5875 +Ref/input/wpt-import/css/css-transforms/individual-transform/stacking-context-001.html