[csswg-drafts] CSS Syntax design considerations and alternatives (#4338)

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

== CSS Syntax design considerations and alternatives  ==
This issue is meant to help consider alternatives and different design for scroll timeline css syntax assuming the current general working models. Note that if we drastically alter the working models of scroll-linked animations these design discussions may not apply. 


## Assumptions
[scroll-linked animation interaction model](https://wicg.github.io/scroll-animations/#scroll-linked-animations-usecase): basically, ScrollTimeline outputs time values that directly drive a regular web Animation by setting its currentTime.

ScrollTimeline properties:
 * start, end offset
 * scroll source (single element)
 * orientation, timeRange, fill mode

## Timeline Syntax

### A) Timeline Property 
This is the current standing syntax proposal which basically adds a new animation property that can be used to adjust each individual animations. The property takes a css function which allows various timeline props to be configures using that function parameters.

```css
  @keyframes progress {
    from {
      width: 0vw;
    }
    to {
      width: 100vw;
    }
  }
  .progress {
    animation-name: progress;
    animation-duration: 1s;
    animation-timing-function: linear;
    /* Assume the HTML element has id 'root' */
    animation-timeline: scroll(element(#root), vertical);
  }
```

Pros:
 - Simple to add and understand
- Fairly simple to implement i.e., no need to introduce a new @rule syntax.

Cons:
 - Not possible to use a single timeline instance with multiple animations (This may actually be a pro too :) )
- Jamming all various properties of the scroll timeline into a css function seems a bit awkward.

Note that w3c/scroll-animations#25 points our that the current `scroll()` function syntax need revision but that is a minor change.

### B) @Timeline rule

This is mostly based on the proposal in w3c/scroll-animations#48 but only limited to parts relevant to current interaction model. 
 
```css 
@timeline root-scroller-timeline {
  timeline-type: scroll; 
  timeline-node: selector(:root) ; /* the element that controls this timeline;
         the selector would match a single element using document.querySelector() rules */
  scroll-direction: block; /* descriptors that are specific to scroll timelines */
  scroll-offset-start: 5rem;
  scroll-offset-end: calc(100% - 5rem); /* scroll-offset-end instead of end-scroll-offset
          so that we could have a scroll-offset shorthand */ 
}
@keyframes progress {
  from {
    width: 0vw;
  }
  to {
    width: 100vw;
  }
}
.progress {
   animation-name: progress;
   animation-duration: duration(root-scroller-timeline); /* maybe also use it with calc. */
   animation-timeline: root-scroller-timeline;
 }
```

Pros:
 - giving timeline its own name means that we can use it in multiple locations e.g., see how animation-duration is linked to the timeline duration.
 -  solution here can also be used when it comes to scroll triggered animations e.g., maybe 
```css
@trigger point(root-scroller-timeline, 10%) {
  /* declare transition here */
}
```

Cons:
 -  @birtles pointed out that "`@keyframes` is already quite problematic when it comes to shadow DOM etc. due to the requirement to have a globally unique name. It also makes generating `@keyframes` from script a pain. I wonder if we could find an alternative mechanism that allows names to be re-used somehow? Perhaps something along the lines of how counters work?"


### Other relevant questions 

How should the css specified timelines map to JS instances?
One approach is to create a separate timeline instance for each animation/timeline pair. This limits the each scroll-timeline to be assigned to a single animation which keeps things simple avoiding potential complications  such as w3c/scroll-animations#35 but it may be counter intuitive specially for the rule-based syntax. (Note that ScrollTimelines are fairly cheap to create)

The other is to treat each declaration as an instance and then use that instance for all animations that match 

Do we need a special syntax to identify the viewport scroller?
This  is specially important for scroll-linked effects inside iframes that want to reference "viewport".

## Scroll Source Element Selector

The current proposals assumes the following construct that helps select the source of scroll timeline in CSS:

`element(<id-selector>)` or `selector(<selector-list>`

The rough desired behavior is that the selector would match a single element using either getElementById() or document.querySelector() rules. But AFAICT this is the first time in css we allow such a construct (e.g., a selectors inside the css declaration) so it is worth making sure it is safe and efficient.

Some other questions that we need to answer:

- is this live? i.e., if dom elements are added to the page so that querySelector would return a new element will we switch the source. I think it should be given that we need this semantic at least for the first assignment but do we allow re-assignment

- which one? why limit to element id selectors when we can potentially allow any selector as long as we apply the querySelector semantic on top

- Implementation wise, is this something that can be done in existing style engines?

If these type of element selector is undesirable and alternative may be to do something like "allow scroll source to be the nearest ancestor scroller with a given name or attribute". This is more limited but maybe this is good enough?!

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

Received on Thursday, 19 September 2019 05:41:13 UTC