Skip to content

fix(css): stop WebKit leaving a stale strip over CJK reading-pane titles on hover - #558

Merged
henry40408 merged 2 commits into
mainfrom
fix/reading-pane-title-hover-repaint
Sep 14, 2026
Merged

henry40408 merged 2 commits into
mainfrom
fix/reading-pane-title-hover-repaint

Conversation

@henry40408

@henry40408 henry40408 commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Problem

In Safari (macOS and iPad), hovering or tapping a CJK entry title in the reading pane leaves a thin strip of the old color above the first line's glyphs: white while the title turns orange, orange after it turns back.

CJK falls back to PingFang/Hiragino, whose glyphs rise above the rect WebKit repaints when the link's color changes.

Fix

padding-block: 0.15em on .reading-pane-title a. Inline vertical padding doesn't affect line layout but grows the rect WebKit repaints.

Verification

Reproduced in a real WKWebView (Safari 26.6.2's WebKit) against the running app: log in, open a seeded CJK entry, simulate a mouse move over and off the title, capture the window pixels, and count stale-color pixels in the title area.

Variant Stale px while hovered Stale px after leaving
original a:hover 621 620
recolor <h1> via :has() + heading padding (this PR's first commit) 621 649
line-height: 1.4 621
transparent border-top on <h1> 893
padding-block: 0.15em on the link 0 0

At rest the fix renders pixel-identically to the unpadded control (0px diff).

  • test_reading_pane_title_link_pads_over_cjk_glyph_overflow guards the rule; it failed with the padding removed and passes with it. cargo nextest run: 1420 passed. clippy, fmt, csp-audit clean.
  • The Chromium-only E2E suite can't observe WebKit repaints, so the pixel harness above isn't part of CI.

🤖 Generated with Claude Code

CJK titles fall back to PingFang/Hiragino, whose ink rises 0.8-1.6px
above the line box Newsreader sizes (CoreText: PingFang TC ink top 27.39px
vs line top 26.57px at 33px/1.14). WebKit repaints the inline link's
color change only within its line boxes, so tapping a title on iPad left
a strip of white over the first line, and leaving it a strip of orange.

Recolor the heading via :has(a:hover) instead, and pad the heading over
the overflow (cancelled by a negative margin) so the block repaint covers
the glyphs. Layout is unchanged: regenerated screenshots differ from the
committed ones only by the same ~416px of noise two identical runs show.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Sep 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.06%. Comparing base (0771ca2) to head (8cc3ae1).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #558   +/-   ##
=======================================
  Coverage   94.06%   94.06%           
=======================================
  Files          93       93           
  Lines       26439    26439           
=======================================
  Hits        24869    24869           
  Misses       1570     1570           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

The previous commit did not fix it: measured in a real WKWebView against
the running app (window pixels captured after a simulated mouse move),
both the original a:hover rule and the :has() heading recolor leave the
same 621 white pixels in the top five device-pixel rows of the first
line while hovered. A taller line-height or a transparent border on the
heading leaves them too, so the stale area follows the glyphs, not the
line box.

Inline vertical padding on the link grows the rect WebKit repaints and
leaves 0 stale pixels in both directions, while rendering the page at
rest pixel-identically (0px diff), since inline padding doesn't affect
line layout. Drop the heading padding and :has() rule.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@henry40408 henry40408 changed the title fix(css): repaint the whole reading-pane title on hover in WebKit fix(css): stop WebKit leaving a stale strip over CJK reading-pane titles on hover Sep 14, 2026
@henry40408
henry40408 marked this pull request as ready for review September 14, 2026 15:34
@henry40408
henry40408 merged commit c027b66 into main Sep 14, 2026
9 checks passed
@henry40408
henry40408 deleted the fix/reading-pane-title-hover-repaint branch September 14, 2026 15:35
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