css3的transition是直接寫在選擇器上,還是寫在選擇器的hover上,為什麼?

我測試過發現如果寫在hover上,移出時會沒效果;

而寫在選擇器上移入移出都會有效果

用js控制元素選擇器的權重(addclass一個類)時,也得到一樣的現象。

是不是應該把transition屬性寫在元素低權重的選擇器上才能獲得全部的效果?

為什麼?


1. 權重影響的是 computed style。

任何屬性,包括transition,寫在什麼權重下的選擇器都是可以的,權重影響css屬性的取值。

2. transition 有一個子屬性,叫做 transition-property,它指定了需要加過渡動畫的css屬性。當這個屬性變化時,瀏覽器會加過渡動畫。

那麼很重要的一點是,你在變化這個目標屬性時,前提是瀏覽器已經得知這個屬性需要加動畫。

是不是有點繞?

舉個例子,我們有一個元素 .el,我們希望在hover上去的時候背景顏色有一個過渡,那麼這麼寫是最簡單的:Edit fiddle - JSFiddle

& .el{
width: 100px;
height: 100px;
background: #000;
transition: background 1s;
}
.el:hover{
background: #fff;
}
&
&&

在hover 之前和之後,瀏覽器都知道 .el 背景色需要transition,這段代碼工作得相當好。

但是假如出於某種原因,我們不希望一開始就把 transition 設定好呢?

那麼就得這樣:Edit fiddle - JSFiddle

& .el{
width: 100px;
height: 100px;
background: #000;
}
.transition{
transition: background 1s;
}
.hover{
background: #fff;
}
&
&& && &

// animation frame 計時器
var raf = window.requestAnimationFrame || window.webkitRequestAnimationFrame;
var caf = window.cancelAnimationFrame || window.webkitCancelAnimationFrame;

// 第一個元素,滑鼠移入後先設transition,再強行 restyle,最後改背景色
el_0.addEventListener("mouseenter", function(){
el_0.classList.add("transition");
el_0.clientWidth; // 強行 restyle + reflow + repaint
el_0.classList.add("hover");
});

// 第二個元素,滑鼠移入後先設transition,等1幀,最後改背景色
el_1.addEventListener("mouseenter", function(){
el_1.classList.add("transition");
el_1._af = raf(function(){ // 等1幀
el_1.classList.add("hover");
});
});

[el_0, el_1].forEach(function(el){
// 滑鼠移除後清理計時器,移除 hover class
el.addEventListener("mouseleave", function(){
caf(el._af);
el.classList.remove("hover");
});

// 動畫結束後,假如滑鼠已經不在元素內,移除 transition
el.addEventListener("transitionend", function(){
if(!el.classList.contains("hover")){
el.classList.remove("transition");
}
});
});
&

第二種方法是不是超級啰嗦?

但沒辦法,安全的做法就是這樣,在變化一個屬性值之前,瀏覽器必須得知道這個屬性值是應該加過渡動畫的。


簡單來講,你把transition寫在了hover上。

當你移入滑鼠時,處於hover狀態,瀏覽器知道你改變了background,還知道要根據transition漸變。

當你移出滑鼠時,處於非hover狀態,瀏覽器知道background是原先那個,但是由於已經不是hover狀態了,也就沒有了transition,瀏覽器也不知道要漸變background


推薦閱讀:

把 HTML5 簡稱為 H5 的人,會把 CSS3 說成 C3 嗎?
JS如何獲取CSS3的transform的值,style.tramsform無效呀?
慕課網老師有一個課程講解的做法是什麼原理?
如何通俗易懂地向初學者通解釋 jQuery、CSS3 和 HTML5 的關係?
請教下 autoprefixer 和 cssnext 分別有什麼用處?有什麼區別?

TAG:前端開發 | CSS | CSS3 |