CSS魔法堂:Transition就这么好玩

前言

 以前说起前端动画必须使用JS,而CSS3为我们带来transition和@keyframes,让我们可以以更简单(声明式代替命令式)和更高效的方式实现UI状态间的补间动画。本文为近期对Transition的学习总结,欢迎各位拍砖。

属性介绍

 首先先我们简单粗暴了解transition属性吧!

transition: <transition-property> <transition-duration> <transition-timing-function> <transition-delay>;



/\* 设置启用Transition效果的CSS属性

 \* 注意:仅会引发repaint或reflow的属性可启用Transition效果

 \*       [CSS\_animated\_properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS\_animated\_properties)

 \*/

<transition-property>: all | none | <property> [,<property>]\*



/\* 设置过渡动画持续时间,单位为s或ms

 \*/

<transition-duration>: 0s | <time> [, <time>]\*



/\* 设置过渡动画的缓动函数

 \* cubic-bezier的值从0到1

 \* [一个很好用的cubic-bezier配置工具](http://cubic-bezier.com)

 \*/

<transition-timing-function>: linear|ease|ease-in|ease-out|ease-in-out|cubic-bezier(n,n,n,n)



/\* 设置过渡动画的延时,单位为s或ms

 \*/

<transition-delay>: 0s | <time> [, <time>]

 另外我们可以一次性为多个CSS属性启动Transition效果

transition: width 1s ease .6s,

            color .5s linear,

            background 2s ease-in-out;

触发方式

 既然Transition是UI状态间的补间动画,那么有且仅有修改UI状态时才能让动画动起来。那么就有3种方式了:

  1. 伪类.:link,:visited,:hover,:active:focus
  2. 通过JS修改CSS属性值
  3. 通过JS修改className值

TransitionEnd事件详解

TransitionEnd Event

el.addEventListener("transitionend"

  , e => 

    {

      const pseudoElement = e.pseudoElement // 触发动画的伪类

          , propertyName = e.propertyName   // 发生动画的CSS属性

          , elapsedTime = e.elapsedTime     // 动画的持续时间

      // ..................

    })

注意:每个启用TransitionCSS属性的分别对应独立的transitionend事件

/\* 触发3个transitionend事件 \*/

transition: width 1s ease .6s,

            color .5s linear,

            background 2s ease-in-out;

Visibility也能transition?

 在可启用Transition的CSS属性中,我们发现到一个很特别的CSS属性——visibilityvisibility常与display相提并论的属性,它凭什么能启用Transition,而display不行呢?这个我真心不清楚,不过我们还是了解启用transition的visibility先吧!

visibility是离散值,0(hidden)表示隐藏,1(visible)表示完全显示,非0表示显示。那么visibility状态变化就存在两个方向的差异了:

  1. 从**隐藏**到**显示**,由于非0就是显示,那么从值从0到1的过程中,实际上是从隐藏直接切换到显示的状态,因此并没有所谓的变化过程;
  2. 从**显示**到**隐藏**,从1到0的过程中,存在一段时间保持在显示的状态,然后最后一瞬间切换到隐藏,因此效果上是变化延迟,依然没有变化过程。

 上述表明启用transition的visibility并没有补间动画的视觉效果,那么到底有什么作用呢?答案就是不影响/辅助其他CSS属性的补间动画。其中最明显的例子就是辅助opacity属性实现隐藏显示的补间动画。

<style>

.form-input{

    display: inline-flex;

    line-height: 2;

    border: solid 1px rgba(0,0,0,0.3);

}

.form-input:hover{

        border: solid 1px rgba(0,0,0,0.4);

}

.form-addon{

    font-style: normal;

    color: #666;

    background: #ddd;

    padding-left: 10px;

    padding-right: 10px;

    border-right: solid 1px rgba(0,0,0,0.3);

}

.form-addon-after{

    border-left: solid 1px rgba(0,0,0,0.3);

    border-right: none 0;

}

.form-control{

    border:none 0;

    outline-color: transparent;

    padding: 5px;

    caret-color: #888;

    font-size: 16px;

}

.tips-host{

    position: relative;

}

.tips{

    cursor: default;

    z-index: 999;

    position: absolute;

    top: 120%;

    font-size: 12px;

    color: #444;

    background: #ccc;

    padding: .5em;

    box-shadow: 2px 2px 10px #999;

    transition: box-shadow .2s,

                       opacity 1s,

                       visibility .8s;

    visibility: hidden;

    opacity: 0;

}

.tips:hover{

    box-shadow: 2px 2px 5px #999;

}

.tips::before{

    content: "";

    border: solid 10px transparent;

    border-bottom: solid 10px #ccc;

    position:  absolute;

    transform: translate(0, -100%);

}

.form-control:focus + .tips{

    visibility: visible;

    opacity: 1;

}

</style>

<div class="form-input tips-host" >

    <i class="form-addon">Amount</i>

    <input class="form-control">

    <div class="tips">

        Starts with alphabet, then anything you would like.

    </div>

</div>

 当opacity:0时,需要元素隐藏了但实际上它仍然位于原来的位置,而且可以拦截和响应鼠标事件,当出现元素重叠时则会导致底层元素失效。而由于visibility:hidden时,元素不显示且不拦截鼠标事件,所以在补间动画的最后设置visibility:hidden为不俗的解决办法。

display:none让transition失效的补救措施

 虽然修改display有可能会引发reflow,但它依然不能启用Transition,这点真心要问问委员会了。更让人疑惑的是,它不单不支持启用Transition,而且当设置display:none时其余CSS属性的Transition均失效。难到这是让元素脱离渲染树的后果??

<style>

.box{

  display: none;

  background: red;

  height: 20px;

}

</style>

<div class="box"></div>

<button id="btn1">Transition has no effect</button>

<button id="btn2">Transition takes effect</button>

<script>

const box = document.querySelector(".box")

    , btn1 = document.querySelector("#btn1")

    , btn2 = document.querySelector("#btn2")

btn1.addEventListener("click", e => {

  box.style.display = "block"

  box.style.background = "blue"

})

btn2.addEventListener("click", e => {

  box.style.display = "block"

  box.offsetWidth              // 强制执行reflow

  box.style.background = "blue"

})

</script>

上面的代码,当我们点击btn1时背景色的transition失效,而点击btn2则生效,关键区别就是通过box.offsetWidth强制执行reflow,让元素先加入渲染树进行渲染,然后再修改背景色执行repaint。

那么我们可以得到的补救措施就是——强制执行reflow,下面的操作均可强制执行reflow(注意:会影响性能哦!)

offsetWidth, offsetHeight, offsetTop, offsetLeft

scrollWidth, scrollHeight, scrollTop, scrollLeft

clientWidth, clientHeight, clientTop, clientLeft

getComputeStyle(), currentStyle()

总结

尊重原创,转载请注明转自:https://www.cnblogs.com/fsjohnhuang/p/9143035.html ^_^肥仔John

参考

小tip: transition与visibility

https://www.cnblogs.com/surfaces/p/4324044.html

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏逸鹏说道

03.Web大前端时代之:HTML5+CSS3入门系列~H5功能元素

Web大前端时代之:HTML5+CSS3入门系列:http://www.cnblogs.com/dunitian/p/5121725.html 2.功能元素 1...

2768
来自专栏HTML5学堂

JavaScript 获取鼠标及元素在页面上的位置

HTML5学堂:JavaScript获取鼠标的位置,大家会想到clientX/Y等属性,灵活的获取鼠标的位置信息,能够便于我们实现各种复杂的页面交互效果,到底还...

3366
来自专栏一“技”之长

iOS动画开发之三——UIView的转场切换 原

        前两篇博客中,我们分别介绍了UIView动画的两种使用方式,分别为,带block的方式:http://my.oschina.net/u/2340...

511
来自专栏十月梦想

layerX/layerY与offsetX/offsetY区别

        layerX/layerY与offsetX/offsetY获取事件源于鼠标作用的位置信息

1065
来自专栏hbbliyong

基于Three.js的360度全景--photo-sphere-viewer--简介

这个是基于three.js的全景插件  photo-sphere-viewer.js  ————————————————————————————————————...

4849
来自专栏CRPER折腾记

Vue 折腾记 - (6) 写一个不大靠谱的backToTop组件

返回顶部这个功能用jq实现,好容易实现,一个animate配合scrollTo就搞定了

691
来自专栏程序员宝库

手机端页面在项目中遇到的一些问题及解决办法

首先你可能会给页面的 html 和 body 增加了 height: 100%, 然后就可能造成 IOS 上页面滑动的卡顿问题。解决方案是:

1593
来自专栏大数据钻研

前端开发面试题总结之——CSS3

---- 相关知识点 布局、 浮动、 盒子模型、 弹性和模型、 选择器优先级、 居中定位、 兼容性、 hack写法...... 题目&答案 如何理解CSS的盒子...

3284
来自专栏贾鹏辉的技术专栏@CrazyCodeBoy

React Native之React速学教程(上)

React Native之React速学教程(上) 本文出自《React Native学习笔记》系列文章。 React Native是基于React的,在开发R...

2788
来自专栏青玉伏案

iOS开发之多图片无缝滚动组件封装与使用

  经常有园友会问"博主,有没有图片无限滚动的Demo呀?", 正儿八经的图片滚动的Demo我这儿还真没有,今天呢就封装一个可以在项目中直接使用的图片轮播。没看...

1839

扫码关注云+社区