Parallax Layer Size Planner
Work out how tall a parallax layer must be, plus why a half-speed layer needs twice the viewport and a hand-picked 120 per cent never works.
The outer box is the viewport and the inner bar is the layer, drawn at the height it must be to stay covered through the whole scroll. Drag the scroll slider to see where its edges end up. Nothing is uploaded.
A moving layer has to be taller, by an exact amount
Speed here is how far the layer travels relative to the viewport, as a fraction of the distance scrolled. A layer at speed s crosses s × scroll of viewport, and it has to be that much taller than the viewport or its trailing edge comes into view before the section ends.
| Speed | Travel over 2000px | Extra height needed | Total height | As a scale |
|---|---|---|---|---|
| 0 | 0px | 0px | 900px | 1.00× |
| 0.2 | 400px | 400px | 1300px | 1.44× |
| 0.4 | 800px | 800px | 1700px | 1.89× |
| 0.5 | 1000px | 1000px | 1900px | 2.11× |
| 0.6 | 1200px | 1200px | 2100px | 2.33× |
| 0.8 | 1600px | 1600px | 2500px | 2.78× |
| 1 | 2000px | 2000px | 2900px | 3.22× |
| 1.2 | 2400px | 2400px | 3300px | 3.67× |
Over a 2000px scroll a half-speed layer travels 1000px and needs a
900px viewport plus that — 2.11× the viewport.
Which is why hand-picked values like background-size: 120% reveal their seams
partway down: they are short by a factor of two, not by a few per cent. A pinned layer at
speed 0 is free; one at speed 1 travels with the content and needs the entire scroll range
added, which is just the statement that ordinary background art must be as tall as its section.
Above speed 1 the layer outruns the content and costs more height than the scroll range itself — the same straight line, simply continued past where it is usually drawn.
The same layer costs more in a longer section
The requirement is linear in the scroll range, so it is not a property of the speed alone. A half-speed layer needs 1.22× the viewport across a 400px section and 3.22× across a 4000px one.
| Scroll range | Scale a half-speed layer needs |
|---|---|
| 400px | 1.22× |
| 900px | 1.50× |
| 2000px | 2.11× |
| 4000px | 3.22× |
This is the failure mode worth knowing about: a parallax layer tuned in a short hero and then reused in a long section breaks with no change to the layer at all. The layer did not get worse — the section got longer, and the requirement grew with it.
Offsets and trigger ranges
The layer's own transform is simply −speed × the distance scrolled, so nothing has moved before the scroll begins and a speed of zero never moves at all. Progress through a trigger range is clamped at both ends, so a scroll position before the range reads as 0 and one past it reads as 1 rather than running off. A range of zero length counts as complete rather than dividing by nothing — the edge case that otherwise produces a silent NaN in the transform.
How to use
- Set the layer speed and the scroll range.
- Read the height the layer must actually be.
- Drag the scroll slider to see its edges move.
- Change the scroll range and watch the requirement grow.
Frequently asked questions
How tall does a parallax layer need to be?
The viewport height plus the speed times the scroll range. A layer at half speed across a 2,000 pixel scroll travels 1,000 pixels relative to the viewport, so on a 900 pixel viewport it needs to be 1,900 pixels tall — a scale of 2.11, not the 1.2 that gets typed in by hand.
What does speed mean here?
How far the layer travels relative to the viewport, as a fraction of the distance scrolled. Zero is pinned and never moves. One travels with the content, which is ordinary background art and needs to be as tall as its whole section. Parallax proper lives strictly between.
Why does my parallax reveal its edge partway down?
Because the layer is short. The requirement is exact rather than a matter of taste: any less than speed times the scroll range of extra height and the trailing edge is guaranteed to come into view before the section ends. A hand-picked 120 per cent is short by a factor of two at half speed.
It worked in my hero and broke in a longer section. Why?
Because the requirement is linear in the scroll range, not a property of the speed alone. The same half-speed layer needs 1.22 times the viewport across a 400 pixel section and 3.22 times across a 4,000 pixel one. The layer did not get worse; the section got longer.
What about speeds above one?
The layer outruns the content and costs more height than the scroll range itself. It is the same straight line, simply continued past where it is usually drawn, so the arithmetic needs no special case.
What happens at the ends of a scroll trigger?
Progress is clamped, so a position before the range reads as zero and one past it reads as one rather than running off into negative or over-unity transforms. A range of zero length counts as complete rather than dividing by nothing, which is the edge case that otherwise produces a silent NaN.
Does this send anything anywhere?
No. Everything is computed in your browser, and nothing is uploaded.
🔒 This tool runs entirely in your browser. Nothing you enter is uploaded, logged, or stored.