投稿004期 | CSS中用 opacity、visibility、d

dunne21發表於2021-09-09

說明

用來設定透明度
定義建立佈局時元素生成的顯示框型別
用來設定元素是否可見。
opacity、visibility、display 這三個屬性分別取值 0、hidden、none 都能使元素在頁面上看不見,但是他們在方方面面都還是有區別的。

是否佔據頁面空間

舉個例子



 


最開始的樣子

圖片描述

黃色塊div元素 使用 opacity:0;

圖片描述

黃色塊div元素 使用 visibility:hidden;

圖片描述

黃色塊div元素 使用 display:none;

圖片描述

可以看出,使用 opacity 和 visibility 屬性時,元素還是會佔據頁面空間的,而使用 display 屬性時,元素不佔據頁面空間。

對子元素的影響

如果子元素什麼都不設定的話,都會受父元素的影響,和父元素的顯示效果一樣,我們就來舉例看看,如果子元素設定的值 和 父元素設定的值不同會有什麼效果。
例子 (opacity屬性)



 


圖片描述

例子 (visibility屬性)



 


圖片描述

例子 (display屬性)



 


圖片描述

可以看出,使用 opacity 和 display 屬性時,父元素對子元素的影響很明顯,子元素設定的 opacity 和 display 屬性是不起作用的,顯示的效果和父元素一樣,而使用 visibility 屬性時,子元素如果設定為 visibility:visible; 並沒有受父元素的影響,可以繼續顯示出來。

自身繫結的事件是否能繼續觸發

這裡說的觸發事件,是指使用者人為的觸發的事件,不包括使用 JavaScript 模擬觸發的事件。
例子 (opacity屬性)



 


圖片描述

例子 (visibility屬性)



 


圖片描述

使用 display:none; 就不用舉例子了,因為使用 display 屬性的話,元素不僅看不見,而且也不佔據頁面空間,所有不會觸發事件。

總的來說,使用 visibility 和 display 屬性,自身的事件不會觸發,而使用 opacity 屬性,自身繫結的事件還是會觸發的。

是否影響其他元素觸發事件

例子(opacity屬性)



 


圖片描述

黃色塊div元素設定 opacity:0;,透過定位,遮擋住了 藍色的p元素,當滑鼠移到藍色p元素上時,並沒有觸發藍色p元素的事件。

例子(visibility屬性)



 


圖片描述

黃色塊div元素設定 visibility:hidden;,透過定位,雖然遮擋住了 藍色的p元素,但是當滑鼠移到藍色p元素上時,還是觸發了藍色p元素繫結的事件。

和上邊一樣,display 屬性就不舉例子了,因為他不會佔據頁面空間,也就不會遮擋其他元素,就不會影響其他元素觸發事件了。
所以,visibility 和 display 屬性是不會影響其他元素觸發事件的,而 opacity 屬性 如果遮擋住其他元素,其他的元素就不會觸發事件了。

是否產生迴流(reflow)

迴流

當頁面中的一部分(或全部)因為元素的規模尺寸,佈局,隱藏等改變而需要重新構建。這就稱為迴流(也有人會把迴流叫做是重佈局或者重排)。
每個頁面至少需要一次迴流,就是在頁面第一次載入的時候。

dispaly 屬性會產生迴流,而 opacity 和 visibility 屬性不會產生迴流。

是否產生重繪(repaint)

重繪

當頁面中的一些元素需要更新屬性,而這些屬性只是影響元素的外觀,風格,而不會影響佈局的時候,比如background-color。則稱為重繪。

dispaly 和 visibility 屬性會產生重繪,而 opacity 屬性不一定會產生重繪。

舉個例子





重繪 repaint

我們可以用 Chrome DevTools 的 Rendering 來看看,
先開啟 Rendering

圖片描述

把第一個選項勾選,這個選項會 高亮顯示需要重繪的區域。

圖片描述

看看效果

圖片描述

改改程式碼,增加上個 transition






重繪 repaint

再看看效果

圖片描述

加上 transition 後就沒有 高亮顯示了,這時候 opacity 不會觸發重繪。

實際上透明度改變後,GPU 在繪畫時只是簡單的降低之前已經畫好的紋理的 alpha 值來達到效果,並不需要整體的重繪。不過這個前提是這個被修改的 opacity 本身必須是一個圖層,如果圖層下還有其他節點,GPU 也會將他們透明化。

注意:迴流必將引起重繪,而重繪不一定會引起迴流。

是否支援transition

opacity 是支援 transition的,一般淡入淡出的效果就是這樣實現的。

圖片描述

visibility 也是支援 transition 的。

visibility: 離散步驟,在0到1數字範圍之內,0表示“隱藏”,1表示完全“顯示”

visibility : hidden; 可以看成 visibility : 0;
visibility : visible; 可以看成 visibility : 1;

只要 visibility 的值大於0就是顯示的,所以
visibility:visible 過渡到 visibility:hidden,看上去不是平滑的過渡,而是進行了一個延時。



 


圖片描述

而如果 visibility:hidden 過渡到 visibility:visible ,則是立即顯示,沒有延時。
注意
上面這個例子只能是從 visibility:visible 過渡到 visibility:hidden,不能從 visibility:hidden 過渡到 visibility:visible
當元素是 visibility:hidden; 時,自身的事件不會觸發,所以像上面這個例子中,直接在藍色塊div元素 上加 hover 事件,要去將自身的 visibility:hidden 過渡到 visibility:visible 是不會起作用的。
但是在其他元素上加事件,來將該元素的 visibility:hidden 過渡到 visibility:visible 是可以的,看例子。



 


圖片描述

display 不僅不支援transition,它還會使 transition 失效。舉個例子看看



 


圖片描述

可以看出用了display,支援 transition 的 opacity 屬性也沒起作用。

這是因為display:none; 的元素,是不會渲染在頁面上的,而 transition 要起作用,元素必須是已經渲染在頁面上的元素,我們可以再來看個例子



 


渲染到頁面
	

圖片描述

給 span 元素繫結事件,點選它的時候,才會把黃色塊div元素,渲染到DOM樹上,然後改變黃色塊div元素的 opacity 屬性,opacity 是支援 transition 的,而在這段程式碼中,並沒有起作用。
更詳細的關於 transition 是否成功 的解讀看

要想解決這個問題,我們可以這樣做。
1、把 display 屬性換成 visibility 屬性



 


圖片描述

2、如果必須要用display屬性,我們可以加上定時器來解決這個問題



 


圖片描述

總結

圖片描述

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1600/viewspace-2801777/,如需轉載,請註明出處,否則將追究法律責任。

相關文章