HTML中的"hidden"属性

hidden属性允许我们隐藏HTML页面中的元素。它以一种非常简单的方式工作:它将CSSdisplay属性设置为none

许多人对此表示担忧,因为我们又一次在标签中混合了样式。公平地说,这是在框架兴起之前的一个时期,人们的思维方式发生了变化,关注点分离变得不再是一个容易争论的问题。也有其他人反对该属性,因为它很容易被CSS覆盖。一个避免隐藏元素意外显示的解决方案是将以下代码段添加到样式表中,以确保它覆盖同一元素上使用的其他规则。

1
2
3
[hidden] {
display: none !important;
}

关于使用!important声明存在不同意见,一些作者认为它破坏代码规则。后来,在类中使用!important变得更加被接受。

减少使用!important的现代方法是使用CSS级联规则。CSS级联规则通过使用@layer指令实现,允许我们为样式定义特定的层。这使我们能够控制CSS规则的特异性和排序,而无需使用!important。这种方法促进了更易维护和可扩展的代码库,减少了对!important声明的依赖,并使跨不同组件和元素管理样式变得更容易。我们只需将前面的代码段添加到实用层中,并将该层移动到最后。这样我们就可以确保它们的样式具有优先权,而无需使用!important

让我们举个例子,假设我们需要切换元素的显示。我们可以通过使用JavaScript和内联CSS将其display属性设置为none来实现。这是许多人用来立即隐藏元素的常见方法。要再次显示元素,我们可以将display更改回我们想要的任何值。

1
2
3
4
5
// 隐藏元素
el.style.display = 'none';

// 通过设置display为另一个值来再次显示元素
el.style.display = 'block';

display设置为除none之外的其他值的问题在于,我们可能正在处理根据媒体大小等不同显示值的元素(例如,blockflex等)。在这种情况下,如果显示类型不匹配,将其设置为特定值可能会引入一些问题。

另一种方法是使用元素的style属性上提供的removeProperty方法,该方法可删除特定的内联样式。

1
2
// 通过删除内联声明的属性来再次显示元素
el.style.removeProperty('display');

支持hidden属性的一个论点是它的语义价值。它清楚地表示使用该属性的元素意图隐藏不显示。另一个论点是,我们可以在HTML中隐藏内容而无需使用CSS。因此,我们可以根据需要在元素上添加和删除属性,而无需设置内联样式。

1
2
3
4
5
6
7
8
9
// 隐藏元素
el.hidden = true;
// 我们也可以使用addAttribute
el.setAttribute('hidden', '');

// 显示元素
el.hidden = false;
// 我们也可以使用removeAttribute
el.removeAttribute('hidden');

hidden属性的未来

最初,hidden属性被认为是一个bool属性。如果HTML元素上存在该属性,则该属性无论其值如何都会生效:

1
2
3
<div hidden>此元素将被隐藏</div>
<div hidden="hidden">此元素也被隐藏</div>
<div hidden="false">这个也被隐藏了</div>

规范最近已更改,hidden属性现在是一个枚举属性。这意味着它可以具有特定的命名值。规范中引入的新值是until-found,它触发了一个称为“Until Found”状态的新状态。

如果hidden属性存在但没有值,或者具有除until-found之外的任何值,则其行为将与以前相同。但是,如果值是until-found,则元素将处于“Until Found”状态。在此状态下,元素将隐藏,直到被用户代理找到为止。

隐藏属性的until-found状态

until-found状态是为了解决一个常见问题而创建的。例如,让我们看一下标签页和手风琴。这些用户界面组件包含在某些操作(例如点击按钮)之前无法发现的元素。这使得内容对于屏幕阅读器、搜索引擎和浏览器内置的页面搜索功能都不可用。

与标准的“隐藏”状态不同,后者通过将其display属性设置为none来完全隐藏内容,而“隐藏直到找到”状态使用content-visibility属性来隐藏内容,同时仍然使其可以被搜索引擎、页面搜索功能和链接发现。考虑以下示例(目前仅在ChromeEdge中支持)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Banana</h1>

<h2>Index</h2>
<ul>
<li><a href="#intro">Introduction</a></li>
<li><a href="#description">Description</a></li>
<li><a href="#etymology">Etymology</a></li>
</ul>

<div id="intro" hidden="until-found">
<p>A banana is an elongated, edible fruit – botanically a berry[1][2] – produced by several kinds of large herbaceous flowering plants in the genus Musa.[3] In some countries, bananas used for cooking may be called "plantains", distinguishing them from dessert bananas. The fruit is variable in size, color, and firmness, but is usually elongated and curved, with soft flesh rich in starch covered with a rind, which may be green, yellow, red, purple, or brown when ripe. The fruits grow upward in clusters near the top of the plant. Almost all modern edible seedless (parthenocarp) bananas come from two wild species – Musa acuminata and Musa balbisiana. The scientific names of most cultivated bananas are Musa acuminata, Musa balbisiana, and Musa × paradisiaca for the hybrid Musa acuminata × M. balbisiana, depending on their genomic constitution. The old scientific name for this hybrid, Musa sapientum, is no longer used</p>
</div>

<div id="description" hidden="until-found">
<h2>Description</h2>
<p>The banana plant is the largest herbaceous flowering plant.[10] All the above-ground parts of a banana plant grow from a structure usually called a "corm".[11] Plants are normally tall and fairly sturdy with a treelike appearance, but what appears to be a trunk is actually a "false stem" or pseudostem. Bananas grow in a wide variety of soils, as long as the soil is at least 60 centimetres (2.0 ft) deep, has good drainage and is not compacted.[12] Banana plants are among the fastest growing of all plants, with daily surface growth rates recorded of 1.4 square metres (15 sq ft) to 1.6 square metres (17 sq ft).[13][14]</p>
</div>

<div id="etymology" hidden="until-found">
<h2>Etymology</h2>
<p>The word "banana" is thought to be of West African origin, possibly from the Wolof word banaana, and passed into English via Spanish or Portuguese.[34][35]</p>
</div>

<button type="button">Reset Display</button>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
if (!('onbeforematch' in document.body)) {
const warning = document.createElement('p');
warning.innerText = `This browser does not support the 'until-found' value for the hidden attribute.`;
document.body.prepend(warning)
}

const button = document.querySelector('button');

button.addEventListener('click', () => {
document.querySelectorAll('[id]').forEach((el) => {
el.setAttribute('hidden', 'until-found');
})
})

在此示例中,尝试使用浏览器的搜索功能(页面搜索)并键入单词“banana”。在第一个结果被突出显示后,尝试导航到下一个结果将会显示“Introduction”部分。随后,后续部分将按顺序变得可见。请注意,一旦元素被显示,该属性就会被移除,使元素保持可见。单击“重置显示”按钮将再次隐藏部分,使您可以重新尝试该过程。此外,单击任何链接将自动显示相应的部分。

请注意,此示例不依赖JavaScript,除了用于重置显示的功能之外。相反,这种行为纯粹通过HTML实现。随着相应部分的“找到”,隐藏属性将自动从元素中移除,触发它们的可见性。

浏览器支持

目前,此功能可在ChromeEdge中应用。虽然Firefox已表达了将其纳入的意愿,但目前尚无来自Safari的应用迹象。目前,该功能标记为“实验性”,这意味着其功能在未来可能会发生变化。

总结

对隐藏属性的预期增强将对使用浏览器中的页面搜索功能的用户体验产生积极影响和增强。