mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Improve logic for establishing a stacking context (#35947)
In particular: - `z-index` will now work on unpositioned grid items. - `will-change: z-index` will only establish a stacking context if `z-index` applies, i.e. if the box is positioned or a flex/grid item. - The conditions in `establishes_stacking_context()` are reordered, so that the most likely ones are checked first. Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
205b97d5ed
commit
f93006af95
33 changed files with 233 additions and 114 deletions
|
@ -257,7 +257,9 @@ impl FlexLineItem<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut fragment_info = self.item.box_.base_fragment_info();
|
let mut fragment_info = self.item.box_.base_fragment_info();
|
||||||
fragment_info.flags.insert(FragmentFlags::IS_FLEX_ITEM);
|
fragment_info
|
||||||
|
.flags
|
||||||
|
.insert(FragmentFlags::IS_FLEX_OR_GRID_ITEM);
|
||||||
if self.item.depends_on_block_constraints {
|
if self.item.depends_on_block_constraints {
|
||||||
fragment_info.flags.insert(
|
fragment_info.flags.insert(
|
||||||
FragmentFlags::SIZE_DEPENDS_ON_BLOCK_CONSTRAINTS_AND_CAN_BE_CHILD_OF_FLEX_ITEM,
|
FragmentFlags::SIZE_DEPENDS_ON_BLOCK_CONSTRAINTS_AND_CAN_BE_CHILD_OF_FLEX_ITEM,
|
||||||
|
|
|
@ -80,8 +80,8 @@ bitflags! {
|
||||||
const IS_BODY_ELEMENT_OF_HTML_ELEMENT_ROOT = 1 << 0;
|
const IS_BODY_ELEMENT_OF_HTML_ELEMENT_ROOT = 1 << 0;
|
||||||
/// Whether or not the node that created this Fragment is a `<br>` element.
|
/// Whether or not the node that created this Fragment is a `<br>` element.
|
||||||
const IS_BR_ELEMENT = 1 << 1;
|
const IS_BR_ELEMENT = 1 << 1;
|
||||||
/// Whether or not this Fragment is a flex item.
|
/// Whether or not this Fragment is a flex item or a grid item.
|
||||||
const IS_FLEX_ITEM = 1 << 2;
|
const IS_FLEX_OR_GRID_ITEM = 1 << 2;
|
||||||
/// Whether or not this Fragment was created to contain a replaced element or is
|
/// Whether or not this Fragment was created to contain a replaced element or is
|
||||||
/// a replaced element.
|
/// a replaced element.
|
||||||
const IS_REPLACED = 1 << 3;
|
const IS_REPLACED = 1 << 3;
|
||||||
|
|
|
@ -301,6 +301,7 @@ pub(crate) trait ComputedValuesExt {
|
||||||
) -> LogicalSides<LengthPercentageOrAuto<'_>>;
|
) -> LogicalSides<LengthPercentageOrAuto<'_>>;
|
||||||
fn is_transformable(&self, fragment_flags: FragmentFlags) -> bool;
|
fn is_transformable(&self, fragment_flags: FragmentFlags) -> bool;
|
||||||
fn has_transform_or_perspective(&self, fragment_flags: FragmentFlags) -> bool;
|
fn has_transform_or_perspective(&self, fragment_flags: FragmentFlags) -> bool;
|
||||||
|
fn z_index_applies(&self, fragment_flags: FragmentFlags) -> bool;
|
||||||
fn effective_z_index(&self, fragment_flags: FragmentFlags) -> i32;
|
fn effective_z_index(&self, fragment_flags: FragmentFlags) -> i32;
|
||||||
fn effective_overflow(&self, fragment_flags: FragmentFlags) -> AxesOverflow;
|
fn effective_overflow(&self, fragment_flags: FragmentFlags) -> AxesOverflow;
|
||||||
fn establishes_block_formatting_context(&self, fragment_flags: FragmentFlags) -> bool;
|
fn establishes_block_formatting_context(&self, fragment_flags: FragmentFlags) -> bool;
|
||||||
|
@ -503,18 +504,35 @@ impl ComputedValuesExt for ComputedValues {
|
||||||
self.get_box().perspective != Perspective::None)
|
self.get_box().perspective != Perspective::None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether the `z-index` property applies to this fragment.
|
||||||
|
fn z_index_applies(&self, fragment_flags: FragmentFlags) -> bool {
|
||||||
|
// As per CSS 2 § 9.9.1, `z-index` applies to positioned elements.
|
||||||
|
// <http://www.w3.org/TR/CSS2/visuren.html#z-index>
|
||||||
|
if self.get_box().position != ComputedPosition::Static {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// More modern specs also apply it to flex and grid items.
|
||||||
|
// - From <https://www.w3.org/TR/css-flexbox-1/#painting>:
|
||||||
|
// > Flex items paint exactly the same as inline blocks [CSS2], except that order-modified
|
||||||
|
// > document order is used in place of raw document order, and z-index values other than auto
|
||||||
|
// > create a stacking context even if position is static (behaving exactly as if position
|
||||||
|
// > were relative).
|
||||||
|
// - From <https://drafts.csswg.org/css-flexbox/#painting>:
|
||||||
|
// > The painting order of grid items is exactly the same as inline blocks [CSS2], except that
|
||||||
|
// > order-modified document order is used in place of raw document order, and z-index values
|
||||||
|
// > other than auto create a stacking context even if position is static (behaving exactly
|
||||||
|
// > as if position were relative).
|
||||||
|
fragment_flags.contains(FragmentFlags::IS_FLEX_OR_GRID_ITEM)
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the effective z-index of this fragment. Z-indices only apply to positioned elements
|
/// Get the effective z-index of this fragment. Z-indices only apply to positioned elements
|
||||||
/// per CSS 2 9.9.1 (<http://www.w3.org/TR/CSS2/visuren.html#z-index>), so this value may differ
|
/// per CSS 2 9.9.1 (<http://www.w3.org/TR/CSS2/visuren.html#z-index>), so this value may differ
|
||||||
/// from the value specified in the style.
|
/// from the value specified in the style.
|
||||||
fn effective_z_index(&self, fragment_flags: FragmentFlags) -> i32 {
|
fn effective_z_index(&self, fragment_flags: FragmentFlags) -> i32 {
|
||||||
// From <https://drafts.csswg.org/css-flexbox/#painting>:
|
if self.z_index_applies(fragment_flags) {
|
||||||
// > Flex items paint exactly the same as inline blocks [CSS2], except that order-modified
|
self.get_position().z_index.integer_or(0)
|
||||||
// > document order is used in place of raw document order, and z-index values other than auto
|
} else {
|
||||||
// > create a stacking context even if position is static (behaving exactly as if position
|
0
|
||||||
// > were relative).
|
|
||||||
match self.get_box().position {
|
|
||||||
ComputedPosition::Static if !fragment_flags.contains(FragmentFlags::IS_FLEX_ITEM) => 0,
|
|
||||||
_ => self.get_position().z_index.integer_or(0),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -617,78 +635,92 @@ impl ComputedValuesExt for ComputedValues {
|
||||||
|
|
||||||
/// Returns true if this fragment establishes a new stacking context and false otherwise.
|
/// Returns true if this fragment establishes a new stacking context and false otherwise.
|
||||||
fn establishes_stacking_context(&self, fragment_flags: FragmentFlags) -> bool {
|
fn establishes_stacking_context(&self, fragment_flags: FragmentFlags) -> bool {
|
||||||
|
// From <https://www.w3.org/TR/css-will-change/#valdef-will-change-custom-ident>:
|
||||||
|
// > 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.
|
||||||
|
let will_change_bits = self.clone_will_change().bits;
|
||||||
|
if will_change_bits
|
||||||
|
.intersects(WillChangeBits::STACKING_CONTEXT_UNCONDITIONAL | WillChangeBits::OPACITY)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// From <https://www.w3.org/TR/CSS2/visuren.html#z-index>, values different than `auto`
|
||||||
|
// make the box establish a stacking context.
|
||||||
|
if self.z_index_applies(fragment_flags) &&
|
||||||
|
(!self.get_position().z_index.is_auto() ||
|
||||||
|
will_change_bits.intersects(WillChangeBits::Z_INDEX))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fixed position and sticky position always create stacking contexts.
|
||||||
|
// Note `will-change: position` is handled above by `STACKING_CONTEXT_UNCONDITIONAL`.
|
||||||
|
if matches!(
|
||||||
|
self.get_box().position,
|
||||||
|
ComputedPosition::Fixed | ComputedPosition::Sticky
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// From <https://www.w3.org/TR/css-transforms-1/#transform-rendering>
|
||||||
|
// > For elements whose layout is governed by the CSS box model, any value other than
|
||||||
|
// > `none` for the `transform` property results in the creation of a stacking context.
|
||||||
|
// From <https://www.w3.org/TR/css-transforms-2/#transform-style-property>
|
||||||
|
// > A computed value of `preserve-3d` for `transform-style` on a transformable element
|
||||||
|
// > establishes both a stacking context and a containing block for all descendants.
|
||||||
|
// From <https://www.w3.org/TR/css-transforms-2/#perspective-property>
|
||||||
|
// > any value other than none establishes a stacking context.
|
||||||
|
// TODO: handle individual transform properties (`translate`, `scale` and `rotate`).
|
||||||
|
// <https://www.w3.org/TR/css-transforms-2/#individual-transforms>
|
||||||
|
if self.is_transformable(fragment_flags) &&
|
||||||
|
(!self.get_box().transform.0.is_empty() ||
|
||||||
|
self.get_box().transform_style == ComputedTransformStyle::Preserve3d ||
|
||||||
|
self.get_box().perspective != Perspective::None ||
|
||||||
|
will_change_bits
|
||||||
|
.intersects(WillChangeBits::TRANSFORM | WillChangeBits::PERSPECTIVE))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// From <https://www.w3.org/TR/css-color-3/#transparency>
|
||||||
|
// > implementations must create a new stacking context for any element with opacity less than 1.
|
||||||
|
// Note `will-change: opacity` is handled above by `WillChangeBits::OPACITY`.
|
||||||
let effects = self.get_effects();
|
let effects = self.get_effects();
|
||||||
if effects.opacity != 1.0 {
|
if effects.opacity != 1.0 {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if effects.mix_blend_mode != ComputedMixBlendMode::Normal {
|
// From <https://www.w3.org/TR/filter-effects-1/#FilterProperty>
|
||||||
return true;
|
// > A computed value of other than `none` results in the creation of a stacking context
|
||||||
}
|
// Note `will-change: filter` is handled above by `STACKING_CONTEXT_UNCONDITIONAL`.
|
||||||
|
|
||||||
if !effects.filter.0.is_empty() {
|
if !effects.filter.0.is_empty() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.has_transform_or_perspective(fragment_flags) {
|
// From <https://www.w3.org/TR/compositing-1/#mix-blend-mode>
|
||||||
return true;
|
// > Applying a blendmode other than `normal` to the element must establish a new stacking context
|
||||||
}
|
// Note `will-change: mix-blend-mode` is handled above by `STACKING_CONTEXT_UNCONDITIONAL`.
|
||||||
|
if effects.mix_blend_mode != ComputedMixBlendMode::Normal {
|
||||||
// See <https://drafts.csswg.org/css-transforms-2/#transform-style-property>.
|
|
||||||
if self.is_transformable(fragment_flags) &&
|
|
||||||
self.get_box().transform_style == ComputedTransformStyle::Preserve3d
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.get_box().isolation == ComputedIsolation::Isolate {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fixed position and sticky position always create stacking contexts.
|
|
||||||
// TODO(mrobinson): We need to handle sticky positioning here when we support it.
|
|
||||||
if self.get_box().position == ComputedPosition::Fixed {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// From <https://www.w3.org/TR/css-masking-1/#the-clip-path>
|
||||||
|
// > A computed value of other than `none` results in the creation of a stacking context.
|
||||||
|
// Note `will-change: clip-path` is handled above by `STACKING_CONTEXT_UNCONDITIONAL`.
|
||||||
if self.get_svg().clip_path != ClipPath::None {
|
if self.get_svg().clip_path != ClipPath::None {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// From <https://www.w3.org/TR/css-will-change/#valdef-will-change-custom-ident>:
|
// From <https://www.w3.org/TR/compositing-1/#isolation>
|
||||||
// > If any non-initial value of a property would create a stacking context on the element,
|
// > For CSS, setting `isolation` to `isolate` will turn the element into a stacking context.
|
||||||
// > specifying that property in will-change must create a stacking context on the element.
|
// Note `will-change: isolation` is handled above by `STACKING_CONTEXT_UNCONDITIONAL`.
|
||||||
let will_change_bits = self.clone_will_change().bits;
|
if self.get_box().isolation == ComputedIsolation::Isolate {
|
||||||
if will_change_bits.intersects(
|
|
||||||
WillChangeBits::OPACITY |
|
|
||||||
WillChangeBits::STACKING_CONTEXT_UNCONDITIONAL |
|
|
||||||
WillChangeBits::Z_INDEX,
|
|
||||||
) || (will_change_bits
|
|
||||||
.intersects(WillChangeBits::PERSPECTIVE | WillChangeBits::TRANSFORM) &&
|
|
||||||
self.is_transformable(fragment_flags))
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Statically positioned fragments don't establish stacking contexts if the previous
|
// TODO: We need to handle CSS Contain here.
|
||||||
// conditions are not fulfilled. Furthermore, z-index doesn't apply to statically
|
false
|
||||||
// positioned fragments (except for flex items, see below).
|
|
||||||
//
|
|
||||||
// From <https://drafts.csswg.org/css-flexbox/#painting>:
|
|
||||||
// > Flex items paint exactly the same as inline blocks [CSS2], except that order-modified
|
|
||||||
// > document order is used in place of raw document order, and z-index values other than auto
|
|
||||||
// > create a stacking context even if position is static (behaving exactly as if position
|
|
||||||
// > were relative).
|
|
||||||
if self.get_box().position == ComputedPosition::Static &&
|
|
||||||
!fragment_flags.contains(FragmentFlags::IS_FLEX_ITEM)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For absolutely and relatively positioned fragments we only establish a stacking
|
|
||||||
// context if there is a z-index set.
|
|
||||||
// See https://www.w3.org/TR/CSS2/visuren.html#z-index
|
|
||||||
!self.get_position().z_index.is_auto()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if this style establishes a containing block for absolute
|
/// Returns true if this style establishes a containing block for absolute
|
||||||
|
|
|
@ -20,7 +20,9 @@ use crate::formatting_contexts::{
|
||||||
Baselines, IndependentFormattingContext, IndependentFormattingContextContents,
|
Baselines, IndependentFormattingContext, IndependentFormattingContextContents,
|
||||||
IndependentLayout,
|
IndependentLayout,
|
||||||
};
|
};
|
||||||
use crate::fragment_tree::{BoxFragment, CollapsedBlockMargins, Fragment, SpecificLayoutInfo};
|
use crate::fragment_tree::{
|
||||||
|
BoxFragment, CollapsedBlockMargins, Fragment, FragmentFlags, SpecificLayoutInfo,
|
||||||
|
};
|
||||||
use crate::geom::{
|
use crate::geom::{
|
||||||
LogicalSides, LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSides, PhysicalSize, Size,
|
LogicalSides, LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSides, PhysicalSize, Size,
|
||||||
SizeConstraint, Sizes,
|
SizeConstraint, Sizes,
|
||||||
|
@ -560,8 +562,12 @@ impl TaffyContainer {
|
||||||
|
|
||||||
match &mut child.taffy_level_box {
|
match &mut child.taffy_level_box {
|
||||||
TaffyItemBoxInner::InFlowBox(independent_box) => {
|
TaffyItemBoxInner::InFlowBox(independent_box) => {
|
||||||
|
let mut fragment_info = independent_box.base_fragment_info();
|
||||||
|
fragment_info
|
||||||
|
.flags
|
||||||
|
.insert(FragmentFlags::IS_FLEX_OR_GRID_ITEM);
|
||||||
let mut box_fragment = BoxFragment::new(
|
let mut box_fragment = BoxFragment::new(
|
||||||
independent_box.base_fragment_info(),
|
fragment_info,
|
||||||
independent_box.style().clone(),
|
independent_box.style().clone(),
|
||||||
std::mem::take(&mut child.child_fragments),
|
std::mem::take(&mut child.child_fragments),
|
||||||
content_size,
|
content_size,
|
||||||
|
|
39
tests/wpt/meta/MANIFEST.json
vendored
39
tests/wpt/meta/MANIFEST.json
vendored
|
@ -307667,6 +307667,45 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"will-change-stacking-context-z-index-2.html": [
|
||||||
|
"9379185048a78b031e8ac290bd7bb3e5df24fa5f",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"/css/reference/ref-filled-green-100px-square.xht",
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"will-change-stacking-context-z-index-3.html": [
|
||||||
|
"4ec40ae1a430a095ea6f703c8c27698e04792220",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"/css/reference/ref-filled-green-100px-square.xht",
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"will-change-stacking-context-z-index-4.html": [
|
||||||
|
"d8a87b23415c3c10a6f4875f16cd63301e789152",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"/css/reference/ref-filled-green-100px-square.xht",
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"will-change-transform-add-content.html": [
|
"will-change-transform-add-content.html": [
|
||||||
"1d8568ee629e48adfe99abab2e2194a73ae1301a",
|
"1d8568ee629e48adfe99abab2e2194a73ae1301a",
|
||||||
[
|
[
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-inline-z-axis-ordering-001.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-inline-z-axis-ordering-002.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-inline-z-axis-ordering-003.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-inline-z-axis-ordering-004.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-inline-z-axis-ordering-005.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-inline-z-axis-ordering-overlapped-items-001.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-inline-z-axis-ordering-overlapped-items-002.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-inline-z-axis-ordering-overlapped-items-003.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-inline-z-axis-ordering-overlapped-items-004.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-inline-z-axis-ordering-overlapped-items-005.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-inline-z-axis-ordering-overlapped-items-006.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-layout-z-order-a.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-layout-z-order-b.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-z-axis-ordering-001.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-z-axis-ordering-002.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-z-axis-ordering-003.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-z-axis-ordering-004.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-z-axis-ordering-005.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-z-axis-ordering-overlapped-items-001.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-z-axis-ordering-overlapped-items-002.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-z-axis-ordering-overlapped-items-003.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-z-axis-ordering-overlapped-items-004.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-z-axis-ordering-overlapped-items-005.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[grid-z-axis-ordering-overlapped-items-006.html]
|
|
||||||
expected: FAIL
|
|
2
tests/wpt/meta/css/css-will-change/will-change-stacking-context-z-index-3.html.ini
vendored
Normal file
2
tests/wpt/meta/css/css-will-change/will-change-stacking-context-z-index-3.html.ini
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[will-change-stacking-context-z-index-3.html]
|
||||||
|
prefs: ["layout_grid_enabled:true"]
|
29
tests/wpt/tests/css/css-will-change/will-change-stacking-context-z-index-2.html
vendored
Normal file
29
tests/wpt/tests/css/css-will-change/will-change-stacking-context-z-index-2.html
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<title>CSS Test: `will-change: z-index`</title>
|
||||||
|
<link rel="author" title="Oriol Brufau" href="obrufau@igalia.com">
|
||||||
|
<link rel="help" href="https://www.w3.org/TR/css-will-change/#valdef-will-change-custom-ident">
|
||||||
|
<link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#painting">
|
||||||
|
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/11827">
|
||||||
|
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
|
||||||
|
<meta name="assert" content="
|
||||||
|
`will-change: z-index` establishes a stacking context on a flex item.
|
||||||
|
">
|
||||||
|
<style>
|
||||||
|
.test {
|
||||||
|
will-change: z-index;
|
||||||
|
width: 100px;
|
||||||
|
background: red;
|
||||||
|
}
|
||||||
|
.test::before {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
z-index: -1;
|
||||||
|
height: 100px;
|
||||||
|
background: green;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||||
|
<div style="display: flex">
|
||||||
|
<div class="test"></div>
|
||||||
|
</div>
|
29
tests/wpt/tests/css/css-will-change/will-change-stacking-context-z-index-3.html
vendored
Normal file
29
tests/wpt/tests/css/css-will-change/will-change-stacking-context-z-index-3.html
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<title>CSS Test: `will-change: z-index`</title>
|
||||||
|
<link rel="author" title="Oriol Brufau" href="obrufau@igalia.com">
|
||||||
|
<link rel="help" href="https://www.w3.org/TR/css-will-change/#valdef-will-change-custom-ident">
|
||||||
|
<link rel="help" href="https://www.w3.org/TR/css-grid-2/#z-order">
|
||||||
|
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/11827">
|
||||||
|
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
|
||||||
|
<meta name="assert" content="
|
||||||
|
`will-change: z-index` establishes a stacking context on a grid item.
|
||||||
|
">
|
||||||
|
<style>
|
||||||
|
.test {
|
||||||
|
will-change: z-index;
|
||||||
|
width: 100px;
|
||||||
|
background: red;
|
||||||
|
}
|
||||||
|
.test::before {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
z-index: -1;
|
||||||
|
height: 100px;
|
||||||
|
background: green;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||||
|
<div style="display: grid">
|
||||||
|
<div class="test"></div>
|
||||||
|
</div>
|
28
tests/wpt/tests/css/css-will-change/will-change-stacking-context-z-index-4.html
vendored
Normal file
28
tests/wpt/tests/css/css-will-change/will-change-stacking-context-z-index-4.html
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<title>CSS Test: `will-change: z-index`</title>
|
||||||
|
<link rel="author" title="Oriol Brufau" href="obrufau@igalia.com">
|
||||||
|
<link rel="help" href="https://www.w3.org/TR/css-will-change/#valdef-will-change-custom-ident">
|
||||||
|
<link rel="help" href="https://www.w3.org/TR/CSS2/visuren.html#z-index">
|
||||||
|
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/11827">
|
||||||
|
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
|
||||||
|
<meta name="assert" content="
|
||||||
|
`will-change: z-index` doesn't establish a stacking context on a non-positioned block box,
|
||||||
|
because `z-index` doesn't apply in that case.
|
||||||
|
">
|
||||||
|
<style>
|
||||||
|
.test {
|
||||||
|
will-change: z-index;
|
||||||
|
width: 100px;
|
||||||
|
background: green;
|
||||||
|
}
|
||||||
|
.test::before {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
z-index: -1;
|
||||||
|
height: 100px;
|
||||||
|
background: red;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||||
|
<div class="test"></div>
|
Loading…
Add table
Add a link
Reference in a new issue