Twenty-Six Lines That Ask You to Turn the Phone

Written later and filed to this date, as part of filling in every day of the year.

Hold the phone upright and my survivor shooter shows you a curved arrow and one sentence, “Please rotate your device to landscape”, on a near-black screen. Turn it sideways and the game is there. The thing that decides which of those you see is not in the game. It is in the page that hosts the game, and it is a media query.

The whole of it is twenty-six lines, twenty-two of style and four of markup. An overlay fixed to the viewport, covering all four edges, above everything with an absurd z-index, hidden by default. Then one rule: when the orientation is portrait and the width is at most seven hundred and sixty-seven pixels, display it. A phone turned upright matches. A phone turned sideways does not, so the overlay vanishes and the canvas underneath is already running. A tablet in portrait is wider than the cutoff and never sees it, which is a judgment about tablets I happen to agree with. A desktop never matches either condition.

What is not there is the part I would have written first, a few years ago: a listener on the orientation-change event, a function that reads the window’s width and height, compares them, toggles a class, and a second listener for resize because the first one fires before the dimensions settle on some browsers and after on others. That code has to be right at page load, right after rotation, right when the keyboard opens, and right when a split-screen view changes the aspect ratio without rotating anything. The media query is right in all of those cases because the browser evaluates it, continuously, from the same facts it uses to lay the page out. There is no moment at which the overlay’s state and the viewport’s state can disagree, because the overlay’s state is a function of the viewport’s state and nothing else.

The same page carries two more lines in that spirit. The document is sized with the dynamic viewport height unit, so the address bar sliding away on a phone does not leave a strip of nothing at the bottom, and the container’s padding reads the safe-area insets, so the canvas keeps clear of the notch and the home indicator. Neither needs a script. The platform knows where its own notch is.

I keep a rule for my own pages that a native element or a stylesheet feature comes before anything hand-rolled, and the rotate prompt is the cleanest case I have of why. The script version would be a small state machine tracking a fact the browser already holds, and every state machine has a state it can be caught in. The declarative version states a condition and lets the browser keep it true.

The commit that added it is called mobile, and this was the smallest thing in it.


← all writing