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種方式了:
- 偽類.
:link
,:visited
,:hover
,:active
和:focus
- 通過JS修改CSS屬性值
- 通過JS修改className值
TransitionEnd事件詳解
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屬性——visibility
。visibility
常與display
相提並論的屬性,它憑什麼能啟用Transition,而display
不行呢?這個我真心不清楚,不過我們還是瞭解啟用transition的visibility
先吧!
visibility
是離散值,0(hidden
)表示隱藏,1(visible
)表示完全顯示,非0表示顯示。那麼visibility
狀態變化就存在兩個方向的差異了:
- 從隱藏到顯示,由於非0就是顯示,那麼從值從0到1的過程中,實際上是從隱藏直接切換到顯示的狀態,因此並沒有所謂的變化過程;
- 從顯示到隱藏,從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
相關文章
- CSS魔法堂:改變單選框顏色就這麼吹毛求疵!CSS
- CSS transitionCSS
- CSS3 TransitionCSSS3
- CSS transition-timing-functionCSSFunction
- css transition 實現滑入滑出CSS
- CSS3 transition-delayCSSS3
- CSS3 transition-durationCSSS3
- CSS3 transition-propertyCSSS3
- Css3中的TransitionCSSS3
- CSS3 transition 屬性CSSS3
- 15年前的《魔獸世界》能有什麼好玩的——真香
- css3 動畫(一) transitionCSSS3動畫
- CSS動畫:animation、transition、transform、translateCSS動畫ORM
- CSS3 之 transform & transition & animationCSSS3ORM
- CSS3 transition-timing-functionCSSS3Function
- CSS魔法堂:display:none與visibility:hidden的恩怨情仇CSSNone
- 強大的CSS動畫:Transition與AnimationCSS動畫
- css3中transition屬性詳解CSSS3
- html css js(這一篇就夠了)HTMLCSSJS
- 我的遊戲這麼好玩,為什麼賣不動?遊戲
- 關於CSS Transition,你需要知道的事CSS
- Elasticsearch就這麼簡單Elasticsearch
- css 的 filter屬性竟然如此好玩CSSFilter
- 前端深入之css篇丨2020年,徹底掌握css動畫【transition】前端CSS動畫
- 為什麼有些遊戲上了NS之後,就變得更“好玩”了?遊戲
- 堆排序就這麼簡單排序
- 泛型就這麼簡單泛型
- 快速排序就這麼簡單排序
- 拓撲排序就這麼回事排序
- 跨域就這麼點事兒跨域
- 乾貨 | PHP就該這麼學!PHP
- SpringMVC入門就這麼簡單SpringMVC
- 基數排序就這麼簡單排序
- 歸併排序就這麼簡單排序
- 插入排序就這麼簡單排序
- 選擇排序就這麼簡單排序
- SpringDataJPA入門就這麼簡單Spring
- 氣泡排序就這麼簡單排序