Skip to content

fix(check): masked or clipped-away text no longer counts as overlapping - #7364

Merged
miguel-heygen merged 4 commits into
mainfrom
fix/check-overlap-visible-box
Nov 7, 2026
Merged

miguel-heygen merged 4 commits into
mainfrom
fix/check-overlap-visible-box

Conversation

@miguel-heygen

Copy link
Copy Markdown
Collaborator

What

hyperframes check flagged text as overlapping other text when the part that touched was masked or clipped away, so it was never on screen. The overlap gate now measures each text block by what it paints.

  • Every text rect is cropped by its own and its ancestors' clip-path (inset, polygon, circle, ellipse, by their bounds) and single-layer gradient mask-image (linear-gradient along an axis, radial-gradient); the mask counts as painting where its alpha is at least 0.35. Overflow clipping of ancestors was already applied and keeps working the same way.
  • A clip-path or mask this code does not read (a path(), an image mask, a repeated or resized mask) keeps today's behavior: the text counts as painted.
  • docs/packages/cli.mdx says overlap is judged on the visible text.

Why

A user report: check reported ten overlaps on text sitting under a mask while the rendered frames looked fine.

Size

One function family in layout-audit.browser.js, one table of Chromium cases, one docs paragraph.

Test plan

  • New Chromium cases in layout-audit.chromium.test.ts: HELLO at 100-220 px, WORLD at 150-270 px, with only WORLD's top 60% able to touch HELLO. WORLD masked transparent there (own mask, a wrapper's fading mask, a radial mask) or cut by clip-path: inset(62% 0 0 0) is no overlap; the unmasked control, a mask that still paints the touching part, and an overflow-hidden wrapper keep their current verdicts.
  • fails without the fix: on main's layout-audit.browser.js the four masked or clipped cases report content_overlap (4 failed, 3 passed).
  • layout-audit*, contrast-audit*, checkBrowser.test.ts, layoutAudit* in Chromium: 451 passed, 3 runs in a row.
  • bun run format:check exit 0; fallow audit --base origin/main --fail-on-issues exit 0; oxlint exit 0.

@mintlify

mintlify Bot commented Nov 7, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
hyperframes 🟢 Ready View Preview Nov 7, 2026, 4:47 PM

💡 Tip: Enable Automations to automatically generate PRs for you.

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES · 1 blocker · 0 important · 0 nits · head a7d207da

The fix works, and fails without the fix: checks out: on main's layout-audit.browser.js the 4 masked/clipped cases fail, and at head all 7 pass. One blocker, inline: a moved mask now hides a real overlap.

Scope

Read all of layout-audit.browser.js (clip-path/mask family, plus both callers of visibleTextClientRects: overlap blocks and craft parts) and the test table. Ran the Chromium cases locally against Chromium 1237. The only change from 55d7e58 to a7d207d is a comment. CI was still running when this was posted.

function maskRegion(node, style) {
const value = style.maskImage || style.webkitMaskImage;
if (!value || value === "none" || topLevelSplit(value, ",").length !== 1) return null;
const size = style.maskSize || style.webkitMaskSize || "auto";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blocker: maskRegion checks mask-size but not mask-position or mask-origin. A moved mask is read as if it sat at 0 0, so this can now hide a real overlap that main reports. That breaks the PR's promise that a mask the code can't read keeps today's behavior.

Repro (added to the new table locally): upper + lower("mask-image:linear-gradient(transparent 62%, #000 62%);mask-repeat:no-repeat;mask-position:0 -75px"). The painted strip moves up to 150-195 px, right on top of the upper heading, but the check now reports no content_overlap (main does report it). Animating mask-position is a common way to do wipe reveals.

Fix: return null unless maskPosition resolves to the origin (0% 0% / 0px 0px) and maskOrigin is border-box. Please also add the case above to the table with overlap: true.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed at 15c92ef. maskRegion now reads a mask only when it sits at the origin (mask-position 0 0 in % or px) on the border box (mask-origin: border-box) with mask-size: auto; any other mask keeps today's verdict (the text counts as painted). Added your repro as masked by a mask moved up onto the other text (overlap: true) and a mask-origin: content-box case (overlap: true). Both fail on the previous head (2 failed, 7 passed of the painted-text table); with the fix 453 passed across layout-audit, contrast-audit, checkBrowser and layoutAudit in Chromium, 3 runs in a row. format:check, fallow and oxlint exit 0.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Fixed in 15c92ef: moved or content-box masks now return null; both repro cases fail on a7d207d and pass at head.

@mintlify

mintlify Bot commented Nov 7, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
hyperframes 🟡 Building – Nov 7, 2026, 4:43 PM

💡 Tip: Enable Automations to automatically generate PRs for you.

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE — 1 resolved, 0 open, 0 new · a7d207da → 15c92ef8

@miguel-heygen
miguel-heygen added this pull request to the merge queue Nov 7, 2026
Merged via the queue into main with commit a3b8f52 Nov 7, 2026
72 checks passed
@miguel-heygen
miguel-heygen deleted the fix/check-overlap-visible-box branch November 7, 2026 18:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant