稀土掘金 稀土掘金

如何理解 CSS step 函数中的 jump-* 关键词?

欢迎关注我的公众号:前端侦探

之前在这篇文章中: CSS 实现 Ant Design官网Logo彩蛋效果实现了一个鼠标 hover 效果,如下

Kapture 2022-01-25 at 10.33.11.gif

原理其实很简单,就是一个 CSS 动画,使用的是steps阶梯函数,不断改变background-position

.logo{
  animation: random 1s steps(10) infinite;
}
@keyframes random {
  to {
    background-position: 100%;
  }
}

里面用到的小图标是这样一张图片(11个小图标)

image-20230611114901264

乍一看,动画好像非常完美,其实还是有一个小小的缺陷,仔细观察,最后一个图标(点赞图标)一直没有出现过,直接被跳过了,文章评论中也有人提到并给出解决方案

image-20230611172403420

但是这种方式不太稳定,background-potion需要考虑实际的帧数,也就是需要根据steps的步数改变。

除了这种方式,其实还有更好的解决方案,今天就一起来探讨这个问题

一、问题重现

为了方便观察和演示,这里用1、2、3来做一张序列帧图片,如下

image-20230611115905877

然后通过 steps阶梯函数实现序列帧动画,关键实现如下

div{
  animation: random 1s steps(2) infinite;
}
@keyframes random {
  to {
    background-position: 100%;
  }
}

效果是这样的(丢失了最后一帧)

Kapture 2023-06-11 at 16.23.09

为啥这里明明有 3 帧,却要设置steps的次数为 2 ?我们不妨设置为 3 试试

animation: random 1s steps(3) infinite;

效果如下

Kapture 2023-06-11 at 16.27.29

情况就更加糟糕了,而且并不是按照123的边界变化的,还出现了中间过渡状态,显然不是我们想要的效果。

要搞清楚这个问题,需要理解steps函数中的第 2 个参数,继续往下看。

二、 steps 中的首尾帧忽略规则

steps其实有两个参数,官方语法如下

steps( <integer> [, <step-position> ]? )  

现在再来看前面的写法

steps(2)

这其实是一个简写,等同于

steps(2, end)

这是什么意思呢,end表示结束,也就是忽略最后一帧,所以上面的例子中,虽然有 3 帧,但忽略最后一帧后就只有 2 帧了,如下

image-20230611164045255

在动画中就是这样,1→2→1→2...

Kapture 2023-06-11 at 16.23.09

所以,steps(2)表示将原图片分成 3 帧,但是只运行前面 2 帧,最后一帧跳过。

那么,上面的steps(3)也很好理解了吧,将原图片平均分成了 4 份,所以就出现了中间过渡状态

image-20230611165732347

除了end以外,还有一个start

steps(2, start)

start表示开始,也就是忽略最前面的一帧

image-20230611164340300

在动画中就是这样,2→3→2→3...

Kapture 2023-06-11 at 16.44.54

所以,steps(2,start)表示将原图片分成 3 帧,但是只运行后面 2 帧,跳过了第一帧。

那么,有没有办法分成多少帧就运行多少帧呢?当然也是有的,就是后来更新的jump-*关键词

三、steps 中jumb-*关键词

Chrome 77+开始,steps支持了几个以jumb-开头的关键词,分别是

  • jump-start,等同于之前的start,表示跳过第一帧
  • jump-end,等同于之前的end,表示跳过最后一帧
  • jump-both,表示跳过第一帧和最后一帧
  • jump-none,表示都不跳过

下面是官方的一个函数图像(每个实心点表示一帧)

image-20230611170252166

其实我还是比较习惯于用跳过来理解,前面两个就不说了,先看jumb-both

steps(1, jump-both)

去除首尾两帧后,就只剩下中间一帧了,示意如下

image-20230611170734032

最后的动画效果也只有中间一帧了,2→2→2→2...

image-20230611170546229

然后是jump-none

steps(3, jump-none)

表示不跳过,有多少帧就运行多少帧

image-20230612101507944

动画效果就是正常的123依次变化,1→2→3→1→2→3...

Kapture 2023-06-11 at 17.11.28

根据这个原理,文章开头的小缺陷就非常好解决了,将steps(10)改为steps(11, jump-none)即可

.logo{
  animation: random 1s steps(11, jump-none) infinite;
}
@keyframes random {
  to {
    background-position: 100%;
  }
}

这样就可以正常的看到最后一个图标了

image-20230611172307214

你也可以访问以下任意链接:

  • CSS ant design logo fix (codepen.io)
  • CSS ant design logo fix (runjs.work)

之前的效果(注意对比观察最后一个点赞图标)

  • Ant Design Logo (codepen.io)

四、最后总结一下

其实这个特性也已经出来好几年了,但是好像很少有人知道,主要原因是这个特性使用场景不太丰富,并且有替代方案,再者,这个特性是旧属性的补充,导致在文档上不易轻易被发现(我也是无意发现的😂)。兼容性方面,Safari还是有些拉胯,需要14+才行,完整兼容性如下:

image-20230611175009504

下面再来回顾一下jump-*的区别

  1. jump-start,等同于之前的start,表示跳过第一帧
  2. jump-end,等同于之前的end,表示跳过最后一帧
  3. jump-both,表示跳过第一帧和最后一帧
  4. jump-none,表示都不跳过,有多少帧就运行多少帧

最后,如果觉得还不错,对你有帮助的话,欢迎点赞、收藏、转发❤❤❤

欢迎关注我的公众号:前端侦探

玻璃钢生产厂家河源玻璃钢座椅雕塑达州室内玻璃钢雕塑摆件定制厂家河北欧式玻璃钢雕塑多少钱芜湖大型户外玻璃钢雕塑玻璃钢门头雕塑定制玻璃钢昆虫雕塑铜川玻璃钢雕塑厂家价格杭州节庆商场美陈四川周年庆典商场美陈批发价杭州商场中秋美陈博爱玻璃钢花盆花器玻璃钢广场雕塑设计特别推荐商场内部灯光美陈永济玻璃钢伟人像雕塑口碑不错玻璃钢雕塑源头好货山西创意玻璃钢雕塑优势工业玻璃钢花盆设计山东商业商场美陈销售公司广东玻璃钢金属雕塑厂家水富市玻璃钢雕塑费用多少张掖抽象人物玻璃钢雕塑多少钱左旗玻璃钢雕塑造型安徽玻璃钢造型雕塑昆山玻璃钢雕塑电话宿迁元旦商场美陈常州人物玻璃钢雕塑定制重庆水果玻璃钢雕塑价位商场冬季主题美陈上海玻璃钢雕塑厂哪家好2018香港商场美陈香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化