From 88f71edca1adffd7cc65d98a506e082e70adccba Mon Sep 17 00:00:00 2001
From: Dan Bjorge
Date: Thu, 29 Feb 2024 20:31:07 -0500
Subject: [PATCH] initial draft of 4350 fix
---
lib/commons/dom/create-grid.js | 31 +++++++++++++++++--
.../rules/target-size/target-size.html | 10 +++++-
.../rules/target-size/target-size.json | 2 ++
3 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/lib/commons/dom/create-grid.js b/lib/commons/dom/create-grid.js
index 612e885bbc..1bef9a2b0f 100644
--- a/lib/commons/dom/create-grid.js
+++ b/lib/commons/dom/create-grid.js
@@ -139,6 +139,7 @@ function isStackingContext(vNode, parentVNode) {
}
// elements with an opacity value less than 1.
+ // See https://www.w3.org/TR/css-color-3/#transparency
if (vNode.getComputedStylePropertyValue('opacity') !== '1') {
return true;
}
@@ -270,9 +271,7 @@ function createStackingOrder(vNode, parentVNode, treeOrder) {
// that point (step #5 and step #8)
// @see https://www.w3.org/Style/css2-updates/css2/zindex.html
if (isStackingContext(vNode, parentVNode)) {
- const index = stackingOrder.findIndex(({ stackLevel }) =>
- [ROOT_LEVEL, FLOAT_LEVEL, POSITION_LEVEL].includes(stackLevel)
- );
+ const index = stackingOrder.findIndex(isFakeStackingContext);
if (index !== -1) {
stackingOrder.splice(index, stackingOrder.length - index);
}
@@ -302,6 +301,23 @@ function createStackingContext(stackLevel, treeOrder, vNode) {
};
}
+function isFakeStackingContext(stackingContext) {
+ const { stackLevel, vNode } = stackingContext;
+
+ // elements with opacity < 1 must be treated as their own stacking context,
+ // even if drawn POSITION_LEVEL layer order.
+ // See https://www.w3.org/TR/css-color-3/#transparency
+ if (vNode && vNode.getComputedStylePropertyValue('opacity') !== '1') {
+ return false;
+ }
+
+ if ([ROOT_LEVEL, FLOAT_LEVEL, POSITION_LEVEL].includes(stackLevel)) {
+ return true;
+ }
+
+ return false;
+}
+
/**
* Calculate the level of the stacking context.
* @param {VirtualNode} vNode - The virtual node container of the stacking context
@@ -324,6 +340,15 @@ function getStackLevel(vNode, parentVNode) {
return POSITION_LEVEL;
}
+ // From https://www.w3.org/TR/css-color-3/#transparency:
+ //
+ // > If an element with opacity less than 1 is not positioned, then it is
+ // > painted on the same layer, within its parent stacking context, as positioned
+ // > elements with stack level 0.
+ if (vNode.getComputedStylePropertyValue('opacity') !== '1') {
+ return POSITION_LEVEL;
+ }
+
// Put floated elements above z-index: 0
// (step #5 floating get sorted below step #8 positioned)
if (vNode.getComputedStylePropertyValue('float') !== 'none') {
diff --git a/test/integration/rules/target-size/target-size.html b/test/integration/rules/target-size/target-size.html
index 3c4b0be940..99da79a7f0 100644
--- a/test/integration/rules/target-size/target-size.html
+++ b/test/integration/rules/target-size/target-size.html
@@ -28,7 +28,7 @@
-
+
+
+
+