关于前端:display-none与visibility-hidden的区别

40次阅读

共计 3464 个字符,预计需要花费 9 分钟才能阅读完成。

引言:

在前端面试中,个别比拟偏重 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 元素取得焦点,比方:

咱们能够通过 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 也是没有问题的。

正文完
 0