你可能不知道的 transition 技巧与细节

简介: 你可能不知道的 transition 技巧与细节

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


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


举个例子:

<div></div>
div {
    width: 140px;
    height: 64px;
    transition: .8s transform linear;
}
div:hover {
    transform: translate(120px, 0);
}

608782-20210201102236574-970608539.gif


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

 

并非所有属性都支持 transition



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


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


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


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

{
    height: unset;
    transition: height 0.3s linear;
    &.up {
        height: 0;
    }
    &.down {
        height: unset;
    }
}

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

608782-20210201102307022-2059680472.gif


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


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


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

{
    max-height: 0;
    transition: max-height 0.3s linear;
    &.up {
        max-height: 0;
    }
    &.down {
        max-height: 1000px;
    }
}


608782-20210201102323364-793268862.gif


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

 

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


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


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


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

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

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

608782-20210201102357093-1498406753.gif


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

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


<div></div>
div {
    position: relative;
    width: 200px;
    height: 64px;
    box-shadow: inset 0 0 0 3px #ddd;
}
div::before {
    content: "";
    position: absolute;
    width: 0;
    height: 0;
    top: 0; left: 0; width: 0; height: 0;
    box-sizing: border-box;
    transition: width .25s, height .25s, border-bottom-color;
    transition-delay: .25s, 0s, .25s;
}
div:hover::before {
    width: 200px;
    height: 64px;
    border-left: 3px solid #00e2ff;
    border-bottom: 3px solid #00e2ff;
}

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


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



608782-20210201102428978-49789884.gif


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


div::after {
    right: 0;
    bottom: 0;
}
div:hover::after{
    transition: height .25s, width .25s, border-top-color .25s;
    transition-delay: 0.5s, 0.75s, 0.75s;
    width: 200px;
    height: 64px;
    border-top: 3px solid #00e2ff;
    border-right: 3px solid #00e2ff;
}

608782-20210201102446125-1218780827.gif


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

608782-20210201102452949-542451067.gif




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


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

 

动态改变 transition-duration



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


举个例子:

div {
    width: 140px;
    height: 64px;
    border: 2px solid red;
    transition: 3s all linear;
}
div:hover {
    transition-duration: .5s;
    border: 2px solid blue;
}


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

608782-20210201102522034-1677336252.gif



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

 

纯 CSS 实现的签名板


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


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

div.g-box
    -for(var i=0; i<100; i++)
        div.g-row
            -for(var j=0; j<100; j++)
                div.g-item

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


608782-20210201102546657-821280086.png


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

.g-item {
    transition: 999999s;
}
.g-item:hover {
    background: #000;
    transition: 0s;
}

看看效果:


608782-20210201102609235-759245758.gif

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


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


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


伪代码如下:

div.g-wrap
div.g-box
    -for(var i=0; i<100; i++)
        div.g-row
            -for(var j=0; j<100; j++)
                div.g-item
.g-wrap {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    z-index: 10;
    &:active {
        display: none;
    }
}

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


608782-20210201102643683-878901533.gif


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


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


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

608782-20210201102653598-1630790515.gif


CodePen Demo -- Snow Scratch

目录
相关文章
|
8天前
利用 @keyframes 规则定义动画的代码如何写?
在上述代码中,定义了一个名为 `myAnimation` 的动画,它在 0%、50% 和 100% 这三个关键帧上分别设置了不同的样式,从而实现动画效果。你可以根据需要修改关键帧上的样式和时间点。
23 1
|
5月前
|
前端开发 JavaScript API
Nuxt3 实战 (十一):添加路由 Transition 过渡效果和 Loading 动画
这篇文章介绍了Nuxt3框架中页面和布局的过渡效果设置方法,以及首屏加载动画的添加。通过配置nuxt.config.ts文件和添加CSS样式,可以实现页面过渡效果。同时,文章也提到了在页面中设置不同的过渡效果和为布局和页面同时设置过渡效果的方法。最后,文章以一个Github仓库链接和一个线上预览地址作为总结,表示遵循官方文档操作即可完成相关设置。
156 0
Nuxt3 实战 (十一):添加路由 Transition 过渡效果和 Loading 动画
|
4月前
|
监控 数据可视化 图形学
重构U3D动画系统:运用Animator Controller层叠状态机优化游戏表现
【7月更文第11天】随着Unity 3D(简称U3D)游戏开发的不断深入,高效且流畅的动画系统成为了提升玩家体验的关键因素。本文将深入探讨如何通过重构U3D项目的动画系统,利用Animator Controller的层叠状态机(Layered State Machine)特性,显著提高动画的处理效率与游戏的流畅度。我们将通过一个实战示例,展示如何设置和优化状态机,进而实现角色动画的细腻控制与高效切换。
110 0
|
6月前
|
前端开发 JavaScript
前端 css 经典:transition 过渡和 animation 动画
前端 css 经典:transition 过渡和 animation 动画
83 2
|
前端开发
transition和animation的区别
transition和animation的区别
|
JavaScript 前端开发
你到底懂不懂 Transition 组件?
你到底懂不懂 Transition 组件?
132 0
|
前端开发 JavaScript 容器
学习Vue3 第二十二章(transition-group过度列表)
<transition-group> 组件还有一个特殊之处。除了进入和离开,它还可以为定位的改变添加动画。只需了解新增的 v-move 类就可以使用这个新功能,它会应用在元素改变定位的过程中。像之前的类名一样,它的前缀可以通过 name attribute 来自定义,也可以通过 move-class attribute 手动设置
144 0
|
前端开发 JavaScript
学习Vue3 第二十一章(transition动画组件)
自定义 transition 过度效果,你需要对transition组件的name属性自定义。并在css中写入对应的样式
398 0
|
前端开发
【不一样的CSS】这些关于transition和animation的小细节,你知道吗?
关于transition和animation这两个CSS3属性想必大家都知道,这两个属性都是非常常用的属性,本篇文章来介绍一下关于transition和animation这两个的细节。
137 0
【不一样的CSS】这些关于transition和animation的小细节,你知道吗?