[CSSWG] Minutes Virtual TPAC Meeting 2021-09-29 Part II: Scroll Animations, CSS Values, CSS Color [scroll-animations] [css-values] [css-color]

=========================================
  These are the official CSSWG minutes.
  Unless you're correcting the minutes,
 Please respond by starting a new thread
   with an appropriate subject line.
=========================================


Scroll Animations
-----------------

  - RESOLVED: Adopt fantasai/miriam's new direction for the declarative
              side of scroll-linked animations (Issue #6674: Rethinking
              declarative syntax for scroll-linked animations)
              https://github.com/w3c/csswg-drafts/issues/6674
  - RESOLVED: Add flackr as editor to scroll-animations, move Majid to
              Former

CSS Values
----------

  - RESOLVED: Accept mix() function into Values 4 (Issue #6245:
              Interpolating values between breakpoints)

CSS Color
---------

  - RESOLVED: Accept proposal to have 'none' / NaN represent missing
              channel (Issue #6107: Achromatic colors converted to
              hue-ish spaces should treat hue as "missing", not NaN)

===== FULL MINUTES BELOW ======

Agenda: https://github.com/w3c/csswg-drafts/projects/22

Scribe: TabAtkins
Scribe's scribe: fantasai


Scroll Animations
=================

Rethinking declarative syntax for scroll-linked animations
----------------------------------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/6674
  <fantasai> See full discussion at https://wiki.csswg.org/ideas/timelines ;
             this crosses multiple issues (into which we posted pieces
             of that overall proposal)

  miriam: So we were looking at scroll-linked animations (SLA) as part
          of a bigger thing
  miriam: Was looking at container-based interpolations, and ideally
          being able to interpolate values *in* the cascade rather than
          jumping out to animations which override everything
  miriam: Current SLA proposal seems JS-focused and later ported to
          CSS, so we wanted to discuss this
  miriam: Rethinking how we could make sure SLAs, already in prototype,
          fit into our future plans for animations/interpolation

  miriam: Several parts
  miriam: Animations based on where you are in the scroll position of a
          container
  miriam: So 0% - 100%, linked to an animation progress
  miriam: Proposal is thus for an animation-timeline property (already
          in the SLA proposal), defaults to auto, but can be given a
          scroll() function.
  miriam: Defaults to looking at nearest scrollable ancestor, you can
          specify what direction you want to listen to.
  miriam: And can opt to look at root scroller, or a given container's
          name (specified in container-name property, re-using from the
          @container query proposal)
  miriam: An alternative to that syntax is that instead of a scroll()
          function, could break out scroll-timeline-* properties
  miriam: Using the function in animation-timeline seemed like an
          extensible way to do more timeline types in the same property
  flackr: Is there a functional difference there? You could specify
          scroll() or a timeline name in animation-timeline?
  miriam: Right
  flackr: So even if it is a function, we have the ability to specify
          other timeline types with a timeline name
  miriam: So I think that's all handled by the larger proposal for SLA

  miriam: Another thing - wanting to animate on elements coming into or
          out of view. These element-based timelines work a little
          differently
  miriam: Proposing view-timeline-* properties
  miriam: view-timeline-name specifies the name of a timeline
          corresponding to the element coming in or out of view
  miriam: view-timeline-inset to adjust how quickly it considers itself
          in view
  miriam: and view-timeline-fit gives the baseline for where 0% is -
          start when they start to come into view, or start when fully
          into view
  miriam: Also a question for if we need a timeline for that in-between
          space, between when it start to come into view and is fully
          in view
  miriam: In terms of scroll-linked timelines, were thinking these
          timelines would be visible to descendants and siblings; scope
          is attached to descendants of the parent
  fantasai: One suggestion was to expose it to the whole document
  fantasai: Could do this
  fantasai: But it's important to resolve name conflicts with closer in
            the tree, not later in stylesheet or tree
  fantasai: Multiple subtrees styled with the same timeline name should
            animate independently

  <flackr> https://github.com/w3c/csswg-drafts/issues/4912
  flackr: We did have use-cases initially with scroll-timeline where
          author wanted to specify for a certain number of pixels of
          scroll (largely for parallax effects, but we had others)
  flackr: I assume that to do this with the new proposal you'd need an
          element that corresponded to the number of pixels you want to
          animate over?
  flackr: Because the scroll() function is always from 0 to max scroll
  flackr: And specifying in terms of %s is dependent on layout which is
          complicated
  miriam: I don't think we covered that use-case, we'll have to think
          about it

  smfr: A few things
  smfr: For animations that run when an element comes into view,
        there's subtlety what designers want
  smfr: Possibly some hysteresis; if you wobble it around the trigger
        point you want a looser organic feel
  smfr: So feel designers will want more specific control
  fantasai: I think you're mixing up scroll-linked and scroll-triggered
            animations
  fantasai: SLA, the scroll position *is* the timeline. if you move the
            scroller it scrubs the animations backwards
  fantasai: scroll-triggered is a timed animation that triggers when it
            comes into view
  fantasai: The SLA in general is not targetting that use-case
  smfr: I think I've seen examples that are scroll-linked but do have
        hysteresis
  smfr: Some Apple pages have things that are linked to scroll position
        but still not precisely linked
  smfr: Some time delay
  flackr: I've seen this too, some examples of animations that are
          specifically lagged behind the timeline to provide some extra
          smoothness
  smfr: So my problem is just making sure it's rich enough to address
        designer use-cases, or else they'll still just write JS
  Rossen: So are your examples addressed more if you have some sort of
          easing function that is part of the change?
  Rossen: So you have some easing between hops?
  smfr: I don't think easing is enough; I think there has to be some
        time-based aspect
  flackr: Could just be a lot of scroll triggers with easing...
  smfr: Here's an example
  <smfr> https://www.apple.com/iphone-13-pro/
  smfr: There's an image showing the camera bumps, it's somewhat
        scroll-linked, but then it's sticky...
  fantasai: We do have the *-inset property, which gives a *spatial*
            delay
  flackr: Further down where it says "shoot it, cut it, ship it" seems
          to be the effect Simon's talking about
  Rossen: So we can record Simon's concern in the issue, but I want to
          keep the conversation moving

  smfr: Is it possible for an SLA to affect the size of the scrolled
        content, so we get circularity?
  flackr: Yes, this has always been the case. We choose to handle it
          similar to :hover examples
  flackr: You get the scroll position at the start of the frame, and if
          you change the size, the next frame will get an updated
          animation progress.
  smfr: So that'll be specified in terms of the HTML event loop
  florian: Seems a little worse than :hover, as it can loop without
           further user interaction
  <fremy> +1 to what florian just said, I was about to say the same
  TabAtkins: Nothing in the spec to that effect, could have it flicker
             madly under the cursor

  flackr: Back to the lag thing, we could have something like
          transitions where the animation progress eases over time
          rather than immediately updates. We'd have to look into it

  <fantasai> https://drafts.csswg.org/scroll-animations-1/
  fantasai: Worth reminding that there is a SLA ED that was already
            adopted
  fantasai: Our issue was just about redesigning how the declarative
            syntax works
  fantasai: Question is, do we want to make changes going in this
            direction

  flackr: Overall I think this is a nice change. There's some use-cases
          we should consider that we might be dropping, but I'm
          supportive of this overall direction.
  flackr: We should probably change the JS API to roughly match the
          proposed CSS timelines; view-timeline and scroll-timeline as
          things you con construct, but also keep the arbitrary-element
          selection that the JS API can allow
  fantasai: Yeah we didn't review the JS part at all; figured we'd hash
            this out and then bring it back to JS

  Rossen: Last comments or objections?

  RESOLVED: Adopt fantasai/miriam's new direction for the declarative
            side of scroll-linked animations
  RESOLVED: Add flackr as editor to scroll-animations, move Majid to
            Former

  [other editors are all still fine]

CSS Values
==========

Interpolating values between breakpoints
----------------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/6245

  <fantasai> https://github.com/w3c/csswg-drafts/issues/6245#issuecomment-926351855
  miriam: This is building on that same idea, but creating timelines
          out of MQ/CQs
  miriam: In this case you're more often doing interpolated values
          based on the timeline, not animations specifically
  miriam: We want to be able to create timelines off the size of the
          container
  miriam: So for defining the query timeline, we have an @timeline
          syntax.
  miriam: Give it a name, say what we're querying, what feature we're
          querying
  miriam: And give it a from/to value to offset that range
  miriam: So interp between a container being 100px and 40em to define
          the timeline
  miriam: If it's a CQ we give the name of the container
  miriam: If there are multiple CQs with that name this'll apply to all
          of them
  miriam: Kids will look at their appropriate ancestor container

  miriam: We can use the timeline name in an animation-timeline
  miriam: But more often we'll want a value that interps in the cascade
          instead, so we can override it if we need to
  miriam: A generic interpolate() function has been discussed for a
          long time
  miriam: We called in mix() here, named TBD
  miriam: Idea is it could be generic, taking a %, or take a timeline
          which resolves to a %. Could invoke scroll timelines too, etc.
  miriam: And then it takes an easing function and two values to interp
          between
  miriam: In some cases this'll get more complex with multiple values,
          maybe get quite long
  miriam: Wondered if mix() could ref keyframes
  miriam: So you could pull out the value details into keyframes for
          more detailed control

  fantasai: I wanted to point out the cascade effects
  fantasai: We considered putting query-based timelines as a value of
            animation-timeline
  fantasai: That ends up applying all the props at once, and at an
            overriding level of the cascade
  fantasai: Usually you don't want that, you just want to specify a
            value at a normal cascade spot, but *based on* a timeline
  fantasai: So my font-size timeline can just spec an interpolated
            normal font size, and then have a more specific rule setting
            the font-size to a specific value as usual in the cascade.

  flackr: I think what fantasai just said might change my q...
  flackr: So this isn't an animation timeline, it only exists for the
          mix() function?
  fantasai: We were debating that.
  fantasai: We definitely want it for mix(). Whether it's available for
            animation-timeline is an open question
  fantasai: We've asked brian for feedback and he pointed out there
            were a lot of complexities, so we might not want to do it
  fantasai: Not the most important; mix() is the primary case
  flackr: Yeah was gonna raise the same complexities; if it's
          animation, we have to have the animation progress update in
          the middle of the cascade.
  flackr: Anders said it would be a huge technical burden to have
          animations update as part of the cascade due to the cascade

  smfr: This feels like calc() to me
  smfr: We could have one that interps with easing funcs
  smfr: Missing piece is input from media features, could come in as
        env()
  smfr: And so with a calc easing function thing
  TabAtkins: Not quite, implies only doing calc()-able things
  TabAtkins: Not all things that can be interpolated
  TabAtkins: which includes colors, etc.
  smfr: Can we make calc() accept these things?
  TabAtkins: I don't want to but we can talk about it?

  ChrisL: So this is unpopular
  ChrisL: We start by lerping two values
  ChrisL: Then we add more values and lerp them
  ChrisL: And if you draw that it's jaggy on a graph because slopes are
          different
  ChrisL: And then we add easings, and you can maybe fake it to look
          continuous
  ChrisL: But we never get to a thing that smoothly interpolates thru N
          values
  ChrisL: Is that something we want to do or just continue keeping it
         pairwise?
  flackr: Is this not having easing on the mix function?
  ChrisL: That requires the author to figure out C1 continuity on their
          own
  fantasai: This seems compatible with what keyframes do right now, we
            could default to smooth interp
  TabAtkins: So ChrisL's request is for the ability to spec an animation
             with N values and have it automatically smoothly interp,
             rather than only having pairwise interp control that needs
             manual adjustment
  ChrisL: yes
  TabAtkins: c1 continuity, to be specific
  fantasai: We specced multi-stop animations using @keyframes, see last
            section of proposal

  TabAtkins: I suspect that's something we can handle at a higher level
  TabAtkins: We have a default for pairwise interpolation, default to ?
  TabAtkins: Could do smarter things in animations
  TabAtkins: Fits within existing syntax structure of animations
  flackr: It will be challenging, though
  flackr: easing function per keyframe is just between those endpoints
  flackr: easing function on animation is just input time to output time
  TabAtkins: animation-easing-function is the default between frames
  flackr: That's correct for CSS. Web Animations also adds an easing
          curve to the timeline
  TabAtkins: You're easing time into massaged version, that's separate
             from this
  fantasai: I think we could easily have a "tweak the time"-based
            version, we could add that into the @timeline rule as well
  fantasai: Intention of mix() argument was the default easing between
            frames
  fantasai: If we want to default to doing continuous magic, or adding
            a keyword to opt into it, that's fine
  flackr: Yeah it would be like combining adjacent pairs that have the
          same value into one continuous timing function

  fantasai: I want to point out we don't have a resolution on the form
            of the generic interp function
  fantasai: So our proposal is to have it accept %s and two values
  <fantasai> https://github.com/w3c/csswg-drafts/issues/581#issuecomment-926353789
  fantasai: So this proposal is a function that replaces the % with a
            timeline that computes to a %
  fantasai: We have a resolution to *add* a mix() function but didn't
            settle on the syntax
  Rossen: So what can we resolve on?

  fantasai: resolution the first: generic interpolate function is
            called mix(). Takes %, then start value, then end value.
            Values are separated with semicolons to avoid ambiguity
            with comma-containing values (you can interp a
            comma-separated list, for example)
  TabAtkins: Simon had some thoughts about this in calc(), do you want
             to continue talking about this?
  smfr: I'm not quite sold on @timeline yet, but I don't want to stall
        this
  <fantasai> https://github.com/w3c/csswg-drafts/issues/581
  fantasai: Right now it's just mix()
  smfr: Would this be like a calc()?
  fantasai: Like, but wider.
  fantasai: It has to be able to interpolate every possible computed
            value in the entire space of CSS
  smfr: It requires UAs to have a parallel version of calc trees, for
        every possible value
  fantasai: You kinda already have that since everything can interp
  fantasai: Like, how do you interp between currentcolor and blue? No
            way to represent that right now. (color-mix() is coming,
            but this is a wider issue)
  fantasai: So we have lots of places where we want to interp things
            that don't have intermediate values
  smfr: That makes sense, we also invented cross-fade() to hit the
        image case
  smfr: I'd like to hear from other impls about their thoughts on impl
        complexity, and whether it makes sense to think of it in terms
        of calc()
  TabAtkins: I don't have problem of thinking about it in terms of
             calc(), can re-use machinery there
  TabAtkins: but I think that's an internal detail
  fantasai: Note that we *resolved* to add the function years ago but
            didn't resolve on the syntax
  <fantasai> see also https://github.com/w3c/csswg-drafts/issues/2854

  RESOLVED: Accept mix() function into Values 4

  fantasai: So next is do we want mix() to accept a timeline+easing
            function instead of a %
  fantasai: If no, I don't need to go into details. If yes, we'd use
            the @timeline rule discussed previously.
  TabAtkins: This just got proposed last week, it's a little big. I'd
             like more time to review on it.
  fantasai: And this would def go into level 5

CSS Color
=========
  scribe: fantasai

Achromatic colors conversion to hue spaces
------------------------------------------
  github: https://github.com/w3c/csswg-drafts/issues/6107

  <TabAtkins> proposal:
https://github.com/w3c/csswg-drafts/issues/6107#issuecomment-929390142
  chris: Several situations where polar color can have undefined hue
  chris: e.g. gray, it doesn't have a chroma so it doesn't have a hue
         angle
  chris: this can occur quite a bit
  chris: In code this is often represented as Not A Number
  chris: If interpolating, if you don't have a hue and the other color
         has a hue, then you take that hue
  chris: so it's not the same as picking a random hue
  chris: There was a bunch of discussion
  chris: and the agreement was to do it like that
  chris: which has knock-on effects in OM
  chris: but the question is, what do we return
  chris: is it NaN or missing or what

  TabAtkins: Proposed that a color can be missing any of its components
  TabAtkins: Author can specify with 'none'
  TabAtkins: if interpolating between two colors and one has 'none', it
             takes the other side's value the entire time
  TabAtkins: this is similar to behavior with premultiplied alpha
  TabAtkins: if you either transition between two colors that are
             missing a channel
  TabAtkins: treat that as an error
  TabAtkins: Reflecting this, in CSS syntax it's a keyword
  TabAtkins: typedOM reflects that keyword
  TabAtkins: In color API, unclear whether we want to reflect as null
             or NaN
  TabAtkins: null is more idiomatic in WebPlatform
  TabAtkins: but in other color APIs tend to use NaN
  TabAtkins: NaN is more infectious
  TabAtkins: so if trying to combine NaN with other number, get NaN
  TabAtkins: I think Chris and Lea prefer NaN
  TabAtkins: So proposal is to go with that for the missing color
             channel

  fantasai: So what happens if you specify none for a channel that
            can't handle it?
  TabAtkins: Set to zero
  Rossen: Any objections?

  RESOLVED: Accept proposal to have 'none' / NaN represent missing
            channel

  smfr: Do we have to parse NaN in <number> context?
  TabAtkins: No, it's only usable as a keyword in calc()
  TabAtkins: Math functions can see NaN along with infinity, e, and pi
  smfr: So no need to construct NaN as color input anywhere?
  TabAtkins: If NaN tries to escape calc(), it gets censored into
             infinity
  TabAtkins: which gets clamped by the range of that context
  TabAtkins: so no HSL with NaN
  <TabAtkins> hsl(calc(NaN * 1deg), 50%, 100%)
  <TabAtkins> ^^^ just renders as an arbitrary hue, whatever the
              largest angle you can hold is
  Rossen: OK, let's end here. Thanks everyone for attending.

Received on Wednesday, 10 November 2021 00:01:11 UTC