From 66ca84a0690efbe941c43bd32134b53d795c6952 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Sun, 20 Sep 2026 15:46:09 +0200 Subject: [PATCH] fix(html): a pdf's selection shows the text it marks v7.2.0 gave the `::selection` rules a background, because an author rule drops the UA's own and the selection painted nothing. That background is `Highlight`, which is opaque, and the layer carrying it paints over the glyph layer - so selecting a word hid it. It is see-through now: a `color-mix` of the platform's highlight, over an rgba fallback for an engine that cannot parse one. Checked on the reported document in chrome 153 and in an android WebView on chrome 91, where the fallback is what paints. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01FJJdfqpnVCKBNHXjAVxSou --- CHANGELOG.md | 5 +++++ src/odr/internal/html/pdf_file.cpp | 27 +++++++++++++++++---------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04ca47bb6..47023e013 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,11 @@ The release run heads these entries with the version and opens a fresh ## Unreleased +- **Fix**: selecting text in a pdf view hid the words it selected. The + `::selection` background v7.2.0 states is `Highlight`, which is opaque, and + the layer carrying it paints over the glyph layer. It is see-through now, so + the text reads through its own selection. + ## v7.2.0 - 2026-09-20 - **Fix**: a pdf underline and squiggle were drawn through the text rather than diff --git a/src/odr/internal/html/pdf_file.cpp b/src/odr/internal/html/pdf_file.cpp index 0c7ca87ca..128947b60 100644 --- a/src/odr/internal/html/pdf_file.cpp +++ b/src/odr/internal/html/pdf_file.cpp @@ -1819,9 +1819,12 @@ class HtmlServiceImpl final : public HtmlService { out.out() << ".i{color:transparent;font-family:sf,sans-serif}"; // A selection paints text in the highlight's own colour, which beats // `transparent` and shows this layer over the glyphs it stands for. An - // author `::selection` drops the UA background, so state that too. - out.out() << ".i::selection,.i *::selection" - "{color:transparent;background-color:Highlight}"; + // author `::selection` drops the UA background, so state that too - and + // state it see-through, because this layer paints over the glyph one. + out.out() + << ".i::selection,.i *::selection" + "{color:transparent;background-color:rgba(70,130,220,.32);" + "background-color:color-mix(in srgb,Highlight 45%,transparent)}"; // Selection-layer run span. `overflow:hidden` clips a wider system font; // `.t`'s inherited `pre` blocks wrapping while preserving a run's own // leading/trailing space, which is real PDF content. @@ -2294,10 +2297,12 @@ class HtmlServiceImpl final : public HtmlService { "color:transparent;vertical-align:baseline}"; // As `.i` in the dual layer above, with `*` reaching a run's own span // and a search `mark`. - out.out() << ".i::selection,.i *::selection," - ".ov::selection,.ov *::selection," - ".sp::selection,.sp *::selection" - "{color:transparent;background-color:Highlight}"; + out.out() + << ".i::selection,.i *::selection," + ".ov::selection,.ov *::selection," + ".sp::selection,.sp *::selection" + "{color:transparent;background-color:rgba(70,130,220,.32);" + "background-color:color-mix(in srgb,Highlight 45%,transparent)}"; // A hit in the overlay is clipped away with it, so the glyphs it belongs // to carry the highlight instead - the whole run of them, which is as // narrow as the overlay can say. @@ -2872,9 +2877,11 @@ class HtmlServiceImpl final : public HtmlService { rule("fn", "color:transparent;"); // The same guard for a line the embedded font makes invisible; the dual // layer's `fnN` rides a `user-select:none` run and needs none. - font_styles += ".fn" + n + "::selection,.fn" + n + - " *::selection" - "{color:transparent;background-color:Highlight}"; + font_styles += + ".fn" + n + "::selection,.fn" + n + + " *::selection" + "{color:transparent;background-color:rgba(70,130,220,.32);" + "background-color:color-mix(in srgb,Highlight 45%,transparent)}"; } }