🐞 fix: Update chrome tint implementation to use opacity for visibility and adjust related tests
This commit is contained in:
@@ -81,24 +81,23 @@ main#maincontent {
|
|||||||
* backgroundColor is updated at runtime by
|
* backgroundColor is updated at runtime by
|
||||||
* static/js/modules/ChromeTint.js.
|
* static/js/modules/ChromeTint.js.
|
||||||
*
|
*
|
||||||
* visibility: hidden keeps the elements invisible to the user (so
|
* opacity: 0 makes the elements fully transparent to the user (so
|
||||||
* they don't appear as dark bars over the page content) while iOS
|
* they don't appear as dark bars over the page content) while the
|
||||||
* Safari still samples their backgroundColor. The WebKit source
|
* backgroundColor is still readable by iOS Safari's sampler.
|
||||||
* explicitly notes that visibility: hidden elements ARE sampled.
|
|
||||||
*
|
*
|
||||||
* The elements are kept as small as possible (12px tall) so they
|
* The elements are kept as small as possible (12px tall) so they
|
||||||
* stay well within the iOS safe-area insets. They have no background
|
* stay well within the iOS safe-area insets. They have no background
|
||||||
* by default — they only get a backgroundColor when the matching
|
* by default — they only get a backgroundColor when the matching
|
||||||
* element (header / footer) is in view. pointer-events: none ensures
|
* element (header / footer) is in view. pointer-events: none ensures
|
||||||
* they never intercept clicks even if made visible.
|
* they never intercept clicks.
|
||||||
*
|
*
|
||||||
* (iOS 26 ignores <meta name="theme-color">; this technique is
|
* (iOS 26 ignores <meta name="theme-color">; this technique is
|
||||||
* what replaced it.)
|
* what replaced it.)
|
||||||
*/
|
*/
|
||||||
.chrome-tint {
|
.chrome-tint {
|
||||||
|
opacity: 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
visibility: hidden;
|
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-13
@@ -61,7 +61,7 @@ test.describe("chrome tint", () => {
|
|||||||
width: Math.round(topR.width),
|
width: Math.round(topR.width),
|
||||||
widthPct: Math.round((topR.width / winW) * 100),
|
widthPct: Math.round((topR.width / winW) * 100),
|
||||||
position: topCs.position,
|
position: topCs.position,
|
||||||
visibility: topCs.visibility,
|
opacity: parseFloat(topCs.opacity),
|
||||||
},
|
},
|
||||||
bottom: {
|
bottom: {
|
||||||
bottomFromViewport: Math.round(winH - bottomR.bottom),
|
bottomFromViewport: Math.round(winH - bottomR.bottom),
|
||||||
@@ -69,25 +69,25 @@ test.describe("chrome tint", () => {
|
|||||||
width: Math.round(bottomR.width),
|
width: Math.round(bottomR.width),
|
||||||
widthPct: Math.round((bottomR.width / winW) * 100),
|
widthPct: Math.round((bottomR.width / winW) * 100),
|
||||||
position: bottomCs.position,
|
position: bottomCs.position,
|
||||||
visibility: bottomCs.visibility,
|
opacity: parseFloat(bottomCs.opacity),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
// Top element: position fixed, top ≤ 4px, width >= 80%, height >= 12px,
|
// Top element: position fixed, top ≤ 4px, width >= 80%, height >= 12px,
|
||||||
// visibility hidden (so it never appears as a dark bar over page content).
|
// opacity 0 (so it never appears as a dark bar over page content).
|
||||||
expect(layout.top.position).toBe("fixed");
|
expect(layout.top.position).toBe("fixed");
|
||||||
expect(layout.top.top).toBeLessThanOrEqual(4);
|
expect(layout.top.top).toBeLessThanOrEqual(4);
|
||||||
expect(layout.top.widthPct).toBeGreaterThanOrEqual(80);
|
expect(layout.top.widthPct).toBeGreaterThanOrEqual(80);
|
||||||
expect(layout.top.height).toBeGreaterThanOrEqual(12);
|
expect(layout.top.height).toBeGreaterThanOrEqual(12);
|
||||||
expect(layout.top.visibility).toBe("hidden");
|
expect(layout.top.opacity).toBe(0);
|
||||||
|
|
||||||
// Bottom element: position fixed, within 3px of viewport bottom, width >= 80%,
|
// Bottom element: position fixed, within 3px of viewport bottom, width >= 80%,
|
||||||
// visibility hidden.
|
// opacity 0.
|
||||||
expect(layout.bottom.position).toBe("fixed");
|
expect(layout.bottom.position).toBe("fixed");
|
||||||
expect(layout.bottom.bottomFromViewport).toBeLessThanOrEqual(3);
|
expect(layout.bottom.bottomFromViewport).toBeLessThanOrEqual(3);
|
||||||
expect(layout.bottom.widthPct).toBeGreaterThanOrEqual(80);
|
expect(layout.bottom.widthPct).toBeGreaterThanOrEqual(80);
|
||||||
expect(layout.bottom.visibility).toBe("hidden");
|
expect(layout.bottom.opacity).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("fixed chrome tint elements are not visible to the user (no extra dark bars)", async ({
|
test("fixed chrome tint elements are not visible to the user (no extra dark bars)", async ({
|
||||||
@@ -106,18 +106,18 @@ test.describe("chrome tint", () => {
|
|||||||
{ timeout: 2000 },
|
{ timeout: 2000 },
|
||||||
);
|
);
|
||||||
// Even though the elements have background colors, they should
|
// Even though the elements have background colors, they should
|
||||||
// be invisible to the user (visibility: hidden) so they don't
|
// be invisible to the user (opacity: 0) so they don't show as
|
||||||
// show as dark bars over the page content.
|
// dark bars over the page content.
|
||||||
const visibility = await page.evaluate(() => {
|
const opacities = await page.evaluate(() => {
|
||||||
const top = document.querySelector(".chrome-tint--top");
|
const top = document.querySelector(".chrome-tint--top");
|
||||||
const bottom = document.querySelector(".chrome-tint--bottom");
|
const bottom = document.querySelector(".chrome-tint--bottom");
|
||||||
return {
|
return {
|
||||||
top: getComputedStyle(top).visibility,
|
top: parseFloat(getComputedStyle(top).opacity),
|
||||||
bottom: getComputedStyle(bottom).visibility,
|
bottom: parseFloat(getComputedStyle(bottom).opacity),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
expect(visibility.top).toBe("hidden");
|
expect(opacities.top).toBe(0);
|
||||||
expect(visibility.bottom).toBe("hidden");
|
expect(opacities.bottom).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("viewport meta includes viewport-fit=cover", async ({ page }) => {
|
test("viewport meta includes viewport-fit=cover", async ({ page }) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user