1. 程式人生 > >CSS中用 opacity、visibility、display 屬性將 元素隱藏 的 對比分析

CSS中用 opacity、visibility、display 屬性將 元素隱藏 的 對比分析

說明

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

是否佔據頁面空間

舉個例子

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <style>
    .yellow{
        width
:100px
; height:100px; background:yellow; }
.red{ width:100px; height:100px; background:red; }
</style> </head> <body> <div class="yellow"></div> <div class="red"></div> </body> </html>

最開始的樣子
這裡寫圖片描述

黃色塊div元素 使用 opacity:0;
這裡寫圖片描述

黃色塊div元素 使用 visibility:hidden;
這裡寫圖片描述

黃色塊div元素 使用 display:none;
這裡寫圖片描述

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

對子元素的影響

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

<!doctype html>
<html lang="en"> <head> <meta charset="UTF-8"> <style> .yellow{ width:100px; height:100px; background:yellow; opacity:0; /* 父元素的 opacity屬性取值為0 */ } .blue{ width:50px; height:50px; background:blue; opacity:1; /* 子元素的 opacity屬性取值為1 */ } </style> </head> <body> <div class="yellow"> <div class='blue'></div> </div> </body> </html>

這裡寫圖片描述

例子 (visibility屬性)

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <style>
    .yellow{
        width:100px;
        height:100px;
        background:yellow;
        visibility:hidden;  /* 父元素的 visibility屬性取值為hidden */
    }
    .blue{
        width:50px;
        height:50px;
        background:blue;
        visibility:visible;  /* 子元素的 visibility屬性取值為visible */
    }
  </style>
 </head>
 <body>
    <div class="yellow">
        <div class='blue'></div>
    </div>
 </body>
</html>

這裡寫圖片描述

例子 (display屬性)

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <style>
    .yellow{
        width:100px;
        height:100px;
        background:yellow;
        display:none;  /* 父元素的 display屬性取值為none */
    }
    .blue{
        width:50px;
        height:50px;
        background:blue;
        display:block;  /* 子元素的 display屬性取值為block */
    }
  </style>
 </head>
 <body>
    <div class="yellow">
        <div class='blue'></div>
    </div>
 </body>
</html>

這裡寫圖片描述

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

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

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

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <style>
    .yellow{
        width:100px;
        height:100px;
        background:yellow;
        opacity:0;
    }

  </style>
 </head>
 <body>
    <div class="yellow" onmouseenter="alert(0)"></div>
 </body>
</html>

這裡寫圖片描述

例子 (visibility屬性)

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <style>
    .yellow{
        width:100px;
        height:100px;
        background:yellow;
        visibility:hidden;
    }

  </style>
 </head>
 <body>
    <div class="yellow" onmouseenter="alert(0)"></div>
 </body>
</html>

這裡寫圖片描述

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

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

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

例子(opacity屬性)

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <style>
       .red{
         width:400px;
         height:40px;
         background:red;
         position:relative;
       }

       .yellow{
        position:absolute;     
        top:0;
        left:0;
        width:200px;
        height:300px;
        background:yellow;
        opacity:0;            
       }

       .blue{
         width:200px;
         height:200px;
         background:blue;
       }
       .red:hover .yellow{
         opacity:1;          
       }
  </style>
 </head>
 <body>
      <div  class='red'>
         <div class='yellow'></div>
      </div>

      <p  class='blue' onmouseenter=alert(0)></p>
 </body>
</html>

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

例子(visibility屬性)

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <style>
       .red{
         width:400px;
         height:40px;
         background:red;
         position:relative;
       }

       .yellow{
        position:absolute;     
        top:0;
        left:0;
        width:200px;
        height:300px;
        background:yellow;
        visibility:hidden;          
       }

       .blue{
         width:200px;
         height:200px;
         background:blue;
       }
       .red:hover .yellow{
         visibility:visible;       
       }
  </style>
 </head>
 <body>
      <div  class='red'>
         <div class='yellow'></div>
      </div>

      <p  class='blue' onmouseenter=alert(0)></p>
 </body>
</html>

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

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

是否產生迴流(reflow)

迴流

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

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

是否產生重繪(repaint)

重繪

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

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

舉個例子

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
</head>
<body>
    <div id="target">重繪 repaint</div>

    <script>
        var flag = false;
        setInterval(function () {
            flag = !flag;
            target.style.opacity = flag ? 0 : 1;
        },1000)
    </script>
</body>
</html>

我們可以用 Chrome DevTools 的 Rendering 來看看,
先開啟 Rendering
這裡寫圖片描述
把第一個選項勾選,這個選項會 高亮顯示需要重繪的區域。
這裡寫圖片描述
看看效果
這裡寫圖片描述

改改程式碼,增加上個 transition

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <style>
    div{
        transition:1s;
    }
  </style>
</head>
<body>
    <div id="target">重繪 repaint</div>

    <script>
        var flag = false;
        setInterval(function () {
            flag = !flag;
            target.style.opacity = flag ? 0 : 1;
        },1000)
    </script>
</body>
</html>

再看看效果
這裡寫圖片描述

加上 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,看上去不是平滑的過渡,而是進行了一個延時。

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <style>
  .blue{
    width:200px;
    height:200px;
    background:blue;
    transition:1s;
    visibility:visible;
  }
  .blue:hover{
    visibility:hidden;
  }
  </style>
 </head>
 <body>
    <div class='blue'></div>
 </body>
</html>

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

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <style>
  .red{
    width:200px;
    height:200px;
    background:red;
  }
  .blue{
    width:200px;
    height:200px;
    background:blue;
    transition:1s;
    visibility:hidden;
  }
  .red:hover+.blue{
    visibility:visible;
  }
  </style>
 </head>
 <body>
        <div class='red'></div>
        <div class='blue'></div>
 </body>
</html>

這裡寫圖片描述

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

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <style>
    .blue{
        width:200px;
        height:200px;
        background:blue;
    }
    .yellow{
        width:100px;
        height:100px;
        background:yellow;
        opacity:0;
        display:none;
        transition:1s
    }
    .blue:hover .yellow{
        opacity:1;
        display:block;
    }
  </style>
 </head>
 <body>
    <div class='blue'>
        <div class='yellow'></div>
    </div>
 </body>
</html>

這裡寫圖片描述

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

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

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <style>
    .blue{
        width:200px;
        height:200px;
        background:blue;
    }
    .yellow{
        width:100px;
        height:100px;
        background:yellow;
        opacity:0;
        transition:1s
    }
  </style>
 </head>
 <body>
    <span>渲染到頁面</span>
    <div class='blue'></div>

    <script>    
        var span = document.querySelector('span');
        span.addEventListener('click',function(){
            var yellowDiv = document.createElement('div');
            yellowDiv.classList.add('yellow');

            var blue = document.querySelector('.blue');
            blue.appendChild(yellowDiv);

            yellowDiv.style.opacity = '1';
        })
    </script>
 </body>
</html>

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

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

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <style>
    .blue{
        width:200px;
        height:200px;
        background:blue;
    }
    .yellow{
        width:100px;
        height:100px;
        background:yellow;
        opacity:0;
        visibility:hidden;
        transition:1s
    }
    .blue:hover .yellow{
        opacity:1;
        visibility:visible;
    }

  </style>
 </head>
 <body>
    <div class='blue'>
        <div class='yellow'></div>
    </div>
 </body>
</html>

這裡寫圖片描述

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

<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <style>
    .blue{
        width:200px;
        height:200px;
        background:blue;
    }
    .yellow{
        width:100px;
        height:100px;
        background:yellow;
        display:none;
        opacity:0;
        transition:1s;
    }
  </style>
 </head>
 <body>
    <div class='blue'>
        <div class='yellow'></div>
    </div>
    <script>    
        var blue = document.querySelector('.blue');
        blue.addEventListener('mouseenter',function(){
            var yellowDiv = document.querySelector('.yellow');
            yellowDiv.style.display = 'block';
            setTimeout(function(){
                yellowDiv.style.opacity = '1';
            },0);
        })
    </script>
 </body>
</html>

這裡寫圖片描述

總結

opacity : 0 visibility : hidden display : none
是否佔據頁面空間 佔據 佔據 不佔據
子元素設定該屬性其他值是否可以繼續顯示 不可以 可以 不可以
自身繫結的事件是否能繼續觸發 能觸發 不能觸發 不能觸發
是否影響遮擋住的元素觸發事件 影響 不影響 不影響
屬性值改變是否產生迴流(reflow) 不產生 不產生 產生
屬性值改變是否產生重繪(repaint) 不一定產生 產生 產生
該屬性是否支援transition 支援 支援 不支援

這裡寫圖片描述

相關推薦

CSS中用 opacityvisibilitydisplay 屬性 元素隱藏對比分析

說明 opacity 用來設定透明度 display 定義建立佈局時元素生成的顯示框型別 visibility 用來設定元素是否可見。 opacity、visibility、display 這三個屬性分別取值 0、hidden、none 都能使元素在

HTML的display屬性行內元素塊狀元素行內塊狀元素互相轉換以及三者的區別

light 參考 utf 嵌入 label 支持 列表項 sub idt 1.行內元素 (1)設置寬高無效 (2)對margin僅設置左右方向有效,上下無效;padding設置上下左右都有效,即會撐大空間 (3)不會自動進行換行 <html> <head

FillRectFrameRect與Rectangle矩形繪製函式使用對比分析

  在Windows中,在GDI函式中傳入的引數指定的矩形大小,起始的座標會繪畫,而結束的座標則不會畫到, 也就是至於結束座標的前面一個畫素。所以,從圖上可以看到,我們繪製一個寬80高50的矩形,實際上,我們 繪製的結束xy座標為(79,49),而不是(80,50),而這樣剛好達到了80x50個畫素的大小。

C++函式指標函式物件與C++11 function物件對比分析

函式指標怎麼宣告?能用來做什麼?什麼時候用? 函式指標變數名稱一定要和函式名字一樣嗎?一個函式只能定義一個函式指標嗎? 給函式指標變數初始化,獲取函式的地址時,有幾種方式?可以不加取址&符號嗎?想要傳入另外一個函式,一定要提前定義嗎?

Day49:CSS屬性操作(文本背景邊框列表display邊距)

tro 驗證 介紹 lec ica 基本 next eat 敬畏 一、CSS屬性操作 1、CSS text 文本顏色:color 顏色屬性被用來設置文字的顏色。 顏色是通過CSS最經常的指定: 十六進制值 - 如: #FF0000 一個RGB值 - 如: RGB(255,

CSS】純CSS另類思路代替displayvisibility解決子選單延遲消失

  在設計子選單時候,需要實現當滑鼠移動到選單時候,子選單顯示,否則子選單都處於隱藏狀態。實現這個功能使用js的話很簡單實現,但是我想用純CSS,使用純CSS的話,就會遇到滑鼠移開選單後,子選單就馬上消失了(display:noe或者visibility:hidden),就滑

css顯示display可見性visibility定位position

隱藏一個元素可以通過把display屬性設定為"none",或把visibility屬性設定為"hidden",但是這兩種方法會產生不同的結果。 display:none隱藏某個元素,且隱藏的元素不會佔用任何空間,即該元素不但被隱藏了,而且原本佔用的空間也會從頁面佈局中消失。 visibility:hid

【htmlCSSjavascript-10】jquery-操作元素屬性CSS和文檔處理)

dom javascrip fun 實用 code color () 進行 java 一、獲得內容-text、html、val() 三個簡單實用的用於 DOM 操作的 jQuery 方法: text() - 設置或返回所選元素的文本內容 html() - 設置或返回所選元

Android中visibility屬性VISIBLEINVISIBLEGONE的區別

int ase htm wid 分享 log img enc 1.0 在Android開發中,大部分控件都有visibility這個屬性,其屬性有3個分別為“visible ”、“invisible”、“gone”。主要用來設置控制控件的顯示和隱藏。有些人可能會疑惑Invi

CSS文本字體個別屬性效果對比

對比 兩端對齊 9.png 劃線 分享 http 中劃線 大小 圖片 text-align:justify;文本兩端對齊效果 text-decoration 下劃線、上劃線、中劃線 text-index 首行縮進效果 text-shadow 文本陰影

CSS基礎 和 font字型背景屬性連寫 與 清除浮動方法

1.偽類   1. :link   2. :visited   3. :hover(重要)   4. :active   5. :focus(input標籤獲取游標焦點) 2.偽元素   1.:first-letter   2.:before(重要在內部前面新增)   3.:after(重要 在內部後面新

css屬性單位顏色

一、屬性 1、字型 font-family:‘微軟雅黑’(第一選擇),arial(第二選擇);如果 font-size:14px; font-style: italic;(字型風格) font-weight: bold;(字型粗細) 2、文字 color:white;(文字色) text

jQuery選擇器IDCLASS標籤獲取物件值屬性設定css樣式

jQuery是繼prototype之後又一個優秀的Javascrīpt框架。它是輕量級的js庫(壓縮後只有21k) , 它相容CSS3,還相容各種瀏覽器 (IE 6.0+, FF 1.5+, Safar

jQuery的屬性css文件處理事件選擇器以及jsp要點簡記

本文繼續紀錄學習jQuery,主要學習jQuery的屬性、css、文件處理、事件、選擇器,最後簡要記錄jsp知識要點。 1.JQ屬性: attr(name|pro|key,val|fn):設定或返回被

計算盒子模型的尺寸display屬性塊級和內聯元素浮動overfloat

計算盒子模型的尺寸  盒子實際高度=上下外邊距+上下邊框+上下內邊距+內容高度  盒子實際寬度=左右外邊距+左右邊框+左右內邊距+內容寬度 box-sizing屬性  content-box    盒子的實際寬度和高度僅應用於元素內容,不包括內邊距和邊框  borde

浮動定位display屬性

浮動 float是css樣式中的定位屬性,用於設定標籤的居左浮動和居右浮動,浮動後的元素不屬於HTML文件流, 需要用清除浮動把文件拽迴文檔流中。(float值:  left 向左浮動;right 向右浮動) 網頁中大部分物件預設是佔用文件流,不過有四種情況使得元素離開文件

詳解CSS中clear屬性bothleftright值的含義

clear的值有四個 none:允許兩邊都可以有浮動物件; both:不允許有浮動物件; left:不允許左邊有浮動物件; right:不允許右邊有浮動物件。 老實說,我沒真正理解字面上的意思,因為這幾段話是有歧義的,例如clear:right的解釋是“不允許右邊有浮動物件

CSS中的marginborderpadding區別 CSS padding margin border屬性詳解

圖解CSS padding、margin、border屬性W3C組織建議把所有網頁上的對像都放在一個盒(box)中,設計師可以通過建立定義來控制這個盒的屬性,這些對像包括段落、列表、標題、圖片以及層。盒模型主要定義四個區域:內容(content)、內邊距(padding)、邊

CSS屬性BFCIFC

定位屬性 1.clear 規定哪一側不允許元素浮動 left 在左側不允許浮動元素。 right 在右側不允許浮動元素。 both 在左右兩側均不允許浮動元素。 none 預設值。允許浮動元素出現在兩側 2.clip 剪裁絕對定位的元素 cl

Spring中使用MapSetList數組屬性集合的註入方法配置文件

查看 main list highlight 配置 spring配置 pla lec while (1)下邊的一個Java類包含了所有Map、Set、List、數組、屬性集合等這些容器,主要用於演示spring的註入配置; [java] view plain c