Linking CSS properties with scroll position: A proposal

As I, and many others have written before, on mobile, rendering/processing of JS is done asynchronously to responding to the user scrolling, so that we can maintain touch response and screen update. We basically have no chance of consistently hitting 60fps if we don’t do this (and you can witness what happens if you don’t by running desktop Firefox (for now)). This does mean, however, that you end up with bugs like this, where people respond in JavaScript to the scroll position changing and end up with jerky animation because there are no guarantees about the frequency or timeliness of scroll position updates. It also means that neat parallax sites like this can’t be done in quite the same way on mobile. Although this is currently only a problem on mobile, this will eventually affect desktop too. I believe that Internet Explorer already uses asynchronous composition on the desktop, and I think that’s the way we’re going in Firefox too. It’d be great to have a solution for this problem first.

It’s obvious that we could do with a way of declaring a link between a CSS property and the scroll position. My immediate thought is to do this via CSS. I had this idea for a syntax:

This would work quite similarly to standard transitions, where a limited number of properties would be supported, and perhaps their interpolation could be defined in the same way too. Relative scroll position is 0px when the scroll position of the particular axis matches the element’s offset position. This would lead to declarations like this:

This would define a transition that would grow and fade in an element as the user scrolled it towards 100px down the page, then shrink and fade out as you scrolled beyond that point.

But then Paul Rouget made me aware that Anthony Ricaud had the same idea, but instead of this slightly arcane syntax, to tie it to CSS animation keyframes. I think this is more easily implemented (at least in Firefox’s case), more flexible and more easily expressed by designers too. Much like transitions and animations, these need not be mutually exclusive though, I suppose (though the interactions between them might mean as a platform developer, it’d be in my best interests to suggest that they should :)).

I’m not aware of any proposal of this suggestion, so I’ll describe the syntax that I would expect. I think it should inherit from the CSS animation spec, but prefix the animation-* properties with scroll-. Instead of animation-duration, you would have scroll-animation-bounds. scroll-animation-bounds would describe a vector, the distance along which would determine the position of the animation. Imagine that this vector was actually a plane, that extended infinitely, perpendicular to its direction of travel; your distance along the vector is unaffected by your distance to the vector. In other words, if you had a scroll-animation-bounds that described a line going straight down, your horizontal scroll position wouldn’t affect the animation. Animation keyframes would be defined in the exact same way.

[Edit] Paul Rouget makes the suggestion that rather than having a prefixed copy of animation, that a new property be introduced, animation-controller, of which the default would be time, but a new option could be scroll. We would still need an equivalent to duration, so I would re-purpose my above-suggested property as animation-scroll-bounds.

What do people think about either of these suggestions? I’d love to hear some conversation/suggestions/criticisms in the comments, after which perhaps I can submit a revised proposal and begin an implementation.

4 Replies to “Linking CSS properties with scroll position: A proposal”

  1. It’s a good idea, although my understanding was that these kind of enhancements were generally being deferred until Web Animations[1] was standardised and implemented[2][3], as it will provide a unified timing model for CSS transitions, animations and SMIL, and is intended to be extended with non-clock sources of timing values, such as scrolling, UI gestures, device orientation, etc.


  2. What about tying it to the variables proposal, by having some built-in variables for scroll positions (absolute and percentage), and supporting variable references and calc()?

  3. I’ve always wanted something like this using just the current transition/animation syntax. i.e. something like:

    .div {
    transition-property: transform;
    transition-duration: 0px 50px;
    transition-delay: 0px 500px;

    i.e. from scrollY 500px to 550px (or maybe you’d be better to use vh units?), we’d interpolate and apply the transform property. Is that essentially what you’re proposing? Do we need more properties or just the ability to interchange space and time at will 🙂

  4. I too have wanted something like this. the :target selector has been fun to work with, and I would see the scroll position as something that could be used similarly.

    :scroll(minX, minY, maxX, maxY)

    body:scroll(0, 200px, 0, 400px) .something {}

    Or if it is an overflow auto/scroll parent, you could apply it to that:
    .parent:scroll(0, 20%, 0, 50%) .somthing {}

Leave a Reply

Your email address will not be published. Required fields are marked *