之前提及前端動畫必須使用JS,而CSS3爲咱們帶來transition和@keyframes,讓咱們能夠以更簡單(聲明式代替命令式)和更高效的方式實現UI狀態間的補間動畫。本文爲近期對Transition的學習總結,歡迎各位拍磚。html
首先先咱們簡單粗暴瞭解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效果ide
transition: width 1s ease .6s, color .5s linear, background 2s ease-in-out;
既然Transition是UI狀態間的補間動畫,那麼有且僅有修改UI狀態時才能讓動畫動起來。那麼就有3種方式了:wordpress
:link
,:visited
,:hover
,:active
和:focus
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;
在可啓用Transition的CSS屬性中,咱們發現到一個很特別的CSS屬性——visibility
。visibility
常與display
相提並論的屬性,它憑什麼能啓用Transition,而display
不行呢?這個我真心不清楚,不過咱們仍是瞭解啓用transition的visibility
先吧!
visibility
是離散值,0(hidden
)表示隱藏,1(visible
)表示徹底顯示,非0表示顯示。那麼visibility
狀態變化就存在兩個方向的差別了:性能
上述代表啓用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
爲不俗的解決辦法。flex
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