From 948cc7e36886c23589a68830ecbe2ec07ef73904 Mon Sep 17 00:00:00 2001 From: Keith Solomon Date: Sat, 27 Jun 2026 22:36:46 -0500 Subject: [PATCH] refactor: harden responsive Our Work artwork --- tests/mobile-homepage.spec.js | 108 +++++++++++++++++++++++++---- views/blocks/our-work/our-work.css | 40 +++++++---- views/blocks/our-work/our-work.php | 25 ++----- 3 files changed, 127 insertions(+), 46 deletions(-) diff --git a/tests/mobile-homepage.spec.js b/tests/mobile-homepage.spec.js index a0fb3ba..9f92f6d 100644 --- a/tests/mobile-homepage.spec.js +++ b/tests/mobile-homepage.spec.js @@ -470,23 +470,78 @@ test("mobile Our Work uses its dedicated linework composition", async ({ }) => { await page.goto(homepage); - const block = await getBox(page.locator(".our-work")); const mobileVector = page.locator(".our-work__vector-mobile"); - const upper = await getBox( - mobileVector.locator(".our-work__vector-mobile-upper"), - ); - const lower = await getBox( - mobileVector.locator(".our-work__vector-mobile-lower"), - ); + const clip = mobileVector.locator(".our-work__vector-mobile-clip"); + const composition = await mobileVector.evaluate((element) => { + const clipElement = element.querySelector( + ".our-work__vector-mobile-clip", + ); + const upper = getComputedStyle(clipElement, "::before"); + const lower = getComputedStyle(element, "::after"); + + return { + lowerBackground: lower.backgroundImage, + lowerWidth: Number.parseFloat(lower.width), + upperBackground: upper.backgroundImage, + upperWidth: Number.parseFloat(upper.width), + }; + }); await expect(mobileVector).toBeVisible(); + await expect(clip).toBeVisible(); await expect(page.locator(".our-work__vector-desktop")).toBeHidden(); - expectNear(upper.x - block.x, 100, 3); - expectNear(upper.y - block.y, 240, 3); - expectNear(upper.width, 960, 4); - expectNear(lower.x - block.x, -430, 3); - expectNear(lower.y - block.y, 490, 3); - expectNear(lower.width, 960, 4); + await expect(mobileVector.locator("img")).toHaveCount(0); + expect(composition.upperBackground).toContain("our-work-vector.svg"); + expect(composition.lowerBackground).toContain("our-work-vector.svg"); + expectNear(composition.upperWidth, 960, 4); + expectNear(composition.lowerWidth, 960, 4); +}); + +test("mobile Our Work reserves reference height only for both images", async ({ + page, +}) => { + await page.goto(homepage); + + const minHeights = await page.locator(".our-work").evaluate((block) => { + const measureVariant = (removedClasses) => { + const clone = block.cloneNode(true); + clone.classList.remove(...removedClasses); + if (removedClasses.includes("has-left-image")) { + clone.querySelector(".our-work__media--left")?.remove(); + } + if (removedClasses.includes("has-bottom-image")) { + clone.querySelector(".our-work__media--bottom")?.remove(); + } + document.body.append(clone); + const measurements = { + height: clone.getBoundingClientRect().height, + minHeight: Number.parseFloat(getComputedStyle(clone).minHeight), + }; + clone.remove(); + return measurements; + }; + + return { + bothImages: { + height: block.getBoundingClientRect().height, + minHeight: Number.parseFloat(getComputedStyle(block).minHeight), + }, + bottomOnly: measureVariant(["has-left-image"]), + leftOnly: measureVariant(["has-bottom-image"]), + noImages: measureVariant(["has-left-image", "has-bottom-image"]), + }; + }); + + expectNear(minHeights.bothImages.minHeight, 888, 3); + expectNear(minHeights.bothImages.height, 888, 12); + for (const variant of [ + minHeights.bottomOnly, + minHeights.leftOnly, + minHeights.noImages, + ]) { + expect(variant.minHeight).toBe(0); + expect(variant.height).toBeLessThan(minHeights.bothImages.height); + } }); test("mobile Our Work linework render remains stable", async ({ page }) => { @@ -553,6 +608,33 @@ test("mobile Our Work remains contained at responsive endpoints", async ({ expectNear(primary.y, secondary.y, 2); expect(left.y).toBeLessThan(bottom.y); + + const vectorScale = await page + .locator(".our-work__vector-mobile") + .evaluate((element) => { + const clip = element.querySelector( + ".our-work__vector-mobile-clip", + ); + const upper = getComputedStyle(clip, "::before"); + const lower = getComputedStyle(element, "::after"); + + return { + lowerLeft: Number.parseFloat(lower.left), + lowerTop: Number.parseFloat(lower.top), + lowerWidth: Number.parseFloat(lower.width), + upperLeft: Number.parseFloat(upper.left), + upperTop: Number.parseFloat(upper.top), + upperWidth: Number.parseFloat(upper.width), + }; + }); + const scale = width / 402; + + expectNear(vectorScale.upperWidth, 960 * scale, 4); + expectNear(vectorScale.lowerWidth, 960 * scale, 4); + expectNear(vectorScale.upperLeft, 100 * scale, 3); + expectNear(vectorScale.upperTop, 240 * scale, 3); + expectNear(vectorScale.lowerLeft, -430 * scale, 4); + expectNear(vectorScale.lowerTop, 490 * scale, 4); } }); diff --git a/views/blocks/our-work/our-work.css b/views/blocks/our-work/our-work.css index 8c466f2..133c4f1 100644 --- a/views/blocks/our-work/our-work.css +++ b/views/blocks/our-work/our-work.css @@ -202,10 +202,13 @@ @media (max-width: 767px) { .our-work { margin-bottom: 2rem; - min-height: clamp(44rem, 220.9vw, 55.5rem); padding-top: 4.25rem; } + .our-work.has-left-image.has-bottom-image { + min-height: clamp(44rem, 220.9vw, 55.5rem); + } + .our-work__vector-desktop { display: none; } @@ -216,6 +219,21 @@ position: absolute; } + /* + * CSS layers keep the approved external SVG available. Browsers do not load + * nested external images from an SVG embedded through an img element. + */ + .our-work__vector-mobile::after, + .our-work__vector-mobile-clip::before { + background-image: var(--our-work-vector-image); + background-repeat: no-repeat; + background-size: 100% 100%; + content: ""; + height: 98.756vw; + position: absolute; + width: 238.806vw; + } + .our-work__vector-mobile-clip { clip-path: polygon( 74.63% 24.77%, @@ -233,22 +251,14 @@ position: absolute; } - .our-work__vector-mobile img { - height: auto; - max-width: none; - object-fit: fill; - position: absolute; - width: min(238.806vw, 60rem); + .our-work__vector-mobile-clip::before { + left: 24.876vw; + top: 59.701vw; } - .our-work__vector-mobile-upper { - left: min(24.876vw, 6.25rem); - top: min(59.701vw, 15rem); - } - - .our-work__vector-mobile-lower { - left: max(-106.965vw, -26.875rem); - top: min(121.891vw, 30.625rem); + .our-work__vector-mobile::after { + left: -106.965vw; + top: 121.891vw; } .our-work__inner { diff --git a/views/blocks/our-work/our-work.php b/views/blocks/our-work/our-work.php index a902923..bafc2e2 100644 --- a/views/blocks/our-work/our-work.php +++ b/views/blocks/our-work/our-work.php @@ -11,6 +11,7 @@ namespace CWC; $left_image = get_field( 'left_image' ); $bottom_image = get_field( 'bottom_image' ); +$vector_url = get_stylesheet_directory_uri() . '/views/blocks/our-work/our-work-vector.svg'; $classes = 'our-work mx-break-out mb-36'; @@ -31,28 +32,16 @@ $wrapper = blockWrapperAttributes( $classes, $is_preview );
>