CSS3 规范出现之前,要实现一个动画效果那必须借助 JavaScript 的能力才够得着,所以当时的前端开发但凡听到动画交互,那眉头可就成了一个川字儿了~

transition 的出现,改变了实现动画难的困境,也让前端的交互不再生硬,所有的页面元素如同有了灵性一般。

transition 过渡

要实现一个 CSS 属性 0 -> 1 的变化,在不使用 transition 的情况下,元素就两种状态 01,而 transition 则是将 0 -> 1 之间的变化完全呈现给了用户,看起来就像是属性 0 慢慢的走到 1,而不是从 0 闪现到 1,期间元素走过了 0.1 0.2 0.3 ... 1,这种变化就叫过渡。

transition 相关的 CSS 属性:

  • transition-property 指定哪些 CSS 属性需要应用过渡动画
  • transition-duration 定义动画持续时间
  • transition-timing-function 控制动画速度变化曲线
  • transition-delay 设置动画开始前的等待时间,也就是延迟执行
  • transition 简写属性
  • will-change 提前告知浏览器哪些属性会变化(优化性能)

transition-property

transition-property 属性用于告诉浏览器哪个 CSS 属性要用来做过渡效果,可以是单个属性,也可以是多个属性,还可以是关键字 all

语法:

transition-property: none; /* 无属性过渡 */
transition-property: all; /* 所有属性都添加过渡效果,出于性能考虑不建议使用 all */
transition-property: transform; /* 只对 transform 做过渡 */
transition-property: transform, opacity; /* 只对 transform 和 opacity 添加过渡 */

过渡动画必须几个属性同时设置才会有效,所以单个属性无法演示~

transition-duration

transition-duration 属性用于设置过渡动画的持续时间,单位是秒(s)或毫秒(ms),默认是 0s,表示没有过渡动画。

需注意单位换算关系:1s=1000ms

语法:

transition-duration: 0s; /* 无过渡动画 */
transition-duration: 0.5s; /* 所有属性都添加 0.5s 过渡 */
transition-duration: 0.5s, 200ms; /* transition-property 指定的第一个属性持续 0.5s,第二个属性持续 200ms */

transition-timing-function

transition-timing-function 用于设置速度曲线,控制动画速度变化,这里面有个叫做 贝塞尔曲线 的东东,顶级大佬做出来的都是一堆数学公式~~本文不会介绍如何绘制贝塞尔曲线,咱们学会怎么使用即可,如果对贝塞尔曲线绘制感兴趣可查找相关书籍。

相关属性值:

  • ease 默认值,在过渡的中间增加速度,在过渡结束时减慢速度。等于 cubic-bezier(0.25, 0.1, 0.25, 1.0)

  • linear 以均匀的速度过渡。等于 cubic-bezier(0.0, 0.0, 1.0, 1.0)

  • ease-in 开始缓慢,过渡速度逐渐增加,直到完成。等于 cubic-bezier(0.42, 0, 1.0, 1.0)

  • ease-out 开始快速过渡,随着过渡的继续而减慢。等于 cubic-bezier(0, 0, 0.58, 1.0)

  • ease-in-out 开始缓慢过渡,然后加速,然后再次减速。等于 cubic-bezier(0.42, 0, 0.58, 1.0)

  • cubic-bezier(x1, y1, x2, y2) 自定义贝塞尔曲线, x1, y1x2, y2 分别代表曲线控制点坐标,其中 x1 和 x2 值必须在 0 到 1 的范围内。

  • step-start 等于 steps(1, jump-start)

  • step-end 等于steps(1, jump-end)

  • steps(n, <jump-term>) 在过渡过程中显示n个停留点,每个停留点显示的时间长度相等。

    例如:如果 n 是 5,那么就有 5 个步骤。过渡过程是在 0%、20%、40%、60% 和 80% 处暂时停留,还是在 20%、40%、60%、80% 和 100% 处停留,或者是在 0% 到 100% 之间设置5个停留点,亦或是包括0%和100%标记在内的5个停留点(在0%、25%、50%、75%和100%处),这取决于使用以下哪个 <jump-term>

    jump-start

    表示左连续函数,即第一个跳跃发生在过渡开始时;

    jump-end

    表示右连续函数,即最后一个跳跃发生在动画结束时;

    jump-none

    两端都没有跳跃。相反,在0%和100%标记处各自停留,每个停留点占持续时间的1/n;

    jump-both

    在 0% 和 100% 标记处都包含暂停,实际上在过渡时间内增加了一个步骤;

    start

    与 jump-start 相同。

    end

    与 jump-end 相同。

语言很空洞,看后面例子。

语法:

transition-timing-function: ease;
transition-timing-function: linear;
transition-timing-function: cubic-bezier(0.1, 0.7, 1, 0.1);
transition-timing-function: step-start;
transition-timing-function: steps(5, jump-end);

在使用 Chrome 调试工具时候,发现 linear 还有一种函数式的写法,查阅了兼容性,发现这种写法比较吃浏览器版本,都是 2023 年之后的浏览器版本才开始支持。写法如下:

/* 第一位表示运动进度,第二位表示时间百分比 */
transition-timing-function: linear(
0 0%,
0.22 2.1%,
0.86 6.5%,
1.11 8.6%,
1.3 10.7%,
1.35 11.8%,
1.37 12.9%,
1.37 13.7%,
1.36 14.5%,
1.32 16.2%,
1.03 21.8%,
0.94 24%,
0.89 25.9%,
0.88 26.85%,
0.87 27.8%,
0.87 29.25%,
0.88 30.7%,
0.91 32.4%,
0.98 36.4%,
1.01 38.3%,
1.04 40.5%,
1.05 42.7%,
1.05 44.1%,
1.04 45.7%,
1 53.3%,
0.99 55.4%,
0.98 57.5%,
0.99 60.7%,
1 68.1%,
1.01 72.2%,
1 86.7%,
1 100%
)

transition-delay

transition-delay 属性用于设置过渡动画开始前的等待时间,单位是秒(s)或毫秒(ms),默认是 0s,表示不用延迟。语法与 transition-duration 一样。

transition

简写属性,同时设置 transition-propertytransition-durationtransition-timing-functiontransition-delay 四个属性。

语法:

transition: transform 3s; /* transform 属性添加 3s 过渡 */
transition: transform 3s 0.5s; /* transform 属性添加 3s 过渡,延迟 0.5s 开始 */
transition: transform 3s ease-in-out; /* transform 属性添加 3s 过渡,使用 ease-in-out 速度曲线 */
transition: transform 3s ease-in-out 0.5s; /* transform 属性添加 3s 过渡,使用 ease-in-out 速度曲线,延迟 0.5s 开始 */

will-change

will-change 这是一般双刃剑,用得好可以优化性能,用得不好反而会使用大量机器资源导致页面变慢!!

使用准则:此属性应当作为最后的手段使用,不要过早优化,如果您的页面未出现卡顿变慢,那么您不需要使用这个属性!

使用方式:

will-change: transform; /* 提前分配 GPU 资源,优化 transform 变化 */

效果演示

不同曲线效果

不同曲线会影响动画运动速度。

<div class="box">
<div class="child">ease</div>
<div class="child">linear</div>
<div class="child">ease-in</div>
<div class="child">ease-out</div>
<div class="child">ease-in-out</div>
<div class="child">cubic-bezier</div>
</div>
<style>
.box {
border: 2px solid rgba(255, 71, 87,0.3);
margin: 20px 0;
width: calc(235px * 3);
/* height: calc(100px * 3); */
}
.child {
border: 2px solid rgba(255, 71, 87,1);
border-radius: 40px;
width: 100px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
transition-duration: 2s;
transition-property: transform;
}
.child:nth-child(1) {
transition-timing-function: ease;
}
.child:nth-child(2) {
transition-timing-function: linear;
}
.child:nth-child(3) {
transition-timing-function: ease-in;
}
.child:nth-child(4) {
transition-timing-function: ease-out;
}
.child:nth-child(5) {
transition-timing-function: ease-in-out;
}
.child:nth-child(6) {
transition-timing-function: cubic-bezier(0, 1.59, .83, .67);
} .box:hover .child {
/* 鼠标放在box上时,子元素向右移动605px */
transform: translateX(605px);
}
</style>

效果:

steps 逐帧动画效果

steps 可以理解为关键帧动画,每次都跳到一个关键帧。

<div class="box">
<div class="child">step-start</div>
<div class="child">step-end</div>
<div class="child">steps(5, start)</div>
<div class="child">steps(5, jump-start)</div>
<div class="child">steps(5, jump-end)</div>
<div class="child">steps(5, jump-none)</div>
<div class="child">steps(5, jump-both)</div>
<div class="child">steps(5, start)</div>
<div class="child">steps(5, end)</div>
</div> <style>
.box {
border: 2px solid rgba(255, 71, 87,0.3);
margin: 20px 0;
width: calc(235px * 3);
}
.child {
border: 2px solid rgba(255, 71, 87,1);
border-radius: 40px;
width: 170px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
transition-duration: 2s;
transition-property: transform;
}
.child:nth-child(1) {
transition-timing-function: step-start;
}
.child:nth-child(2) {
transition-timing-function: step-end;
}
.child:nth-child(3) {
transition-timing-function: steps(5, start);
}
.child:nth-child(4) {
transition-timing-function: steps(5, jump-start);
}
.child:nth-child(5) {
transition-timing-function: steps(5, jump-end);
}
.child:nth-child(6) {
transition-timing-function: steps(5, jump-none);
}
.child:nth-child(7) {
transition-timing-function: steps(5, jump-both);
}
.child:nth-child(8) {
transition-timing-function: steps(5, start);
}
.child:nth-child(9) {
transition-timing-function: steps(5, end);
} .box:hover .child {
/* 鼠标放在box上时,子元素向右移动535px */
transform: translateX(535px);
}
</style>

效果:

不同持续时间

持续时间越短,运动越快。

<div class="box">
<div class="child">1s</div>
<div class="child">2s</div>
<div class="child">500ms</div>
<div class="child">1500ms</div>
</div>
<style>
.box {
border: 2px solid rgba(255, 71, 87,0.3);
margin: 20px 0;
width: calc(235px * 3);
}
.child {
border: 2px solid rgba(255, 71, 87,1);
border-radius: 40px;
width: 100px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
transition-property: transform;
}
.child:nth-child(1) {
transition-duration: 1s;
}
.child:nth-child(2) {
transition-duration: 2s;
}
.child:nth-child(3) {
transition-duration: 500ms;
}
.child:nth-child(4) {
transition-duration: 1500ms;
} .box:hover .child {
/* 鼠标放在box上时,子元素向右移动605px */
transform: translateX(605px);
}
</style>

效果:

不同延迟时间

延迟时间越长,动画等待时间越久。

<div class="box">
<div class="child">1s</div>
<div class="child">2s</div>
<div class="child">500ms</div>
<div class="child">1500ms</div>
</div>
<style>
.box {
border: 2px solid rgba(255, 71, 87,0.3);
margin: 20px 0;
width: calc(235px * 3);
}
.child {
border: 2px solid rgba(255, 71, 87,1);
border-radius: 40px;
width: 100px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
transition-duration: 2s;
transition-property: transform;
}
.child:nth-child(1) {
transition-delay: 1s;
}
.child:nth-child(2) {
transition-delay: 2s;
}
.child:nth-child(3) {
transition-delay: 500ms;
}
.child:nth-child(4) {
transition-delay: 1500ms;
} .box:hover .child {
/* 鼠标放在box上时,子元素向右移动605px */
transform: translateX(605px);
}
</style>

效果:

贝塞尔曲线

Chrome 开发者工具内置曲线调试工具:

点击 1 可以呼出调试工具,2 可以切换不同类型的曲线,3 可以切换同类型的不同曲线,4 可以拖拽手柄绘制不同曲线。

这里再分享一个在线绘制贝塞尔曲线的链接:https://yisibl.github.io/cubic-bezier/

图解贝塞尔曲线:

图中红色箭头指向的红点表示:在动画执行 37% 时间的时候要运动到目标的 53% 位置。

图中 1(x1, y1) 和 2(x2, y2) 分别表示控制贝塞尔取消的两个坐标点,cubic-bezier(x1, y1, x2, y2)。

贝塞尔曲线越陡峭,表示速度越快。

总结

  1. 在使用 transition 过渡动画时,必须要有触发条件!比如鼠标放上时、鼠标离开时、元素的 class 变化等。
  2. transition 无法做到让元素无休止的运动下去,过渡动画必须有持续时间!
  3. transition-property 应当尽可能少的使用 all(浏览器需要监控元素的所有可过渡属性)。
  4. transition-property 指定的属性必须是可量化的属性,比如 transform、background-color、color 等,不能是 display、float、font-style 这种无法计算的属性。
  5. 避免过渡 margin/width 等布局属性(易引发重排,性能差)

Web前端入门第 43 问:CSS 动画之过渡属性 transition 改变用户体验的更多相关文章

  1. web前端入坑第五篇:秒懂Vuejs、Angular、React原理和前端发展历史

    秒懂Vuejs.Angular.React原理和前端发展历史 2017-04-07 小北哥哥 前端你别闹 今天来说说 "前端发展历史和框架" 「前端程序发展的历史」 「 不学自知, ...

  2. 好程序员web前端分享18个用CSS制作出来的东西

    好程序员web前端分享18个用CSS制作出来的东西,与流行的看法相反,CSS不仅仅是用来提供一个WEB页面的基本风格,以使它看起来更有吸引力.还有很多其他的事情,CSS也可以做的很好.由于它创建动画和 ...

  3. 好程序员web前端分享值得参考的css理论:OOCSS、SMACSS与BEM

    好程序员web前端分享值得参考的css理论:OOCSS.SMACSS与BEM 最近在The Sass Way里看到了Modular CSS typography一文,发现文章在开头部分就提到了OOCS ...

  4. 进击的Python【第十三章】:Web前端基础之HTML与CSS样式

    进击的Python[第十四章]:Web前端基础之HTML与CSS样式 一.web框架的本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客 ...

  5. Android零基础入门第43节:ListView优化和列表首尾使用

    原文:Android零基础入门第43节:ListView优化和列表首尾使用 前面连续几期都在学习ListView的各种使用方法,如果细心的同学可能会发现其运行效率是有待提高的,那么本期就来一起学习有哪 ...

  6. web前端学习(三)css学习笔记部分(8)-- SVN的介绍和应用、CSS动画效果、CSS3布局属性全接触

    15.SVN的介绍和应用 15.1.SVN的介绍和应用课程概要 将代码进行集中管理,有版本号的进行迭代,方便集体工作的build流程 15.2.SVN的介绍 SVN是Subversion的简称,是一个 ...

  7. web前端学习(三)css学习笔记部分(5)-- CSS动画--页面特效、HTML与CSS3简单页面效果实例

    CSS动画--页面特效部分内容目前仅仅观看了解内容,记录简单笔记,之后工作了进行内容的补充 7.  CSS动画--页面特效 7.1  2D.3D转换 7.1.1  通过CSS3转换,我们能够对元素进行 ...

  8. web前端入坑第二篇:web前端到底怎么学?干货资料! 【转】

    http://blog.csdn.net/xllily_11/article/details/52145172 版权声明:本文为博主[小北]原创文章,如要转载请评论回复.个人前端公众号:前端你别闹,J ...

  9. web前端的10个顶级CSS UI开源框架

    随着CSS3和HTML5的流行,我们的WEB页面不仅需要更人性化的设计理念,而且需要更酷的页面特效和用户体验.作为开发者,我们需要了解一些宝贵的CSS UI开源框架资源,它们可以帮助我们更快更好地实现 ...

  10. Web前端开发实战6:CSS实现导航菜单结合二级下拉式菜单的简单变换

    前面几篇博文都在讲导航菜单和二级下拉式菜单,事实上有非常多方法都能够实现的.详细的情况还要视情况而定. 在后面学习到jQuery框架之后,会有更丰富的动画效果.因为在学习Ajax和jQuery的初步阶 ...

随机推荐

  1. MacSecureCRT配置

    一.调整连接服务器超时时间 Options->Global Options->General->Default Session-> 右侧Edit Default Setting ...

  2. 运行jar包时,在命令行中指定依赖的jar包和主类

    在一次实验过程中,使用maven打包java项目为jar包,打出来的myexp.jar包只有7KB(我的实验项目正常打出来的包不小于60MB).这时,运行java -jar myexp.jar报错&q ...

  3. 记录一次修复 JetBrains Rider 控制台输出乱码

    在使用 JetBrains Rider 调试程序时,控制台输出日志出现了乱码. 歪打正着结果困扰许久的问题得到了解决,于是记录下了这个小短文. 具体的修复建议如下:将终端编码设置为 GB2312 具体 ...

  4. Deepseek学习随笔(3)--- 高效提问技巧

    明确需求 在与 DeepSeek 互动时,明确需求是获取高质量回复的关键.以下是一些示例: 错误示例:帮我写点东西 这样模糊的指令无法让 DeepSeek 理解你的具体需求,生成的回复可能无法满足你的 ...

  5. C# 委托Action和Func

    Action和Func是微软已经定义好的的两种委托类型,区别是Action是没有返回值的,而Func是需要返回值的. 1 //Action内置委托的实例化及调用 2 //不带参数 3 Action m ...

  6. Qt ButtonRole参数的作用

    文章目录 QMessgageBox中addButton(QAbstructButton* , ButtonRole),ButtonRole的作用 QMessgageBox中addButton(QAbs ...

  7. coco数据集详解

    什么是COCO数据集? MS COCO的全称是Microsoft Common Objects in Context,起源于微软于2014年出资标注的Microsoft COCO数据集,与ImageN ...

  8. 【VMware VCF】解决 VCF 环境中组件用户密码过期问题。

    由于长时间没有启动 VCF 环境,现在在启动 SDDC Manager 组件后,UI 一直处于如下图所示的"初始化"状态.当时第一直觉就认为肯定是 VCF 环境组件的用户密码过期了 ...

  9. python实现排列组合--itertools

    这是一个python自带的工具集,简单好用功能强大,能够大大提升编写代码效率. 功能不止排列组合,其他的用用加深理解了再整理. 官方文档:https://docs.python.org/zh-cn/3 ...

  10. Delphi 使控件变成圆角的方法

    procedure RoundControl(Control: TWinControl; arc1, arc2: Integer); var R: TRect; Rgn: HRGN; begin wi ...