快速了解 CSS @starting-style 規(guī)則
一、快速了解 @starting-style
通常做一個動畫效果,你可能會考慮 transition 和 animation。
相對于animation,transition使用更簡單,但是有一定條件,需要有狀態(tài)的改變,例如手動添加一個class。
div{
transform: scale(0)
}
div.show{
transform: scale(1)
}
示意如下:
但是,如果這個show是一開始就存在的,比如:
<div class="show">
</div>
這樣在頁面打開的時候,肯定也是沒有過渡效果的,因為沒有狀態(tài)的變化。
在以前,我們可以換成用animation的方式,這樣即使是一開始存在的,也能有動畫效果,因為animation是可以自動運行的。
不過到了現(xiàn)在,我們可以用transition的方式來實現(xiàn)了,將上面的例子改寫一下。
div{
transform: scale(1);
transition: 1s;
}
@starting-style {
div{
transform: scale(0);
}
}
這里的@starting-style表示初始樣式,相當于在渲染之前就有了一個初始狀態(tài),這樣也就算有狀態(tài)變化了。
實際效果如下(每次刷新瀏覽器都有放大動畫)。
這樣,即使不手動添加狀態(tài)也能觸發(fā)過渡動效了,這就是@starting-style。
二、元素添加時添加過渡
有時候,即使是手動添加class,也無法保證一定能觸發(fā)過渡動效,比如新創(chuàng)建的元素。
const div = document.createElement('div')
div.className = 'show' //過渡無效,直接就生效了
document.body.append(div)
這種情況下,transition就失效了,因為你在添加class的時候元素還未完全渲染。
要解決這個問題,之前也有幾種方式。
首先是定時器,添加一點點延時。
settimeout(()=>{
div.className = 'show'
},50)
還有一種方式,主動觸發(fā)元素的渲染,強制重繪。
div.clientWidth // 強制觸發(fā)重繪
div.className = 'show'
另外,還可以用動畫animation來代替,這樣也能主動觸發(fā)動畫。
.show{
animation: ...
}
現(xiàn)在,使用@starting-style也能實現(xiàn)這樣的效果。
div.show{
transition: 1s;
}
@starting-style {
div{
transform: scale(0);
}
}
下面是一個元素出現(xiàn)過渡效果:
你也可以訪問以下鏈接查看實際效果(Chrome 117+)
- CSS @style-rule (juejin.cn)[1]
- CSS @style-rule (codepen.io)[2]
這讓我想起了之前做過一個message效果,實現(xiàn)原理是這樣的,如果頁面上還沒有 message元素,就先創(chuàng)建,然后添加show類名,讓這個元素出現(xiàn),這里就是通過強制觸發(fā)重繪實現(xiàn)的。
function showMessage(txt){
this.timer && clearTimeout(this.timer);
var oDiv = document.getElementById('messageInfo');
if(!oDiv){
oDiv = document.createElement('div');
oDiv.className = 'messageInfo';
oDiv.id = 'messageInfo';
document.body.appendChild(oDiv);
}
oDiv.innerHTML = '<span>'+txt+'</span>';
div.clientWidth; // 強制觸發(fā)重繪
oDiv.classList.add('show');
this.timer = setTimeout(function(){
oDiv.classList.remove('show');
},2000)
}
效果如下,第一次創(chuàng)建的時候也有過渡效果:
有興趣的可以回顧之前這篇4年前的文章:css3元素出現(xiàn)動畫實例 。
三、讓 display:none 也支持過渡
大家可能知道,當一個元素從display:none變成display:block時,是無法觸發(fā)過渡效果的,即便有一些過渡屬性。
div{
display: none;
transition: 1s;
transform: scale(0)
}
div.show{
display: block;
transform: scale(1)
}
像這種情況下沒有過渡效果的,如下:
不過,現(xiàn)在有了@starting-style,也能輕易實現(xiàn)過渡效果,不管你有沒有display:none。
/*僅需添加一個初始狀態(tài)*/
@starting-style {
div{
transform: scale(0);
}
}
效果如下:
遺憾的是,從display:block變?yōu)閐isplay:none是無法觸發(fā)過渡效果的。
另外,原生組件很多的隱藏和顯示都是直接通過display:none實現(xiàn)的,例如dialog,可以直接添加@starting-style規(guī)則來實現(xiàn)打開動畫,而無需改變默認 display。
dialog{
transition: 1s;
}
@starting-style {
dialog{
transform: scale(0);
}
}
效果如下:
你也可以訪問以下鏈接查看實際效果(Chrome 117+)
- CSS @style-rule display (juejin.cn)[3]
- CSS @style-rule display (codepen.io)[4]
四、總結一下
一個可以改變元素初始狀態(tài)的新特性,你學到了嗎?
- transition 需要有狀態(tài)的改變才能觸發(fā)過渡效果。
- animation 無需狀態(tài)改變,因為可以自動運行。
- @starting-style 可以改變元素的初始狀態(tài),讓元素在初次渲染時也有過渡效果。
- @starting-style 可以在元素添加時直接添加過渡效果。
- @starting-style 可以讓 display:none 也支持過渡。
不過像這樣的 CSS 特性注定是冷門屬性,主要是可替代性太強了,而且不知道什么時候才可以正式投入使用,現(xiàn)在就當提前了解吧。
[0]css3元素出現(xiàn)動畫實例: https://segmentfault.com/a/1190000018889396。
[1]CSS @style-rule (juejin.cn): https://code.juejin.cn/pen/7299436237318799423。
[2]CSS @style-rule (codepen.io): https://codepen.io/xboxyan/pen/ZEwKYpR。
[3]CSS @style-rule display (juejin.cn): https://code.juejin.cn/pen/7299479246152400896。
[4]CSS @style-rule display (codepen.io): https://code.juejin.cn/pen/7299479246152400896。