[csswg-drafts] [scroll-animations-1] CSS @scroll-timeline: Allow `<element-offset>` selector() to point to self (#5884)

bramus has just created a new issue for https://github.com/w3c/csswg-drafts:

== [scroll-animations-1] CSS @scroll-timeline: Allow `<element-offset>` selector() to point to self ==
When animating an element based on the location of the element itself inside a scroll container using [scroll-animations](https://drafts.csswg.org/scroll-animations-1/), you need to set a `start` and `end`. To configure this one needs [an Element-based Offset](https://drafts.csswg.org/scroll-animations-1/#element-based-offset-section).

When applying such an animation using the JavaScript it's pretty easy to set this up for many elements, as you can use a loop and refer to the current element by referring to its local var. See `startScrollOffset`/`endScrollOffset` in the code snippet below.

```js
const $listView = document.querySelector('ul');
const $listItems = document.querySelectorAll('ul > li');

$listItems.forEach(($listItem) => {
 // Slide-In
 new Animation(
  new KeyframeEffect(
   $listItem,
   {
    transform: ["translateX(-100%)", "translateX(0)"],
   },
   { duration: 1, fill: "both" }
  ),
  new ScrollTimeline({
   scrollSource: $listView,
   timeRange: 1,
    fill: "both",
   startScrollOffset: { target: $listItem, edge: 'end', threshold: 0 },
   endScrollOffset: { target: $listItem, edge: 'end', threshold: 1 },
  })
 ).play();
 
});
```

While trying to recreate this using the CSS @​scroll-timeline I've noticed that this this type of concise code is exactly possible as the `<element-offset>` type requires a `selector(<id-selector>)`. Because of that one has to create @​scroll-timeline's for every individual `li`

```css
@supports (animation-timeline: works) {
 @keyframes fade-in {
  from {
   transform: translateX(-100%);
  }
  to {
   transform: translateX(0);
  }
 }

 li {
  transform: translateX(-100%);
  animation: 1s fade-in linear forwards;
 }

        /* Scroll Timeline for first item */
 @scroll-timeline list-item-1 {
  source: selector(ul);
  start: selector(#list-item-1) end 0;
  end: selector(#list-item-1) end 1;
  time-range: 1s;
 }
 #list-item-1 {
  animation-timeline: list-item-1;
 }

        /* Scroll Timeline for second item */ 
 @scroll-timeline list-item-2 {
  source: selector(ul);
  start: selector(#list-item-2) end 0;
  end: selector(#list-item-2) end 1;
  time-range: 1s;
 }
 #list-item-2 {
  animation-timeline: list-item-2;
 }
 
        /* Scroll Timeline for third item */
 @scroll-timeline list-item-3 {
  source: selector(ul);
  start: selector(#list-item-3) end 0;
  end: selector(#list-item-3) end 1;
  time-range: 1s;
 }
 #list-item-3 {
  animation-timeline: list-item-3;
 }

       /* Now rinse and repeat for the next 100 elements … */

}
```

To not have to repeat that @​scroll-timeline definition over and over again for each and every single `li`, **it'd be handy if the `selector()` part in the `<element-offset>` could be configured in such a way that it refers to the element being animated itself**, e.g. `this` or `self`.

That way our code would become something like this:

```css
@supports (animation-timeline: works) {
 @keyframes slide-in {
  from {
   transform: translateX(-100%);
  }
  to {
   transform: translateX(0);
  }
 }

 @scroll-timeline slide-in-in-parent-ul {
  source: selector(ul);
  start: selector(self) end 0;
  end: selector(self) end 1;
  time-range: 1s;
 }

 li {
  transform: translateX(-100%);
  animation: 1s slide-in linear forwards slide-in-in-parent-ul;
 }

}
```

I see this as a huge benefit to the spec, as this would open up the way for animation/code reuse.

Would this be something worth pursuing, or am I overlooking something in the spec that would already allow this?

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/5884 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Thursday, 21 January 2021 08:11:29 UTC