乐趣区

关于前端:你可能不知道的-transition-技巧与细节

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

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

举个例子:

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

当然,除了上述根本的用法,其实 CSS transition 还有一些十分有意思的细节和乏味的用法。上面让我一一娓娓道来。

并非所有属性都反对 transition

并非所有属性都反对 transition。和 animation 相似,这里有一个列表,列出了所有反对 transition 的属性 — CSS animated properties

当然,有的时候,还有更例外的。某些反对 transition 的属性在某些特定状态下,也是不反对 transition 的。十分典型的就是 height: autowidth: auto

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

元素的动静高度过渡动画生效,伪代码大略是这样:

{
    height: unset;
    transition: height 0.3s linear;

    &.up {height: 0;}
    &.down {height: unset;}
}

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

起因在于,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;}
}

具体的详情你能够看看 — 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);
}

能够看到不论是过渡触发,还是过渡复位,都会期待 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 之上,看看成果:

利用同样的原理,咱们再把元素的另外一个伪元素也利用上,然而他们的动画世界,整体须要再全副加上 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;
}

这样,咱们能够把两个伪元素的过渡动画合并,失去一个残缺的 border 动画如下:

残缺的 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:

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

纯 CSS 实现的签名板

利用上述的,小技巧,咱们能够实现一个纯 CSS 的签名板。

首先,在高宽都为 500px 的容器中,实现一个 100×100 的 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,实际上,背景和格子都是红色的:

为了实现签名的成果,咱们给每个格子 g-item 加上 hover 事件,hover 时扭转以后格子背景色。同时,最重要的是,** 在失常状态设置一个十分大的 transition-duration,而在 hover 的时候,设置一个十分小的 transition-duration,伪代码如下:

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

看看成果:

这样就实现了,鼠标 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;}
}

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

残缺的代码实现,并且利用 CSS 增加上了 reset 性能,你能够戳这里:CodePen Demo — Pure CSS signature

reset 办法因为会同时扭转所以元素的 background,会有点卡顿,所以在我的根底上,好友小狮子用 animation 改进了一版 reset 不卡顿版本,能够戳这里:Pure CSS signature

利用这个技巧,其实就能够用 CSS 实现追寻鼠标轨迹的性能(尽管很鸡肋 >_<),咱们再能够和其余很多属性混合起来,譬如混合模式和滤镜。

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

CodePen Demo — Snow Scratch

最初

本文到此结束,心愿对你有帮忙 :),想 Get 到最有意思的 CSS 资讯,千万不要错过我的公众号 — iCSS 前端趣闻 ????

更多精彩 CSS 技术文章汇总在我的 Github — iCSS,继续更新,欢送点个 star 订阅珍藏。

如果还有什么疑难或者倡议,能够多多交换,原创文章,文笔无限,满腹经纶,文中若有不正之处,万望告知。

退出移动版