The most puzzling Web platform bug I’ve encountered
So say you’re me and you’re procrastinating on Hacker News instead of what you meant to be doing, like maintaining your open source project MathQuill, the formula editor used in the Desmos graphing calculator:
And the friendly folks at Desmos chat you up in your Slack and say:
Hey, a smattering of our Chrome users say they can’t type in the equation list on the left (which is powered by MathQuill), but we can’t repro even with the same Chrome version on the same OS version, and the rest of our Chrome users have no problem, any ideas?
“Hmmmmm,” you begin, hoping to sound thoughtful and wise even though you’re at a loss, “there was this one thing where
font-size: 0 on MathQuill’s hidden textarea broke typing in Chrome, which is why MathQuill doesn’t do that anymore . But you’re up-to-date, and besides, if that was the culprit, it would’ve broken all your Chrome users.”
Yeah no, our MathQuill hidden textareas are not
Here’s what’s weird though, they’re saying that at first they could type fine and then suddenly it broke in the middle of a session. Which just sounds like a bad state, right? But then when they refresh, or open a new tab or window, the problem persists. This is for any graph opened with Desmos, not a particular saved graph. If they restart Chrome or even their computer, the problem persists. If we deploy an update to the code, or even a revert, the problem persists. There’s no problem in other browsers or on other computers. Don’t suppose you’re setting a
breakTypingForChromeUsersOutOfSpitecookie or something? Or Web Storage? Maybe something something browser caching?
MathQuill does not touch cookies, Web Storage, or caching.
We figured a formula editor has no reason to touch cookies or caching, and also you seem very gracious and not at all spiteful. But, when we served the same code under a different domain to someone experiencing the problem, they can type fine in the tab with the alternate domain, even alongside an open tab where they can’t type, which is running the exact same code on the exact same data (same graph)!
That sounds like cookies or caching, doesn’t it? Any guesses as to how either could cause this, or what else could behave like this?
On the other hand, cookies or caching don’t make sense because once the problem starts, it’ll happen in Incognito too.
Ideas? Here’s one last piece:
So we just noticed that we set
font-size: 1pxon the hidden textarea . Removing that (so the hidden textarea is the normal
font-size) does reportedly fix the problem. How…why…
That’s all you get! Can you figure it out?
The answer, which I’m hiding in a long sentence because it’s basically one word and also to draw out the suspense, which is kinda fun, is zoom level.
Folks were accidentally zooming out to 90% in the middle of a session, which apparently causes Chrome to round the
font-size: 1px down to
font-size: 0, breaking typing. Then, because Chrome persists zoom level of websites on a per-domain basis and shares it across tabs and windows and even Incognito, no amount of refreshes, restarts, new tabs, or code updates to the graphing calculator could restore typing. (This is arguably a minor security issue since it leaks information about zoom level, which could be used for fingerprinting, weakening the anonymity of Incognito.)
font-size: 0/1px were obsoleted by
transform: scale(0) to hide the textarea, which also fixed other issues, and just feels nice and robust since transforms are so low level .
Credits to the incredibly talented team at Desmos, in particular @ehberger for making the connection between zoom and persistence keyed by domain, and @eluberoff for discovering the
font-size: 1px. I’m just lucky to have witnessed this saga unfold.
The above conversation was dramatized and summarized, but the order of discoveries is accurate.
Shameless self-promotion time!
Round 2 since, let’s face it, I was pretty shameless at the beginning there.
Footnotes (Warning: the links have spoilers)
: The purpose of
font-size: 0 was to hide the blinking cursor in iOS, because the CSS we used at the time to hide the textarea didn’t hide the blinking cursor (#310). At the time, that actually mostly worked, it didn’t break typing until Chrome 51, which we luckily caught in Chrome Canary (#540, thanks @ajhyndman!). Now, we instead do
transform: scale(0) to hide both textarea and cursor, which fixed a few other issues too (#584).
: This was a workaround for the problems described in , before the solution was found. It fixes typing in Chrome while making the blinking cursor in iOS as small as possible.