Four things people warn you about scroll animation on phones. Three are not true here
Scroll-driven templates are supposed to hijack your scrolling, need a mouse and block pinch zoom. We checked all sixty source files. Three of those four warnings do not apply — and the fourth is a one-line mistake in eight of them.
Published
The four warnings
If you ask around about buying a template whose whole design is driven by scrolling, you will be told four things. That it will take control of your scrolling away from you. That half of it only works with a mouse, so a phone gets a broken version. That it will stop you pinching to zoom. And that its full-screen sections will be the wrong height on a phone, because the address bar moves.
All four are real failure modes. They are common enough that the warnings are fair as general advice. What they are not is a description of any particular template, and a marketplace listing will not settle it either: the claim there is always the same categorical adjective — responsive, mobile-optimised, touch-friendly — with no statement of what the page actually does when the address bar retracts under it.
So we read the source of all sixty single-file templates in this catalogue and checked each warning against what the files contain. Three of the four do not apply to anything here. The fourth does, in eight templates, and it is a one-line mistake rather than a design decision — which is the useful thing to know, because it means you can see it in the file and it can be fixed in a minute.
Sixty of the sixty-two, not all of them. Nebula and Nexora are multi-file builds rather than one document, so the same search would not be the same measurement, and they are left out of every count below rather than estimated.
It will take your scrolling away: no
The thing people mean here is scroll-jacking: the page listens for your scroll gesture, cancels it, and animates to wherever it thinks you should be instead. It is why the pattern has a bad name. It also breaks the scrollbar, the keyboard, find-in-page and the phone’s own momentum scrolling in one move.
Not one of the sixty does it. No file attaches a listener to the wheel event, and none of them loads any of the libraries that exist to replace native scrolling — no Lenis, no Locomotive Scroll, no ScrollSmoother, no ScrollMagic, no fullPage.js. Fourteen use GSAP’s ScrollTrigger, which reads the scroll position and moves things in response to it; it does not intercept the gesture. Your scroll stays your scroll, and the scrollbar keeps telling the truth about how far through the page you are.
Thirty-five of the sixty do set scroll-behavior: smooth, which animates the jump when you follow a link to an anchor on the same page. That is a small thing and it is not scroll-jacking, but it is motion somebody may not want — and all thirty-five switch it back to auto inside a prefers-reduced-motion block. That media feature detects a setting the visitor has deliberately turned on to minimise non-essential motion, and all sixty templates respond to it somewhere.
Half of it needs a mouse: also no, and this one surprised us
The failure this warning describes is specific: content that only exists in a hover state. A caption that appears when the cursor is over a card, a submenu that opens on hover, a description revealed behind an image. On a touchscreen there is no cursor, so either the content is unreachable or it appears on the first tap and then sticks there.
We expected to find a lot of this, because fifty-three of the sixty files contain hover rules and there are four hundred and seventy such rules between them. Almost none of them matter. Reading the declarations inside each one, only nineteen change what is actually visible rather than what colour or size something is — the other four hundred and fifty-one shift a shade, lift a shadow, nudge a transform.
Of those nineteen, ten name a focus state in the same selector, so a tap or the Tab key reaches the identical result. The nine that respond to hover alone are all small affordances on things that are themselves tappable: six are the arrow button on the classic tier’s image carousel, one a navigation icon, one a category icon, one a social link. Nothing in this catalogue keeps information behind a cursor. Forty-nine of the sixty use focus-visible somewhere, which is a better keyboard showing than we would have predicted before counting.
It will stop you pinching to zoom: no, in all sixty
This is the shortest check and the one most worth running on anything you are about to buy, because it takes one line of HTML to get wrong and it locks out anyone who needs larger text. A viewport meta tag carrying user-scalable=no, or maximum-scale=1, tells the browser to refuse pinch zoom.
All sixty templates declare a viewport meta tag. None of the sixty sets either value. Pinch zoom works everywhere in this catalogue. We are reporting it because it is the kind of thing that is invisible until somebody who needs it finds it missing, not because avoiding an own goal deserves credit.
Full-screen sections are the wrong height: true in eight files
Here is the mechanism, because the fix depends on it. When you write a height of 100vh, you are not asking for the height of the screen the visitor can see. MDN is explicit that vh is equivalent to lvh — the large viewport, meaning the viewport as it would be with the browser’s retractable interface hidden. On a phone that interface is showing when the page loads. So a section sized at 100vh is taller than the visible area by the height of the address bar, from the first paint until the visitor scrolls enough to retract it.
CSS has two newer units for this. svh is the small viewport — the height with the browser interface expanded — so a section sized in svh always fits, at the cost of leaving a strip of the next section showing once the bar retracts. dvh tracks the real height live as the bar moves, which is exactly what you want for a hero and, as MDN warns, can also resize content mid-scroll and cost you frames.
Thirty-eight of the sixty templates declare a full-screen section. Not one of them uses plain vh on its own for it: nineteen use a dynamic unit only, and nineteen declare both. Declaring both is the right instinct, because a browser that does not understand svh ignores that declaration and falls back to the vh one. But the order is the whole trick. The cascade applies the last declaration of a property, so the fallback has to come first.
| Order written | What a modern browser applies | Templates |
|---|---|---|
| vh first, then svh | svh — correct | Thailand Tours, AI Solutions, Travel & Visa, Velocity, Aurora |
| svh first, then vh | vh — the fallback wins, svh never applies | Vermeil, Digital Infrastructure, Quarry, Meridian, Commercial Real Estate, Boulevard, Cadence, Pigment |
| both units, but on different elements | each as written; not a pair | Aperture, Coastal Route, Living Facade, Neon Avenue, Palm District, The Ascent |
The eight in the middle row have it backwards. Each writes min-height: 100svh and then min-height: 100vh immediately after it, in the same rule, three times over — at 100, 130 and 104 — so twenty-four declarations in total that were meant to be the modern behaviour and are instead overridden by the old one. Every browser that understands svh throws it away. The visible result is the thing the warning describes: on a phone, those sections are taller than the screen by the height of the address bar.
This is a real defect in our own inventory and we would rather you heard it here than found it after handover. It is also about as cheap as a defect gets: swapping the order of two adjacent lines fixes each instance. Templates affected are Vermeil, Formynex Digital Infrastructure, Quarry, Meridian, Formynex Commercial Real Estate, Boulevard, Cadence and Pigment.
Which unit belongs where, since the answer is not "use dvh"
The reason the fix above is a reordering and not a search-and-replace is that plain vh is the correct unit in a scroll-driven template more often than you would think. Twenty-six of these templates build their sequence on a tall invisible element — a runway the page scrolls down while the scene on top of it animates. Those runways are declared between 210vh and 1000vh, and every one of the fifty-four declarations uses plain vh.
That is deliberate and it should stay that way. A runway written in dvh would change length while the visitor scrolls, because retracting the address bar changes what dvh resolves to. Every keyframe in the sequence is positioned as a fraction of that length, so the whole animation would shift under the reader’s thumb halfway down. The one exception in the catalogue is Orbital HUD, whose panel track is a multiple of svh — also a stable unit, so also safe.
A section meant to fill the screen: svh if you would rather it always fit and accept a strip of the next section showing, dvh if you want it to track the bar exactly and can afford the reflow. Write the plain vh value first as the fallback, then the new one.
A scroll runway, or anything a keyframe is measured against: plain vh or svh. Never dvh. A value that moves mid-gesture is the one thing a scroll sequence cannot absorb.
A modal, a panel or a dropdown: cap it. Every template here that does this writes something like max-height: min(86vh, 760px), which bounds the variation with a pixel value so the address bar cannot push a close button off screen.
Type sized to the viewport: check it at 320px wide before you commit. That is a different problem and we have written about what happens to a long company name in display type.
What these templates take away on purpose
One genuine tradeoff did come out of the reading, and it is a choice rather than a mistake. Twenty-six of the sixty set overscroll-behavior, most often as overscroll-behavior-y: none. MDN is direct about what that does: it stops scroll chaining, and it disables native browser navigation including the vertical pull-to-refresh gesture.
For a scene driven by scroll position, the reasoning is sound — a rubber-band bounce at the top of a sequence looks like a bug, and an accidental pull-to-refresh halfway through restarts the whole thing. But it is your visitor’s gesture being removed, on every one of those twenty-six templates, and it is worth knowing that is a decision somebody made rather than a browser default.
The two tiers also diverge sharply here, which is the clearest single difference between them that we have measured. All eighteen classic templates use CSS scroll snap, and none of the forty-two interactive ones do. All twenty-six templates setting overscroll-behavior are interactive, and no classic one does. Nineteen use position: sticky, split ten to nine across the two. If you want to understand what you are choosing between, that split is a better guide than the category labels — the same point the architecture guide reached from a different direction.
What a source read cannot tell you about a phone
Everything above is a property of the files. None of it is a measurement of a phone. A template can use every unit correctly and still animate at fifteen frames a second on a four-year-old handset, and nothing here tells you which ones do, because we have not run these scenes on a range of real devices and will not publish a frame rate we did not record. The units decide whether the layout is the right size; the hardware decides whether the motion is smooth.
The hover counting has a limit too. We classified a rule by the declarations inside it, so a hover state whose content is revealed by a script rather than by CSS would not appear in those numbers. We found no such case while reading, but absence of evidence from one search method is not the same as a guarantee.
The honest way to use all of this: open any demo on your own phone, turn it landscape, and scroll it to the bottom and back. Then pinch it. What you are checking is whether the first screen fits before you scroll, which is the symptom of the one defect above. If you want the rest of the pre-launch list, what your visitors see when the 3D does not load covers the failure modes this guide does not.
Sources
The documentation referred to above, at source. Everything said about the Formynex catalogue was counted from the templates themselves.
