display: none與visibility: hidden的區別

来源:https://www.cnblogs.com/beckyyyy/archive/2023/09/27/17732843.html
-Advertisement-
Play Games

在前端面試中,一般比較側重JavaScript方面的考察,CSS佈局方面考察的內容會相對少一些,其中display: none與visibility: hidden的區別是較常見的考點,這兩個css配置都可以從視覺上隱藏DOM元素,那這兩者的使用上有什麼區別呢? ...


引言:

在前端面試中,一般比較側重JavaScript方面的考察,CSS佈局方面考察的內容會相對少一些,其中display: none與visibility: hidden的區別是較常見的考點,這兩個css配置都可以從視覺上隱藏DOM元素,那這兩者的使用上有什麼區別呢?

display: none

首先我們來看W3C中對display: none的描述:

'none'

​ The element and its descendants generate no boxes or text sequences.

​ Similarly, if a text node is defined to behave as display: none, it generates no text sequences.

Elements with either of these values do not have inner or outer display types, because they don’t generate any boxes at all.

NOTE: As these values cause affected elements to not generate a box, anonymous box generation rules will ignore the elided elements entirely, as if they did not exist in the box tree.

簡單翻譯一下:

元素及其後代不生成盒子或文本序列。

同樣,如果文本節點被定義為display: none,它就不會生成文本序列。

具有上述任一值(指none和contents,W3C的文檔中這兩者放在同一小節)的元素都沒有內部或外部顯示類型,因為它們根本不會生成任何盒子。

註意:由於這些值會導致受影響的元素不生成盒子,因此匿名盒子生成規則會完全忽略被省略的元素,就好像它們不存在於盒子樹中一樣。

根據上面這段描述可以看出,給元素設置display: none後,該元素及其後代都不會生成盒子和文本序列,也就是在渲染樹上不會有這個元素對應的節點。

visibility: hidden

首先我們看visibility屬性本身的描述:

The visibility property specifies whether the box is rendered. Invisible boxes still affect layout.

意思是:

可見性屬性指定是否渲染盒子。不可見的盒子仍會影響佈局。

接著繼續看visibility: hidden的描述:

hidden

Any boxes generated by the element are invisible. Descendants of the element can, however, be visible if they have visibility: visible.

意思是:

該元素生成的任何盒子都是不可見的。然而,該元素的後代如果設置為visibility: visible,則就是可見的。

根據上面這段描述,可以看出,給元素設置為visibility: hidden後,該元素也會生成盒子,所以仍會影響佈局,只是不可見(沒有被繪製),並且後代元素可以控制自己是否可見;也就是說後代是可能被顯示到頁面上的,因此渲染樹上會有其對應的節點,只是這個元素本身是不可見的,類似透明。

我們可以看到W3C中還有下麵一段描述:

Invisible boxes are not rendered (as if they were fully transparent), cannot be interacted with (and behave as if they had pointer-events: none), are removed from navigation (similar to display: none), and are also not rendered to speech (except when speak is always [CSS-SPEECH-1]). However, as with display: contents, their semantic role as a container is not affected, to ensure that any visible descendants are properly interpreted.

翻譯一下意思是:

隱形盒子不會被呈現(就像完全透明一樣)、無法與之交互(行為類似於設置了pointer-events: none)、被從導航中移除(類似於display: none),也不會呈現為語音(除非speak被設置為always [CSS-SPEECH-1])。不過,與display: contents一樣,它們作為容器的語義作用不會受到影響,以確保任何可見後代都能得到正確的解釋。

我看了一下,大概意思差不多理解,但是其中“被從導航中移除”這個不太理解,原本以為是設置錨點不能跳轉,但是嘗試了一下,發現是可以的,所以又查閱了一下MDN的說法:MDN-visibility

hidden

The element box is invisible (not drawn), but still affects layout as normal. Descendants of the element will be visible if they have visibility set to visible. The element cannot receive focus (such as when navigating through tab indexes).

大致意思就是:

不能被聚焦(比如通過tabindex這個屬性)。

tabindex這個屬性可以使HTML元素獲得焦點,比如:

image

我們可以通過tab鍵使設置了tabindex的元素獲得焦點,也可以直接點擊這個元素使它獲得焦點;那麼也就是說如果元素設置了visibility: hidden,即使設置了tabindex屬性,也無法獲取焦點。

另外後面這段內容,我覺得也可以幫助理解,

Using a visibility value of hidden on an element will remove it from the accessibility tree. This will cause the element and all its descendant elements to no longer be announced by screen reading technology.

它的意思是,設置了hidden的元素將從可訪問樹上被移除,其中的內容無法被無障礙閱讀設備讀取,總體來說,就是將這個被設置了visibility: hidden的元素當做完全不存在,直接跳過,在頁面審查元素的時候,也無法選中這個元素。

兩者對比

從上述的定義中,可以看出,兩者在渲染時,主要有兩個區別:

  • 第一,是對後代元素是否可見的可控性,visibility: hidden無法完全控制後代的可見性
  • 第二,是是否參與佈局計算,從定義中完全可以看出,元素即使設置了visibility: hidden,依舊會生成盒子,會參與佈局的計算

那麼在使用上要怎麼選擇呢?

首先我們可以考慮,是否由元素完全控制其後代的可見性,如果答案是否,那麼display: none就可以排除了。

其次我們還要考慮一件事,就是通常來說,如果某個元素頁面上不需要展示,我們直接可以不寫,但既然我們寫了,那麼這個隱藏元素就可能出現在頁面上,也就是說顯示/隱藏的狀態會發生切換。

這個時候我們就要考慮迴流重排的問題,因為元素在設置display: none時不參與佈局的計算,在狀態切換為顯示時,又會參與佈局,這就會使渲染樹的節點發生改變,導致觸發瀏覽器迴流並重新生成渲染樹;頻繁的切換狀態就會導致頻繁地觸發迴流重排,影響頁面渲染性能,所以在有狀態切換的場景,尤其是頻繁切換,更推薦優先使用visibility: hidden

並且使用visibility: hidden還可以設置一些過渡的顯示效果(transition)。

還要註意一個問題,就是元素設置visibility: hidden後,就無法與之交互,如果遇到一些特殊的業務需求,比如需要與不可見元素髮生交互,或者能夠被無障礙閱讀設備讀取,這個時候就不能這樣用了,這個時候可以考慮使用opacity: 0,將元素的透明度設置為0,這樣除了變成完全透明,其他方面與普通元素沒什麼不同。

display: none這麼多缺點,是不是就要拋棄不用呢? 那倒也不是這麼絕對,比如有種情況,在頁面載入的時候,根據某些值來判斷是否顯示某個元素,並且後續基本很少切換狀態,那簡單使用display: none也是沒有問題的。

可以用以下比喻來幫助理解

opacity: 0是玻璃(固態,有形),雖然看不見,但是摸得著(可以獲得焦點)

width: 0是水(液態),但摸得著(可以獲得焦點),觸碰它可以直接穿透,相當於沒有寬度

visibility: hidden是空氣(氣態,無形),雖然看不見也摸不著(無法獲得焦點),但是是真實存在的氣態物質

以上三種都是存在的物質,固體和液體可以摸得著(獲得焦點),但是氣體摸不著(無法獲得焦點);所以在渲染樹上都會存在。

而display: none可以理解成沒有肉身,只有能量態,比如一個按鈕被設為display: none,它仍舊可以被觸發點擊事件,它這個能量(功能)還存在。

本文來自博客園,作者:beckyye,轉載請註明原文鏈接:https://www.cnblogs.com/beckyyyy/p/17732843.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 質量是產品的生命線,代碼檢查是軟體開發過程中至關重要的一環,它可以幫助我們發現並糾正潛在的錯誤,提高軟體質量,降低維護成本。 在袋鼠雲產品中也存在這個問題,由於離線數據開發人員 SQL 水平不一,導致代碼書寫混亂、SQL 代碼運行問題較多。本文將介紹在離線產品中如何利用 SQL 檢查規則規範化 SQ ...
  • 索引雖然能加速查詢,但是會降低寫操作的性能,以及耗費更多的磁碟空間。所以建立索引之前需要考慮是不是必要的。 ...
  • 什麼是機器學習(ML)? 它有什麼作用 機器學習(ML)是人工智慧(AI)的一個子集,通過演算法發現數據中的通用模式,並根據持續不斷的訓練來優化調整最終結果。ML模型從過去的經驗中學習,並根據已有的經驗進行預測。例如,現在的電商已不再會使用普遍性降價或優惠券等手段吸引客戶,取而代之的是根據每個客戶的歷 ...
  • 數據作為新型生產要素,已快速融入生產、分配、流通、消費和社會服務管理等各環節,深刻改變著生產方式、生活方式和治理方式。越來越多企業也在嘗試充分利用數據要素,開闢全新發展路徑,進一步實現業務價值提升。 在數字化轉型的大背景之下,白鯨開源旗下WhaleStudio與火山引擎ByteHouse依托於雙方完 ...
  • ora2pg使用記錄 前言 這篇文章是我在學習使用ora2pg過程中的學習記錄,以便日後遺忘查閱; 諸君也可跟隨我的步伐瞭解一下ora2pg,或可移步如下官方文檔參考學習:Ora2Pg : Migrates Oracle to PostgreSQL (darold.net) 本文的ora2pg安裝和 ...
  • 一、背景 分享一個在項目運維中遇到的一個主從複製限制的一個坑,項目的架構為主集群+災備集群,每個集群為一主兩從模式。主集群到災備集群的同步為主從複製的方式,根據業務需求災備集群需要忽略系統庫跟某些配置表,所以才會觸發此限制,而這個限制如果我們之前沒有遇到過,那麼排查起來也是相對不易的。 二、限制描述 ...
  • JavaScript 中有很多簡寫技巧,可以縮短代碼長度、減少冗餘,並且提高代碼的可讀性和可維護性。本文將介紹 20 個提升效率的 JS 簡寫技巧,助你告別屎山,輕鬆編寫優雅的代碼! 移除數組假值 可以使用 filter() 結合 Boolean 來簡化移除數組假值操作。假值指的是在條件判斷中被視為 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 生在國旗下,長在春風裡!國慶將至,採黎為大家帶來 定製頭像2.0(國慶頭像),讓我們用代碼的形式為祖國慶生!歡迎大家點贊收藏加關註哦 前言 想看效果或者想定製春節頭像的小伙伴請直奔 效果區域; 想一睹定製頭像2.0小工具的原理及實現思路請 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...