Text Selection Regression in Chrome 83

Illustration: Text Selection Regression in Chrome 83

In an ideal world, once you implement a solution that works across all browsers, you expect newer versions of each browser to be consistent and keep functioning. And while standardization processes and features are shaped with “don’t break the web” as a golden rule, unfortunately, regressions in rendering engines do happen. Chrome 83 broke text selection in our PDF SDK, and this is the story about it.

Text Selection in PDF

My colleague noticed text selection wasn’t working properly on macOS Chrome. I tried to reproduce the issue, but it was working perfectly fine for me. I then realized I was still on the previous major release of Chrome in my local dev environment (Chrome 81 — Version 82 was canceled), and Google had just released Chrome 83. And sure enough, I could reproduce the bug once I had updated.

What’s happening is that Chrome 83 renders any bit of selected text as black, no matter what color has been set for the original text.

This might be a small bug for Google, but for us, it’s a major regression. I started looking for this issue in Chromium’s official bug tracker, and sure enough, I found a reported issue that described exactly the same situation we observed: Issue #1083232. The minimum reproduction case provided is great — a simple data URL that sets an inline portion of text to transparent:

1
data:text/html,The word <span style="color:transparent">&quot;invisible&quot;</span> should not be visible

Try copying and pasting that into Chrome 83’s address bar. Then select the text and notice how the word “invisible” is displayed as black while you’re selecting it. The expected behavior is for that text to keep its original color during the selection.

Fixing Bugs Quickly

Our customers license our SDK so they don’t have to deal with PDF rendering problems on a quickly evolving platform. As such, we needed to find a workaround that would allow us to overcome this regression and keep the expected uniform behavior across browser vendors.

When you want to customize the style of the text highlight, ::selection CSS pseudo-element is a great choice. It only supports a subset of CSS properties, but fortunately, color and background-color are two of them. To avoid the black text rendering, we simply needed to set color: transparent:

1
2
3
::selection {
  color: transparent;
}

Here is a data URL with this same fix:

Copy
1
data:text/html, <style>.invisible { color: transparent; } .invisible::selection { color: transparent; }</style>The word <span class="invisible">&quot;invisible&quot;</span> should not be visible

Yay! The word “invisible” is no longer visible in the selection when I visit it. However, the selection appears broken; there’s no fill color around that word even though it is indeed part of the selection. So we need to explicitly set a background color.

Chrome renders the selection highlight with a different background color depending on the current platform; you can see a list with some of them in this Stack Overflow answer. One option is to use JavaScript and perhaps CSS custom properties to set the background color for each platform accordingly.

However, there is a little-known hack available: The CSS2 specification included some special values that could be used as color values. One of them is highlight, which represented the native platform color of text highlights. The entire set of these special values was removed as part of the CSS Color Module Level 3 specification, but highlight still works on Chrome:

1
2
3
4
::selection {
  background-color: highlight;
  color: transparent;
}

Try this data URL with these two properties set:

Copy
1
data:text/html, <style>.invisible { color: transparent; } .invisible::selection { color: transparent; background-color: highlight; }</style>The word <span class="invisible">&quot;invisible&quot;</span> should not be visible

Now we achieve the desired result! We have a working workaround in place! 🎉

To recap, below is a video showing the buggy behavior.

And here’s a video of it after applying the fix.

Shipping Updates Fast

Once we implemented a fix for the regression, we started our QA process to make sure we weren’t introducing any regressions on our own and that text selection still worked for other platforms. In this case, to minimize the impact surface of this change, we added checks to only apply this CSS rule on Chrome.

Overall, it took us only three days from the time we discovered the bug until 2020.2.5 was released. We’ll continue to keep an eye out to ensure browser updates don’t break the experience for our customers.

This fix is part of our 2020.2.5 release of PSPDFKit for Web, which is now available for all of our customers. You can try it here for free, with no sign-up required.

PSPDFKit for Web

PDF viewing, annotating, and collaboration for web apps.

Try Now