Closed fantasai closed 1 year ago
We resolved on this in https://github.com/w3c/csswg-drafts/issues/8552#issuecomment-1476442986, no?
@bramus That applies to keyframes, this is about animation-range
.
I agree we should allow all values and not clamp them. This will allow authors to define animations that start just before or end just after particular ranges.
So they should not expand the attachment range and simply get clamped?
When you say clamped what do you mean? I just said I don't think we should clamp the values :-)
Note that currently if you try to animate beyond the cover range we will clip the animation to the cover range just as we clip keyframes outside of 0-100% to the active range. Update: After testing this seems to work fine in the chromium implementation - demo
Ugh. Read/wrote too fast. Clipping is what I intended.
So, by accepting all values and not clamping, would that stretch out the animation-range or would it clip?
It will stretch out the animation range. The thing you're specifying in animation-range is a start and end point on the timeline. There's nothing special about the specified range-name especially since the start and end range-name can be different and cross other ranges. (e.g. entry and exit).
@flackr @fantasai the clamped flow is also very important for many use-cases, e.g: effects that happen to appear on first/last folds, could happen with authoring tools or when shuffling layouts on different breakpoints.
It's good that by default we don't clamp, but it's very important that author can also choose to opt-in to respecting the effect playing from start to end regardless of layout.
If we could have something that behaves like min(0px, entry 0%)
that would allow this clamping, but this depends on what we resolve in #8672. If we allow <length-percentage>
to resolve to an absolute offset then we could allow authors to achieve that without any additional syntax.
Another issue with something like using min(entry 0%, contain 100%)
for start
in first fold, for example, is that it will just choose the lowest between the two, and not really interpolate and map the 0% progress to the actual starting point of the range.
So my use case is, if something has an effect that should run from 0% to 100% progress, regardless of layout, but it happens to load inside the viewport in first fold, then there's no range that the author can set and guarantee that it will happen.
If we could have something that behaves like
min(0px, entry 0%)
that would allow this clamping, but this depends on what we resolve in #8672.
Does it depend on #8672? Can't you specify all possibilities using the longhands?
If we allow
<length-percentage>
to resolve to an absolute offset then we could allow authors to achieve that without any additional syntax.
Using absolute offsets is already supported by spec using the non-named-range <length-percentage>
version of animation-range
on a scroll timeline. https://www.w3.org/TR/scroll-animations-1/#animation-range-start
There's an open bug to get this working in chromium's implementation.
Maybe we should revisit the range of view-timeline and make it so that it can reference ranges over the entire scroll which I think would directly support your use case, e.g.
.target {
/* Animate from initial scroll position to exit. */
animation-range-start: 0px;
animation-range-end: exit 100%;
}
Or if we want to allow for the start phase to be later than 0px,
.target {
/* Animate from initial scroll position to exit. */
animation-range-start: max(0px, entry 0%);
animation-range-end: exit 100%;
}
Another issue with something like using min(entry 0%, contain 100%) for start in first fold, for example, is that it will just choose the lowest between the two, and not really interpolate and map the 0% progress to the actual starting point of the range.
If the keyframes are not specified in terms of range attachment points, they will map to the entire range name, so a 0% keyframe will occur at the result of this range calculation.
Does it depend on https://github.com/w3c/csswg-drafts/issues/8672? Can't you specify all possibilities using the longhands?
If <percentage>
without a range name is not computed differently, i.e. expanded to a <name>
+ <percentage>
, then maybe it doesn't depend on #8672, but I was assuming that for view-timelines a <length-percentage>
will always be expanded that way.
Using absolute offsets is already supported by spec using the non-named-range
version of animation-range on a scroll timeline. https://www.w3.org/TR/scroll-animations-1/#animation-range-start There's an open bug to get this working in chromium's implementation.
Yes, we support <length>
for attaching to an absolute offset on scroll-timelines, but I was hoping we could use existing syntax to also limit effects and mapping their progress to the given layout.
Maybe we should revisit the range of view-timeline and make it so that it can reference ranges over the entire scroll which I think would directly support your use case, e.g.
.target { /* Animate from initial scroll position to exit. */ animation-range-start: 0px; animation-range-end: exit 100%; }
Yes, that could be useful. But I realize this should be on a separate issue (:
Back to the issue at hand, if I understand it correctly, the question is: "do we allow range offset values that correspond to outside the entire cover
range", correct?
So regarding @flackr's comment:
I agree we should allow all values and not clamp them. This will allow authors to define animations that start just before or end just after particular ranges.
This is specifically the case with effects like:
@keyframe parallax {
from {
transform: translateY(-500px);
}
to {
transform: translateY(500px);
}
}
.parallaxed {
animation: parallax both view();
animation-range: cover 0% cover 100%;
}
Because we ignore the transforms, the animation will actually start when the element is 500px above cover 0%
and end when the element is 500px below cover 100%
.
Now, there are 3 ways to tackle this:
view-timeline-inset: -500px
.animation-range: entry -500px exit 500px
or with calc()'s: calc(entry 0% - 500px) calc(exit 100% + 500px)
, but I assume these are equivalent, right?view-timeline
on a different element that's 1000px higher and the .parallaxed
element is centered inside it.Same can be said for effects where the animated element is offset from the view-timeline subject and or extends beyond it.
I think option 3 requires an extra element, so having to resort to that is a less desirable solution.
So, if my conclusion is correct, it's either we clamp for simplicity's sake, or we allow offsets that are out-of-range? I think we can allow out-of-range if that makes more sense to authors, no particular reason why not to allow it also.
Because we ignore the transforms, the animation will actually start when the element is 500px above cover 0%
Technically the element isn't 500px above cover until the animation starts 😉
I think that either options 1 or 2 should work. Note that the range name can't go inside the calc. Option 2 would be animation-range: entry -500px exit calc(100% + 500px);
. exit 500px
is equivalent to exit calc(0% + 500px)
which is 500px after the start of the exit range which isn't what you want in your use case.
So, if my conclusion is correct, it's either we clamp for simplicity's sake,
I don't think we should clamp. It results in animations which behave differently if the animated element is near the top/bottom of the document versus further down.
or we allow offsets that are out-of-range? I think we can allow out-of-range if that makes more sense to authors, no particular reason why not to allow it also.
Yes, I think we should allow out-of-range values.
Note I tested this and it seems the chromium implementation already supports this (requires a very recent version e.g. >=115.0.5767.0): https://jsbin.com/hitegay/edit?html,css,js,output
@flackr SGTM.
Another use-case for explicitly clamping, the following can work for ensuring something animates from entry, even if in some screen/layout it appears in first fold, and in others it's below:
.target {
animation-range-start: max(100vh, entry 0%);
animation-range-end: contain 50%;
}
Regarding negative values, if we'll use absolute values without a range name to refer to the entire scroll range, then negative values become practically useless. Perhaps we should consider again using these to specify offsets from the end of the scroll range?
Another use-case for explicitly clamping, the following can work for ensuring something animates from entry, even if in some screen/layout it appears in first fold, and in others it's below:
.target { animation-range-start: max(100vh, entry 0%); animation-range-end: contain 50%; }
I suspect it would be hard to support range names within the calc. Maybe it could be done - since the entry 0% effectively turns into a proportion of the timeline range which is comparable with 100vh - but I think this could get complex.
Regarding negative values, if we'll use absolute values without a range name to refer to the entire scroll range, then negative values become practically useless. Perhaps we should consider again using these to specify offsets from the end of the scroll range?
I think negative values are still useful when associated with a range name, e.g.
.target {
/* Start 50px before the contain phase */
animation-range-start: contain -50px;
}
While we could do something different when no range name is given, I worry that it would be very magical, and also make it harder to work with calcs. E.g. imagine your calc sometimes produces a negative value - it shouldn't suddenly flip to the end of the range.
D'oh! I messed up the example, took screen end instead of start, should be:
.target {
animation-range-start: max(0%, entry 0%);
animation-range-end: contain 50%;
}
I suspect it would be hard to support range names within the calc. Maybe it could be done - since the entry 0% effectively turns into a proportion of the timeline range which is comparable with 100vh - but I think this could get complex.
I guess this requires transforming range names into functions, and then they could be simply parsed as <length>
, right?
Is there another option?
I think negative values are still useful when associated with a range name, e.g.
.target { /* Start 50px before the contain phase */ animation-range-start: contain -50px; }
Yes of course, it's useful for names in that way, but useless for absolute values.
While we could do something different when no range name is given, I worry that it would be very magical, and also make it harder to work with calcs. E.g. imagine your calc sometimes produces a negative value - it shouldn't suddenly flip to the end of the range.
Yep, that's a real concern. I guess this is something that can be added later if demand arises.
Looking at the original issue, this was about allowing values greater than 100% and less than 0%. Maybe we should split off the min/max functionality to a separate issue?
The CSS Working Group just discussed [scroll-animations-1][css-animations-2] Out-of-range range offsets
, and agreed to the following:
RESOLVED: allow timeline ranges outside of 0-100% range, and use them as-is for existing animation start-time and duration calculations.
Currently
animation-range-start/end
take<length-percentage>
values to indicate a position on the timeline. By allowing<length>
values in #7575, we made it possible to choose positions outside the declared range; and unless we restrict the percentages to [0%,100%], that can be done with percentages also.The question here is, what do we do about such out-of-range values?
animation-range
to expand the attachment range for animations.I think the last one makes the most sense. See also https://github.com/w3c/csswg-drafts/issues/8405#issuecomment-1464810166