别再用 display: contents 了

1,570 阅读6分钟

首发于公众号 大迁世界,欢迎关注。📝 每周7篇实用的前端文章 🛠️ 分享值得关注的开发工具 😜分享个人创业过程中的趣事

文章讨论了在网站上使用"display: contents"属性可能导致的潜在问题。作者强调了这种做法可能破坏网页的语义结构,并可能对可访问性产生不利影响。文章还提到了一些潜在的解决方案,以帮助开发人员避免这些问题。

下面是正文~~

display: contents 介绍

CSS(层叠样式表)中的 display: contents 是一个相对较新的属性值,它对元素的布局和可视化有特殊的影响。当你对一个元素应用 display: contents,这个元素本身就像从DOM(文档对象模型)中消失了一样,而它的所有子元素则会升级到DOM结构中的下一个层级。换句话说,该元素的盒模型将被忽略,它的子元素会取而代之,就像直接插入到父元素中一样。

假设我们有这样一个HTML结构:

<div id="parent">
  <div id="child1">Child 1</div>
  <div id="child2">Child 2</div>
</div>

正常情况下,#parent#child1#child2 的父元素,它们在DOM和布局中有一个明确的层级关系。

现在,如果我们对 #parent 应用 display: contents

#parent {
  display: contents;
}

在这种情况下,#parent 在页面布局中就像是“消失了”一样。它的所有子元素(这里是 #child1#child2)会直接升级到#parent所在的DOM层级。也就是说,在布局和渲染过程中,#child1#child2 将不再被视为 #parent 的子元素,而是像直接插入到 #parent 的父元素中一样。

这样做的结果是,任何应用于 #parent 的布局和样式都不会影响到页面的渲染,但 #child1#child2 会像正常元素一样被渲染。

主要用途:

  1. 语义改进:能够改进HTML结构,使其更符合语义,但不影响布局和样式。
  2. 布局优化:在某些复杂的布局场景中,它可以简化DOM结构,提高渲染性能。

display: contents 和可访问性的长期问题

从字面上看,这个CSS声明改变了其应用到的元素的显示属性。它使元素“消失”,将其子元素提升到DOM中的下一层级。

这种声明在很多方面都可能是有用的。讽刺的是,其中一个用例就是改善你工作的底层语义。然而,这个声明一开始的效果有点过头了。

CSS和可访问性

不是每个人都意识到这一点,但某些CSS会影响辅助技术的工作方式。就像烧毁你的房子确实会成功地除去其中可能存在的蜘蛛一样,使用 display: contents 可能会完全消除某些元素被辅助技术识别的关键属性。

简而言之,这会导致按钮不被声明为按钮,表格不被声明和导航为表格,列表也是如此,等等。

换句话说:当人们说“HTML默认是可访问的”时,display: contents 彻底破坏了这个“默认”。这不好。

可访问性从业者注意到了这个问题,并提出了完全合理的修复要求。特别值得一提的是Adrian Roselli的勤勉、有条理和实事求是的文档和报告工作。

修复已经完成,浏览器也已经更新,我们得到了一个快乐的结局。对吗?并不是那么简单。

回归问题

在软件开发中,回归可能意味着几件事情。这个词通常用于负面语境,表达更新后的行为不小心恢复到以前,不太理想的工作方式。

对于 display: contents,这意味着每个人的自动或近乎自动更新的浏览器抛弃了非常必要的错误修复,而没有任何警告或通知,就回到了破坏语义HTML与辅助技术交流的基础属性。

这种类型的回归不是一个令人讨厌的 bug,而是破坏了 Web 可访问性的基础方面。

Adrian注意到了这一点。如果你继续阅读我给你链接的部分,他继续注意到这一点。总之,我统计了关于 display: contents 的行为以不可访问的方式回归了16次的更新。

看问题的角度

制作浏览器是一件困难的事情。需要考虑很多、很多不同的事情,那还没考虑到软件的复杂性。

可访问性并不是每个人的首要任务。我可以在这里稍微宽容一些,因为我主要是尝试用我拥有的东西工作,而不是我希望能有的东西。我习惯了应对由于这种优先级而产生的所有小问题、陷阱和杂项。

然而,能够使用Web界面绝非小事。display: contents 的问题对使用它的界面的人们的生活质量有非常真实、非常可量化的影响。

我还想让你考虑一下这种打地鼠游戏是如何影响可访问性从业者的。告诉某人他们不能使用一个闪亮的新玩具永远不会受到欢迎。然后告诉他们你可以,但后来又不能了,这会削弱信任和能力的认知。

别用 display: contents

现在,我不认为我们这个行业可以自信地使用 display: contents。过去的行为是未来行为的良好指标,而走向地狱的道路是由好意铺成的。

我现在认为这个声明是不可预测的。常见的“只需用辅助技术测试其支持情况”的回应在这里也不适用——当前浏览器版本中该声明的期望行为并不能保证在该浏览器的未来版本中持续。

这是一件罕见且令人不安的事情——整个现代Web都是建立在这样的假设之上,即这样的事情不会以这种方式停止工作。这不是互操作性问题,而是由于疏忽造成的伤害。

display: contents 的回归给我们提供了一个小小的窗口,让我们看到浏览器制作的某些方面是如何(或不是如何)被优先考虑和测试的。

人们可以发誓说像可访问性和包容性这样的事情是重要的,但当涉及到这个特定的CSS声明时,很明显大多数浏览器制造商是不可信的。

这个声明在实践中的不稳定性代表了一种非常真实、非常严重的风险,即在你无法控制的情况下,可能会在你的网站或Web应用中引入关键的可访问性问题。

交流

首发于公众号 大迁世界,欢迎关注。📝 每周一篇实用的前端文章 🛠️ 分享值得关注的开发工具 ❓ 有疑问?我来回答

本文 GitHub github.com/qq449245884… 已收录,有一线大厂面试完整考点、资料以及我的系列文章。