早在2011年整理了一篇有关于图片替换文本的方法,而前几天看到一篇有关于隐藏DOM元素的几种方法。今天这里也将继续说说如何隐藏DOM元素?
隐藏DOM元素方法
在《用 CSS 隐藏页面元素的 5 种方法》一文中介绍了五种方法隐藏DOM元素,并且剖析了它们之间的差异。这里也再回顾一下,在CSS中,要隐藏DOM元素常见的方法有:
- 设置元素的
opacity
值为0
- 设置元素的
visibility
值为hidden
- 设置元素的
display
值为none
- 设置元素的
position
值为absolute
,并且将其移到不可见区域 - 设置元素
clip
(在新的CSS中使用clip-path
来替代clip
)
除此之外,还可以使用:
- 设置元素的
hidden
上面隐藏元素的方法都是大家常见的,也是众所周之的。当然除此之外还有一些特殊的小技巧,比如说:
- 将元素的
font-size
、line-height
、width
和height
设置为0
- 设置元素的
transform
的translateX
或者translateY
的值为-100%
当然,或许在你的实战经验当中,你还有别的方案。对于其他的方案,我们不再罗列,咱们具体来看看各种隐藏DOM元素的差异。
隐藏DOM元素的差异性
上面简单的罗列了八种隐藏DOM元素的方式,其实给我们视觉上的效果,这些方法都可以让元素不可见(也就是我们所说的隐藏)。然而,屏幕并不是唯一的输出机制,比如说,屏幕上看不见的元素(隐藏的元素),但其中一些隐藏元素的方式在屏幕阅读器中并没有隐藏,它依然能被屏幕阅读器读出来(因为屏幕阅读器依赖于可访问性树来阐述)。为了消除它们之间的歧意,我们将使用以下条款:
- 完全隐藏:元素既不在屏幕上可见,而且也不暴露在可访问性树上
- 语义上隐藏:元素在屏幕上呈现,但不暴露在可访问性树上
- 视觉上隐藏:元素没有在屏幕上呈现,但是暴露在可访问性树上
三种类型的隐藏总结下来如下表所示:
可见性状态 | 屏幕上 | 可访问性树 |
---|---|---|
完全隐藏 | 隐藏 | 隐藏 |
语义上隐藏 | 可见 | 隐藏 |
视觉上隐藏 | 隐藏 | 可见 |
如何完全隐藏元素
针对上面所列的隐藏元素方式当中,能完全隐藏元素的方法有三种:
- 通过CSS设置元素的
display
属性值为none
- 通过CSS设置元素的
visibility
属性值为hidden
- 通过HTML5元素的属性值
hidden
(就是给元素声明一个hidden
属性值),比如<div hidden>
虽然上面的几种方法得到的结果相同,即内容在屏幕上不可见,屏幕阅读器也无法读到(不在可访问性树上),但它们之间还是有所差别的。
给DOM元素设置display:none;
来隐藏元素,将导致元素完全消失,而且不会占据任何的空间。如果通过visibility:hidden;
隐藏元素,元素虽然消失了,但会占据空间(其占据的空间和元素的大小有直接关系)。
除此之外,通过元素嵌套的方式,外部元素虽然设置了visibility:hidden
并不能隐藏内部元素设置了visibility:visible
的元素,如下所示:
<div style="visibility: hidden">
<span>not visible</span>
<span style="visibility: visible">visible!</span>
</div>
效果如下图所示:
提示:除非非常明确知道嵌套的内容需要做什么,否则应该尽量的避免使用
visibility: visible;
,应该在CSS样式表中使用visibility:inherit;
来替代。在默认情况之下,通过继承元素的visibility
的值,就可以确保避免父元素显式设置了visibility:hidden;
还让嵌套的元素偶然变得可见。
另外HTML5的hidden
属性提供了一个很方便的API,只需要设置hidden = true
可以切换元素是否可见。通过这种方式,元素本身并不会直接隐藏,但浏览器内部会解析成:
[hidden] {
display: none;
}
这样一来,元素间接通过display:none;
隐藏。
虽然无法直接通过设置hidden
来让元素可见,但可以通过CSS样式设置可让元素可见:
div[hidden] {
display: block;
visibility: hidden;
}
通过上面CSS设置,虽然div
元素设置了hidden
属性,元素不可见,但其表现形式类似于visibility:hidden;
,具有一定的空间,除此之外,如果改变visibility
的值为visible
,元素虽然设置了hidden
值,也可以让元素可见:
div[hidden] {
display: block;
visibility: visible;
}
遗憾的是没法直接使用inherit
、initial
或者unset
取消display:none;
。另外initial
和unset
会翻译成display:inline;
,而inherit
只是导入父元素的display
的值。不过从上面的内容来看,我们可以使用扩展选择器来解决这种现象:
div[hidden] {
display: block;
/* ... */
}
div[hidden] {
visibility: hidden;
}
如何语义上隐藏元素
语义上隐藏元素,指的是可访问性树上隐藏,但屏幕上会显示。其实这种隐藏,并未达到元素实际隐藏,因为其在屏幕上仍然是可见的,但其在屏幕阅读器上是不可读的。我们可以在元素上设置aria-hidden="true"
来达到语义上隐藏元素。例如:
<a href="https://google.com">
<img src="search-symbol.png" alt="" aria-hidden="true">
Google Search
</a>
上面这种完全只是达到美化的效果。
提示:我们不应该在CSS的选择器
[aria-hidden="true"]
上添加隐藏元素的样式,比如visibility:hidden
或者display:none
。因为我们的目的很单纯,仅仅只是让屏幕阅读器无法阅读到。
注意:如果需要在屏幕上让元素不可见,仅仅在DOM元素上显示设置[aria-hidden="true"]
是无法隐藏元素。而需要另外配合visibility:hidden
或者display:none
来达到所需要的效果。
有关于WAI-ARIA(Web Accessibility Initiative - Accessible Rich Internet Applications)更详细的介绍,可以阅读早前整理过的《WAI-ARIA 无障碍Web规范》文章,里面详细介绍了如何在HTML中使用ARIA。或者可以通过accessibility.voxmedia.com网站查阅HTML对应元素中ARIA如何使用。
另外在这个微博中将不间断的会更新关于WAI-ARIA相关的资料。
如何视觉上隐藏元素
为了让Web页面更具有可读性,可访问性。隐藏DOM元素更应该采用的是视觉上隐藏元素,而在可访问性树上并不对元素进行隐藏。简单点说,在屏幕上不可见元素,但屏幕阅读器可见。从上述隐藏DOM元素的方式方法主要有:
- 设置元素的
opacity
值为0
- 设置元素的
position
值为absolute
,并且将其移到不可见区域 - 设置元素
clip
(在新的CSS中使用clip-path
来替代clip
) - 将元素的
font-size
、line-height
、width
和height
设置为0
- 设置元素的
transform
的translateX
或者translateY
的值为-100%
虽然上述的方法都能对DOM元素进行隐藏,但其表现形式也是略有不同。
- 通过CSS给元素设置
opacity:0
,让元素不可见,但其可具有一定的空间 - 通过CSS给元素设置
transform
的translateX
或者translateY
的值为-100%
,元素不可见,但其也具有一定的空间
设置元素的position
值为absolute
,并且将其移到不可见区域。这种方法虽然隐藏元素,但元素也会脱离文档流,在Web显示中不占据空间。
为什么会如此,请阅读有关于
position
相关的介绍:《十步图解CSS的position》和《你对Position的了解程度有多少?》。
另外使用CSS的clip
(或者新属性clip-path
)和设置元素的font-size
、line-height
、width
和height
为0
也可以隐藏元素,虽然它们没有将元素移除到不可见区域,但这两种方法将元素的大小变成为了0
。造成不可见现象。
在HTML5 Boilerplate中采用的就是这种方式:
.visuallyhidden {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
border: 0;
padding: 0;
clip: rect(0 0 0 0);
overflow: hidden;
}
要让clip
生效,必须给元素的position
的值设置为absolute
或者fixed
,有关于这方面的详细介绍,可以阅读《Clip》一文。不过在CSS规范中已经开始使用clip-path
属性来替代clip
属性,简单点说,可以使用clip-path:inset(100%)
来替代clip:rect(0 0 0 0)
。
有关于
clip-path
相关的介绍可以阅读《理解Clip Path》和《CSS的clip-path》。
但很多时候想让.visuallyhidden
元素在:focus
或者:active
可见,可以在.visuallyhidden
元素上动态添加.focusable
(比如click
事件给元素添加此类名):
.visuallyhidden.focusable:active,
.visuallyhidden.focusable:focus {
position: static;
width: auto;
height: auto;
margin: 0;
clip: auto;
overflow: visible;
}
当然,针对于优秀的现代浏览器,可以不借助JavaScript事件,直接使用CSS3的:not()
选择器来更新.visuallyhidden
样式:
.visuallyhidden:not(:focus):not(:active) {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
border: 0;
padding: 0;
clip-path: inset(100%);
clip: rect(0 0 0 0);
overflow: hidden;
}
总结
文章详细介绍了如何隐藏DOM元素的方法。也简单的对各种隐藏元素方式做了对比,最后简单的回顾一下:
- 通过HTML5的API,可以在元素上显式声明
hidden
,直接隐藏元素 - 使用
aria-hidden="true
从可访问性树上隐藏元素,但对于用户而言,在屏幕上仍然可见,只是屏幕阅读器无法阅读 - 使用
.visuallyhidden
声明隐藏CSS的样式,在屏幕上隐藏元素 - 使用
visibility:inherit
替代visibility:visible
避免意外地显示内容 - 对于设置了
aria-hidden
的元素,不附加任何隐藏CSS隐藏元素的样式
对比下来,为了让你的Web页面变得更具可访问性,可阅读性,我们更趋向于使用.visuallyhidden
配合clip
(或者clip-path
),当然也可以是其它只在屏幕上隐藏而在可访问性树上不隐藏的CSS样式。只不更常见的是clip
方式而以。
如需转载,烦请注明出处:http://www.w3cplus.com/css/hidden-dom-element.html