div 太不好用了!
不好意思,我是标题党
~
div
当然好用啦,例如:
-
当你需要额外的样式元素时,可以用
div
。 -
当没有其他合适适合划分内容结构时,可以用
div
。 -
当需要自定义 landmarks 时,可以用
div
。
尽管 dive
本身没有任何问题,但很多人(包括我)还是会在无意识地用到它的时候对它进行无情地吐槽。
众所周知,较大的 DOM 可能会给降低性能,过大的文档会很难读取,也很难进行 debug,但 dive
的问题不在于数量,而在于放置的位置。如果把 div
放到错误的地方,就会带来严重的负面效应。
下面举例说明:
details
和 summary
如果你把 details
元素的内容封装到 div
里边,浏览器或屏幕阅读器有可能无法正确识别 summary
元素,反而展示了备用文本。
错误
<details>
<div>
<summary>Show info</summary>
Hi, I'm the info!
</div>
</details>
正确
<details>
<summary>Show info</summary>
Hi, I'm the info!
</details>
figure
如果你把 figure
元素的内容封装在 div
里,figcaption
可能会被识别成 figure
的标题。看起来没有什么影响,但如果 figure
没有可访问名称,figure
有可能会无法使用辅助技术。
错误
<figure>
<img src="/images/gus.jpg" width="400" alt="Gus Polinski.">
<div>
<figcaption>
The Polka King of the Midwest talking to a desperate mother.
</figcaption>
</div>
</figure>
The Polka King of the Midwest talking to a desperate mother.
(中西部的波尔卡舞之王正在和一个绝望的母亲说话。)
正确
<figure>
<img src="/images/gus.jpg" width="400" alt="Gus Polinski.">
<figcaption>
The Polka King of the Midwest talking to a desperate mother.
</figcaption>
</figure>
The Polka King of the Midwest talking to a desperate mother.
(中西部的波尔卡舞之王正在和一个绝望的母亲说话。)
fieldsets
fieldset
从 legend
元素那里获得标签。如果 legend
封装在 div
里,fieldset
就没有可访问名称,这会导致单选按钮群组无法以群组状态宣布,而且 legend
跟单选按钮之间没有语义关系,视觉外观也因此中断, legend 并不位于 feildset 的边界上,而是位于它的下方。
错误
<fieldset>
<div>
<legend>Shirt sizes</legend>
<div>
<input type="radio" id="l" name="shirt1">
<label for="l">Large</label>
</div>
<div>
<input type="radio" id="m" name="shirt1">
<label for="m">Medium</label>
</div>
</div>
</fieldset>
正确
<fieldset>
<legend>Shirt sizes</legend>
<div>
<input type="radio" id="l2" name="shirt2">
<label for="l2">Large</label>
</div>
<div>
<input type="radio" id="m2" name="shirt2">
<label for="m2">Medium</label>
</div>
</fieldset>
列表
ul
和 ol
只能直接包含 li
、script
和 template
元素。把所有列表项目封装在 div
里可能会改变屏幕阅读器宣布列表项目的方式。
错误
<ul>
<div>
<li>A</li>
<li>B</li>
<li>C</li>
</div>
</ul>
- A
- B
- C
正确
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
</ul>
- A
- B
- C
注:可以在定义列表(dl
)中使用 div
。
正确
<dl>
<div>
<dt>Key:</dt>
<dd>Value</dd>
</div>
<div>
<dt>Key:</dt>
<dd>Value</dd>
</div>
</dl>
密钥:值
密钥:值
段落
如果你把 div
放进 p
里,会破坏段落。例如,可能会导致浏览器浏览器隐式关闭段落,呈现段落外内容,或添加另一个段落。
这在给段落添加样式时尤为明显,例如,添加一个红色边框。
p {
border: 2px solid red;
}
错误
<p>
<div>I'm wrapped in a div.</div>
I'm not wrapped in a div.
</p>
可能会导致:
<p></p>
<div>I'm wrapped in a div.</div>
I'm not wrapped in a div.
<p></p>
正确
<p>
I'm wrapped in a div.<br>
I'm not wrapped in a div.
</p>
我已经在很多网站上看过类似这种的执行错误了。
怎么避免这些问题呢?
在发布网站前,如果对当前使用的组件、页面部署改变,或添加新组件,记得要验证呈现的标记,我建议使用 Deque 的 validation bookmarklet(验证书签),它适用于服务器端和客户端的呈现页面。
如果你使用的是 JavaScript 库或是要求将组件中的所有项封装在在父元素中的框架,在使用 di
之前,建议先查看是否可以使用 fragment 来替代,或是否可以使用更合适的语义元素。
原文作者:Manuel Matuzovic
原文链接:Divs are bad! - Manuel Matuzović