CSS 中,transition 属性用于指定为一个或多个 CSS 属性添加过渡效果。

最为常见的用法,也就是给元素添加一个 transition,让其某个属性从状态 A 变化到状态 B 时,不再是非常直接突兀,而是带有一个补间动画。

举个例子:

  1. <div></div>
  1. div {
  2. width: 140px;
  3. height: 64px;
  4. transition: .8s transform linear;
  5. }
  6. div:hover {
  7. transform: translate(120px, 0);
  8. }

当然,除了上述基本的用法,其实 CSS transition 还有一些非常有意思的细节和有趣的用法。下面让我一一娓娓道来。

并非所有属性都支持 transition

并非所有属性都支持 transition。和 animation 类似,这里有一个列表,列出了所有支持 transition 的属性 -- CSS animated properties

当然,有的时候,还有更例外的。某些支持 transition 的属性在某些特定状态下,也是不支持 transition 的。非常典型的就是 height: auto 和 width: auto

在 CSS 奇技淫巧:动态高度过渡动画 一文中,提到了这样一个场景:

元素的动态高度过渡动画失效,伪代码大概是这样:

  1. {
  2. height: unset;
  3. transition: height 0.3s linear;
  4.  
  5. &.up {
  6. height: 0;
  7. }
  8. &.down {
  9. height: unset;
  10. }
  11. }

明明给 height 属性设置了 transition,但是过渡动画没有触发,而是直接一步到位展开:

原因在于, CSS transtion 不支持元素的高度或者宽度为 auto 的变化。

对于这种场景,我们可以使用 max-height 进行 hack。

这里有一个非常有意思的小技巧。既然不支持 height: auto,那我们就另辟蹊径,利用 max-height 的特性来做到动态高度的伸缩,譬如:

  1. {
  2. max-height: 0;
  3. transition: max-height 0.3s linear;
  4.  
  5. &.up {
  6. max-height: 0;
  7. }
  8. &.down {
  9. max-height: 1000px;
  10. }
  11. }

具体的详情你可以看看 -- CSS 奇技淫巧:动态高度过渡动画

transition 可以精细化控制每一个属性

继续。在 transition 中,我们可以使用 transition: all 1s linear 这样,统一给元素下面的所有支持过渡的属性添加过渡效果(时间及缓动函数)。

同时,我们也可以分别精细化控制每一个属性:

  1. {
  2. // 可以这样
  3. transition: all 1s linear;
  4.  
  5. // 也可以这样
  6. transition: height 1s linear, transform 0.5s ease-in, color 2s ease-in-out;
  7. }

并且,和动画类似,每一个过渡都是支持延迟触发的:

  1. div {
  2. // 延迟 1s 触发过渡,过渡动画的时间为 0.8 秒
  3. transition: .8s transform 1s linear;
  4. }
  5. div:hover {
  6. transform: translate(120px, 0);
  7. }

可以看到不管是过渡触发,还是过渡复位,都会等待 1 秒再触发。

利用这个技巧,我们就可以实现一些过渡效果的结合。首先我们实现这样一个宽高变化的过渡动画:

  1. <div></div>
  1. div {
  2. position: relative;
  3. width: 200px;
  4. height: 64px;
  5. box-shadow: inset 0 0 0 3px #ddd;
  6. }
  7. div::before {
  8. content: "";
  9. position: absolute;
  10. width: 0;
  11. height: 0;
  12. top: 0; left: 0; width: 0; height: 0;
  13. box-sizing: border-box;
  14. transition: width .25s, height .25s, border-bottom-color;
  15. transition-delay: .25s, 0s, .25s;
  16. }
  17. div:hover::before {
  18. width: 200px;
  19. height: 64px;
  20. border-left: 3px solid #00e2ff;
  21. border-bottom: 3px solid #00e2ff;
  22. }

我们分别控制元素的伪元素的高度、宽度、及下边框的变化,并且给宽度过渡动画和下边框的颜色动画设置了 0.25 秒的延迟,这样元素的高度会先进行过渡,由于整体的过渡动画世界时间也是 0.25s,所以高度过渡动画结束后,才会开始宽度过渡动画,下边框也才会出现颜色变化。

这样就能把他们的过渡动画衔接在一起,体现到元素的 border 之上,看看效果:

利用同样的原理,我们再把元素的另外一个伪元素也利用上,但是他们的动画世界,整体需要再全部加上 0.5 秒,等到上述的过渡动画执行完毕后才执行:

  1. div::after {
  2. right: 0;
  3. bottom: 0;
  4. }
  5. div:hover::after{
  6. transition: height .25s, width .25s, border-top-color .25s;
  7. transition-delay: 0.5s, 0.75s, 0.75s;
  8. width: 200px;
  9. height: 64px;
  10. border-top: 3px solid #00e2ff;
  11. border-right: 3px solid #00e2ff;
  12. }

这样,我们可以把两个伪元素的过渡动画合并,得到一个完整的 border 动画如下:

完整的 Demo 你可以戳这里:CodePen Demo -- 借助 transition-delay 实现按钮 border 动画效果

所以,合理控制每一个属性,就能组合得到各种有趣的效果。

动态改变 transition-duration

还有一个非常有意思的技巧,我们可以利用元素的一些伪类,动态的去改变元素的 transition-duration

举个例子:

  1. div {
  2. width: 140px;
  3. height: 64px;
  4. border: 2px solid red;
  5. transition: 3s all linear;
  6. }
  7. div:hover {
  8. transition-duration: .5s;
  9. border: 2px solid blue;
  10. }

当鼠标 hover 元素时,将元素的过渡动画的持续时间 transition-duration 从 3s 改成 0.5s,这样可以做到元素 hover 的时候,过渡动画持续的时间是 0.5s,但是过渡复位的持续时间却是 3s:

利用这个小技巧,我们尝试制作一些有意思的效果。

纯 CSS 实现的签名板

利用上述的,小技巧,我们可以实现一个纯 CSS 的签名板。

首先,在高宽都为 500px 的容器中,实现一个 100x100 的 HTML 网格布局,利用 flex、grid 都行,这里为了方便,我借助了 Pug 模板引擎。

  1. div.g-box
  2. -for(var i=0; i<100; i++)
  3. div.g-row
  4. -for(var j=0; j<100; j++)
  5. div.g-item

为了方便示意,我把每个格子加了个 border,实际上,背景和格子都是白色的:

为了实现签名的效果,我们给每个格子 g-item 加上 hover 事件,hover 时改变当前格子背景色。同时,最重要的是,**在正常状态设置一个非常大的 transition-duration,而在 hover 的时候,设置一个非常小的 transition-duration,伪代码如下:

  1. .g-item {
  2. transition: 999999s;
  3. }
  4. .g-item:hover {
  5. background: #000;
  6. transition: 0s;
  7. }

看看效果:

这样就实现了,鼠标 hover 上去的时候,因为 transition: 0s 的缘故,背景色被快速的改变,而当 hover 效果离开, transition: 999999s 重新生效,黑色则会以一个非常非常慢的速度失效,以至于慢到感受不到它在发生变化。

当然,要实现签名的话,目前来看还欠缺点什么,我们需要实现鼠标 hover 到画板上不会立即开始出发元素的背景色变化,只有鼠标按下时(保持 :active 状态),才开始遵循鼠标轨迹改变颜色。当鼠标停止点击,则停止画画。

这个有个巧妙的方法可以实现,我们在画布上,再叠加一层 div,层级 z-index 比画布更高,当鼠标 hover 到画布上,其实是 hover 到这个遮罩层上,当鼠标按下,触发 :active 事件时,给元素添加一个 :activce 事件,将遮罩层移除即可。

伪代码如下:

  1. div.g-wrap
  2. div.g-box
  3. -for(var i=0; i<100; i++)
  4. div.g-row
  5. -for(var j=0; j<100; j++)
  6. div.g-item
  1. .g-wrap {
  2. position: absolute;
  3. top: 0;
  4. left: 0;
  5. bottom: 0;
  6. right: 0;
  7. z-index: 10;
  8.  
  9. &:active {
  10. display: none;
  11. }
  12. }

这样,一个完整的签名板,或者说是画板就实现了:

完整的代码实现,并且利用 CSS 添加上了 reset 功能,你可以戳这里:CodePen Demo -- Pure CSS signature

reset 方法由于会同时改变所以元素的 background,会有点卡顿,所以在我的基础上,好友小狮子用 animation 改良了一版 reset 不卡顿版本,可以戳这里:Pure CSS signature

利用这个技巧,其实就可以用 CSS 实现追随鼠标轨迹的功能(虽然很鸡肋>_<),我们再可以和其他很多属性混合起来,譬如混合模式和滤镜。

像是这样,来自好友 alphardex 的一个效果,利用了上述技巧,叠加了混合模式和滤镜实现:

CodePen Demo -- Snow Scratch

最后

本文到此结束,希望对你有帮助 :)

更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。

如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

你可能不知道的 transition 技巧与细节的更多相关文章

  1. [iOS翻译]《iOS 7 Programming Pushing the Limits》系列:你可能不知道的Objective-C技巧

    简介: 如果你阅读这本书,你可能已经牢牢掌握iOS开发的基础,但这里有一些小特点和实践是许多开发者并不熟悉的,甚至有数年经验的开发者也是.在这一章里,你会学到一些很重要的开发技巧,但这仍远远不够,你还 ...

  2. 漫谈程序员(十一)老鸟程序员知道而新手不知道的小技巧之Web 前端篇

    老鸟程序员知道而新手不知道的小技巧 Web 前端篇 常充电!程序员只有一种死法:土死的. 函数不要超过50行. 不要一次性写太多来不及测的代码,而是要写一段调试一段. UI和编码要同步做. 多写注释方 ...

  3. [No0000194]聊聊 Chrome DevTools 中你可能不知道的调试技巧

    对于前端开发者来说,ChromeDevTools 绝对是不可或缺的调试工具,我们常用的调试方法包含一些console等,而ChromeDevTools 其实很强大,下面来聊聊一些你可能不知道的debu ...

  4. Android Context完全解析,你所不知道的Context的各种细节

    Context相信所有的Android开发人员基本上每天都在接触,因为它太常见了.但是这并不代表Context没有什么东西好讲的,实际上Context有太多小的细节并不被大家所关注,那么今天我们就来学 ...

  5. 你可能不知道的 Mac 技巧 - 文本操作

    找不到 Mac 上的 Home,End,PageUp?想截图还得打开 QQ?不知道 Mac 如何剪切文件?找不到全屏窗口的按钮?找不到隐藏文件夹?不知道如何向后删除?想少用鼠标,多用键盘?…… 希望我 ...

  6. iPhone 上你可能还不知道的小技巧

    用了这么久的 iPhone,这些技巧你可能都还不知道哦. 1.怎么用耳机切歌? 将耳机的话筒部位的中间(平时暂停用的,按一下)连按两下 即可. 连按两下,下一首. 连按三下,上一首. 2.摇一摇,相当 ...

  7. 初学者可能不知道的vue技巧

    前言 大家好,这里是@IT·平头哥联盟,我是首席甩锅官——老金,今天给大家分享的,一些日常中神秘而又简单的vue的实用小技巧,以及我在我司项目中实用vue的总结和坑,跟大家一起分享,希望能给其他攻城狮 ...

  8. 你可能不知道的 Python 技巧

    英文 | Python Tips and Trick, You Haven't Already Seen 原作 | Martin Heinz (https://martinheinz.dev) 译者 ...

  9. 你所不知道的 C# 中的细节

    前言 有一个东西叫做鸭子类型,所谓鸭子类型就是,只要一个东西表现得像鸭子那么就能推出这玩意就是鸭子. C# 里面其实也暗藏了很多类似鸭子类型的东西,但是很多开发者并不知道,因此也就没法好好利用这些东西 ...

随机推荐

  1. 多线程写法,消除同步bug

    public class Demo01 implements Runnable { private int ticket = 10; @Override public void run() { for ...

  2. Kafka 消费组消费者分配策略

    body { margin: 0 auto; font: 13px / 1 Helvetica, Arial, sans-serif; color: rgba(68, 68, 68, 1); padd ...

  3. Netty学习之IO模型

    目录 1.1 同步.异步.阻塞.非阻塞     同步 VS 异步         同步         异步     阻塞 VS 非阻塞         阻塞         非阻塞     举例   ...

  4. WPF时间长度自定义选择控件TimeSpanBox

    以下控件采用https://www.cnblogs.com/cssmystyle/archive/2011/01/17/1937361.html部分代码 以下控件采用https://www.cnblo ...

  5. uber_go_guide解析(三)(规范)

    前言 一主要讲的是容易忽略的错误,可能在build时都不会体现出来但是在使用时出现问题 二主要讲的是一些可以提高代码效率的用法 本篇则讲解一些规范,不是强制的但是根据规范会提高代码的可读性, 减少BU ...

  6. node解决跨域和服务器代理详解代码

    node中有很多解决服务器代理的插件,这里简介一个:express-http-proxy 之前网上查的使用node解决跨域的插件,有很多,例如,cors,koa2,这里解决跨域问题我拿原生解决的,ex ...

  7. 实验一-最小生成树Kruskal算法

    实验名称 最小生成树算法-Kruskal算法 实验目的 1.掌握并查集的合并优化和查询优化: 2.掌握Kruskal算法. 3.能够针对实际问题,能够正确选择贪心策略. 4.能够针对选择的贪心策略,证 ...

  8. Hash Tables and Hash Functions

    Reference: Compuer science Introduction: This computer science video describes the fundamental princ ...

  9. ubuntu 上搭建 go的开发环境 vscode

    原文链接: https://astaxie.gitbooks.io/build-web-application-with-golang/zh/01.4.html 原本我是在windows下进行go的环 ...

  10. 【EXP】WINDOWS下如何导出

    有些时候需要在windows下通过远程来导出数据 那么windows下怎么导出呢 例子: exp hr/hr@192.168.1.222:1521/zhang file=d:backup.dmp lo ...