CSS – Transition & Animation
前言
之前的笔记 就有讲过 CSS Transitions 和 CSS Animations.
这里做一个整理, 补上一些细节.
Transitions
Link to W3Schools
5 个属性可以用
transition-property
transition-property: width;
watch propety width, 改变的时候就会有 animation
transition-delay
trasition-delay: 1s
delay 1 秒才触发
transition-duration
transition-duration: 1s
整个 animation 过程用时 1 秒
transition-timing-function
过度的体验, 比如 ease-in, ease-out 那些
transition
shorthand property
transition: width 2s linear 1s;
property, duration, function, delay
Apply Multiple
transition: width 1s, height 1s; transition-property: width, height; transition-duration: 1s, 1s;
property, shorthand 写法都是加逗号
什么时候放 ?
有个 div width 100px
<div class="target">targetdiv>
.target { border: 2px solid red; width: 100px; }
hover 的时候 width change to 300px
.target:hover { width: 300px; transition-property: width; transition-duration: 1s; transition-timing-function: ease-in; }
当 hover 的时候, 修改 width, 同时给予它 transition 逻辑.
把 transition 逻辑放到 hover 是可以的, 但是注意结尾的时候, 到 mouse leave 的时候 width 恢复到 100px 同时 transition 也移除了, 所以退回的动作没有 animation.
从这个例子可以看出来 Transition 的 work flow, 当 element 有 transition 属性时, 修改 CSS 就会有 animation. 如果没有就不会出现 animation.
所以呢, 比较常见的做法是一开始就给元素 transition 属性. 后续就操作其它 CSS 属性就可以了.
如果是要复杂一些的 animation, 比如有 2 step 的, 动态多一点的, 那么建议之间用 JS 的 animation 更直观.
JS Listen to Transition Event
transitionrun, transitionstart, transitioncancel, transitionend
run 是一开始就跑的, 比 start 还早.
cancel 是当 animation 没有结束, 但是属性被又修改了.
参考: HTMLElement: transitionend event
Animations
Link to W3Schools
@keyframes
animation 过程的 style
@keyframes example { from {background-color: red;} to {background-color: yellow;} }
@keyframes example { 0% {background-color:red; left:0px; top:0px;} 25% {background-color:yellow; left:200px; top:0px;} 50% {background-color:blue; left:200px; top:200px;} 75% {background-color:green; left:0px; top:200px;} 100% {background-color:red; left:0px; top:0px;} }
可以写任何 style property, % 就是 duration 到那个 % 时要出什么 style
Percentage 例子说明:
CSS
h1::after { content: ''; width: 0; height: 100%; position: absolute; top: 0; left: 0; background-color: rgba(255, 0, 0, 0.7); animation: overlay 3s ease infinite; }
它是一个 overlay, 开始时 width 0, left 0
left 0, width 70% 长这样
left 10% width 90%, 长这样
所以动画是
@keyframes overlay { 50% { width: 100%; left: 0; } 100% { width: 0%; left: 100%; } }
我一开始认为 50% 的时候不需要 left 0, 因为本来就是 0 丫. 结果是这样的
因为它变成了 0-100% duration 时, left 从 0 到 100%. 所以一开始 left 就往 100% 去了. 而正确的效果应该是 50% 的时候, left 依然要在 0.
animation-name, duration, delay, timing-function
div:hover { animation-name: example; animation-duration: 4s; animation-delay: 2s; animation-timing-function: ease-in-out; }
name 对应 @keyframes 的名字, duration, delay, timing-function 和 transition 一样.
animation-iteration-count
animation 跑完, 就会回到原本的 style. 要跑多几次就用 iteration
animation-iteration-count: 2;
animation-iteration-count: infinite; 无限次
animation-direction
normal, reverse, alternate, alternate-reverse
reverse 是从最后一个 @keyframes style 跑到第一个, 反过来执行.
alternate 是在最少跑 2 次才有用的, 第 1 次正常跑, 第 2 次 reverse 跑, 以此类推
alternate-reverse 是第一次跑 reverse, 第 2 次正常跑
animation-fill-mode
animation 跑完, 就会回到原本的 style.
by default, animation 的 style, 只会在 animation 过程中有效, 之前, 之后都不会有, 但 fill-mode 可以调.
animation-fill-mode: none,
forwards,
backwards,
both
forwards
是跑完 animation 后把最后一个 keyframs's style apply 去 element. (注: apply 了就 lock 着了, 无法用 js 之类的去改它哦)
backwards 是当 delay 期间, 它会提前去拿 first keyframe's style 去 apply.
both 是 2 forwards + backwards
animation
shorthand property
animation: example 5s linear 2s infinite alternate;
animation-name, duration, timing-function, delay, iteration, direction (没有 fill-mode)
JS Listen to Animation
animationstart
animationend
animationcancel
animationiteration
Animation 和 Transition 的区别
transition 和 animation 的使用动机差挺多的.
如果是 style change 不想太突兀, 做点过渡, 这个叫 transition.
如果是, 想让一个东西"动"起来, 这叫 animation.
具体在使用上的区别:
transition 是先定义好过渡效果 duration ease, 然后修改 element 的 style 属性值.
animation 是先用 @keyframes 定义好动画过程中的 style, 然后 apply animation 并附上 duration ease.
transition 是后来加 style, 这个 style 就是 element 普通的 style, transition 结束它也不会消失.
animation 是先定义动画过程中的 style, 然后 apply 动画进去, 动画结束并不会影响 element 的 style (除非 fill-mode)
综上还是差挺远的.