CSS 滚动驱动动画 animation-range

  • animation-range
    • 语法
      • normal
      • length-percentage
      • timeline-range-name
        • [具名时间线范围 named timeline range](#具名时间线范围 named timeline range "#%E5%85%B7%E5%90%8D%E6%97%B6%E9%97%B4%E7%BA%BF%E8%8C%83%E5%9B%B4-named-timeline-range")
        • cover
        • contain
        • [entry 和 entry-crossing](#entry 和 entry-crossing "#entry-%E5%92%8C-entry-crossing")
        • [exit 和 exit-crossing](#exit 和 exit-crossing "#exit-%E5%92%8C-exit-crossing")
    • 兼容性

animation-range

这个属性可同时对 scroll progress timelineview progress timeline 这两种不同时间线驱动的动画起效果!

还记得之前在 view() 中看到的例子吗, view progressive timeline 是以元素开始出现为 0%, 完全离开滚动容器后为 100%. 实际上我们可能需要更多类型的进度, 比如开始出现(0%)和完全出现(100%), 或准备离开(0%)和完全离开(100%). 如下

这个时候就需要 animation-range 大放异彩了, 因为它改变的就是动画范围.

语法

css 复制代码
animation-range = 
  [ <'animation-delay-start'> <'animation-delay-end'>? | <timeline-range-name> ]#  

animation-range 是一个简写属性, 是 animation-range-startanimation-range-end 的简写. 如果同时指定两个值, 那么第一个值会作为 animation-range-start 第二个值会作为 animation-range-end.

不论是 animation-range-start 还是 animation-range-end, 他们的取值都是一样的

  • normal:
  • <length-percentage>
  • <timeline-range-name>
  • <timeline-range-name> 加上 <timeline-range-name>

有了上面的取值, 对于简写属性 animation-range 来说

  • 如果只是 normal 或者 <length-percentage>, 那么这个值就属于 animation-range-start, 而 animation-range-end 默认为 normal
  • 如果仅仅是一个 <timeline-range-name>, 那么动画范围就是这个具名时间线范围从 0%100%
    • 📖 也就是, 如果 <timeline-range-name> 属于 animation-range-start, 那么百分比默认为 0%; 如果属于 animation-range-end 那么百分比默认为 100%.
  • 如果是 <timeline-range-name> 加上 <length-percentage>, 那么动画范围就是这个具名时间线从 <length-percentage> 到结束.

因此下面的语法都是 OK 的.

  • animation-range: normal;
  • animation-range: 50%;
  • animation-range: contain;
  • animation-range: normal 50%;
  • animation-range: 50% normal;
  • animation-range: 50% 75%;
  • animation-range: entry exit;
  • animation-range: cover cover 100px;
  • animation-range: entry 100px exit;

下面就具体看看不同取值代表的含义

normal

默认值

先看 view progress timeline, 先给出代码, 并且后面的示例都将在此基础上修改

html 复制代码
<div class="relative">
  <div class="container">
    Lorem...
    <div class="box positive-inset-length"></div>
  </div>
</div>
css 复制代码
.container {
  height: 200px;
  overflow: auto;
}
.box {
  animation: appear1 linear both;
  animation-timeline: --why-is-this;
  view-timeline: --why-is-this;
  animation-range: normal;
}

这就是默认的表现, 在 .box 元素将要出现时, 动画进度为 0%; 在元素完全离开滚动容器时, 动画进度为 100%.

再看 scroll progress timeline.

html 复制代码
<div class="relative">
  <div class="container container1">
    <div class="top"></div>
    Lorem ...
  </div>
</div>
css 复制代码
.container1 {
  scroll-timeline: --youHaveToBeThis;
}
.container1 .top {
  position: absolute;
  animation: appear1 linear both;
  animation-timeline: --youHaveToBeThis;
}

这也是默认的表现, 容器开始滚动时, 动画进度为 0%; 滚动容器滚动到最大位置时, 动画进度为 100%.

length-percentage

同样先看 view progress timeline

css 复制代码
.box {
  animation-range: 20%;
}

记得之前说过什么吗? 如果只有一个 <length-percentage> 值, 那么这个值被分配给 animation-range-startanimation-range-end 保持默认值 normal 不变. 下图表现得符合预期, 动画在 20% 的位置开始, 在元素完全离开滚动容器时结束.

然后是 scroll progress timeline

css 复制代码
.container1 .top {
  animation-range: 50%;
}

动画效果符合预期, 顶部水平条在滚动 50% 的位置开始出现, 在滚动到结束时完全展开.

timeline-range-name

再继续往下之前, 我必须说的是 MDN 关于这几个关键字的解释和含义不如 CSS 规范 解释得清楚明白. 因此, 下面的关键字我都会采用规范中的定义, 以便更清楚地说明他们之间的不同之处.

💡 还有一点, 下面的属性和 scroll progress timeline 无缘了

📮 本节所有的例子演示都来自 这个网站. 强烈推荐, 因为演示效果非常清晰易懂

具名时间线范围 named timeline range

📖 百分比的是根据具名时间线范围, named timeline range计算的, 如果没有具名时间线范围则根据整个时间线计算.

cover

cover: 表示 view progress timeline 的全部范围

  • 0% 表示元素的 principle boxstart border edge 开始边框边界 和时间线的 view progress visibility rangeend edge 结束边界的相交位置.
  • 我知道大家看到这么多名词又看到哐哐哐好多链接🔗有一点害怕, 不过不要紧, 我慢慢简化到大家最熟悉的情景
  • principle box: 就理解为 border box 就行, 为什么会多一个新的名字呢, 因为像 li 这样的元素, 它不光光有自己的盒子, 还会有前面的 marker box. 但这里我们不考虑这种情况就简化为 border box
  • start border edge: 这个更容易解释, 因为这里用 start 表示的逻辑方向. 如果是从下到上滚动, 表示上边框; 如果是从左到右滚动, 表示右边框
  • view progress visibility range: 这个就是纯纯新概念, 还记得我们之前写过 view-timeline-inset 吗? 这个范围表示的就是滚动区域减去 view-timeline-inset 后剩下的区域
  • 所以, 解释了这么多, 0% 表示元素的上边框和滚动区域下边界相交的位置. 这样说起来, 是不是容易多了呢? 😊
  • 100% 表示元素的 principle boxend border edge 结束边框边界 和时间线的 view progress visibility rangestart edge 开始边界的相交位置.

来看例子,

接下来, 我们要叠 buff 了, 也就是增加百分比和 view-timeline-inset

css 复制代码
#subject {
  animation-timeline: view(block);
  animation-range: cover 50% cover 100%;
  view-timeline-inset: 10%;
}

所以, 再次印证了 animation-range 的百分比是根据谁的百分比, 根据的应该是 timeline-range-name 指定的范围, 也就是 cover 的范围百分比, 也就是整个滚动窗口去掉 view-timeline-inset 后的范围百分比.

contain

contain: contain 的情况稍微复杂, 为啥嘞, 因为存在着元素和滚动窗口谁大谁小的问题

同样下面要叠 buff 了, 也就是增加百分比和 view-timeline-inset

css 复制代码
#subject {
  animation-timeline: view(block);
  animation-range: contain 20% contain 100%;
  view-timeline-inset: 10%;
}

entry 和 entry-crossing

  • entry
    • 0%cover0% 相同.
    • 100%contain0% 相同.
  • entry-crossing
    • 0%cover0% 相同. (这一点规范没有明确说相同, 但是看定义他们确实是相同的)
    • 100% 表示元素的 principle boxend border edge 结束边框边界 和时间线的 view progress visibility rangeend edge 结束边界的相交位置.
    • 有意思的事情来了, 首先 entryentry-crossing 看起来就很像, 而且他们 0% 的位置一模一样, 不一样的地方就是 100%. 因为 contain0% 包含了两种情况.

对于元素高度小于窗口高度的情况, 这两个属性的标签完全相同. 先看 entry

再看 entry-crossing, 和 entry 一模一样

但是当元素高度超过滚动容器时, 就不一样了, 还是先看 entry, 0% 的时候没啥好说的, 100% 的位置是元素开始离开滚动容器(上 border 要离开)

entry-crossing 呢, 0% 的时候和 entry 一样, 而 100% 的位置是元素下边界进入滚动容器

exit 和 exit-crossing

  • exit: 从这个关键字的意思来看, 就表示离开.
    • 0%contain100% 相同.
    • 100%cover100% 相同.
  • exit-crossing

当元素高度小于滚动窗口时, 先看 exit

再看 exit-crossing

当元素高度大于滚动窗口时, exit 表现如下. 0% 表示当元素的下边界进入滚动容器, 而 100% 表示元素完全离开滚动容器, 即元素的下边界离开滚动容器的上边界. 不好意思, 下面这张图可能要大家自己去前面说的网站上看了, 因为掘金限制了文件上传 20MB, 而这张文件超过了.

来看 exit-crossing, 与 exit 不同的是 0% 的部分, exit-crossing0% 是元素的上边界开始离开滚动容器.

兼容性

我必须说, 我第一次刚看也不是很明白每个的意思并且搞不清 entryentry-crossing 的区别, 关键这几个新的 CSS 属性又是新出的, 网上可参考的资料寥寥无几, 就只能去看 CSS 规范的文档. 如果你不是瞬间滑倒最后而是认真看懂每个关键词的意思以及对应的动图演示, 特别是插入了 view-timeline-inset 的值, 相信你一定会有收获

谢谢你看到这里😊

相关推荐
fishmemory7sec2 分钟前
Electron 使⽤ electron-builder 打包应用
前端·javascript·electron
豆豆1 小时前
为什么用PageAdmin CMS建设网站?
服务器·开发语言·前端·php·软件构建
看到请催我学习1 小时前
如何实现两个标签页之间的通信
javascript·css·typescript·node.js·html5
twins35202 小时前
解决Vue应用中遇到路由刷新后出现 404 错误
前端·javascript·vue.js
qiyi.sky2 小时前
JavaWeb——Vue组件库Element(3/6):常见组件:Dialog对话框、Form表单(介绍、使用、实际效果)
前端·javascript·vue.js
煸橙干儿~~2 小时前
分析JS Crash(进程崩溃)
java·前端·javascript
安冬的码畜日常2 小时前
【D3.js in Action 3 精译_027】3.4 让 D3 数据适应屏幕(下)—— D3 分段比例尺的用法
前端·javascript·信息可视化·数据可视化·d3.js·d3比例尺·分段比例尺
l1x1n03 小时前
No.3 笔记 | Web安全基础:Web1.0 - 3.0 发展史
前端·http·html
昨天;明天。今天。3 小时前
案例-任务清单
前端·javascript·css
zqx_74 小时前
随记 前端框架React的初步认识
前端·react.js·前端框架