div 太不好用了!

不好意思,我是标题党 :face_with_open_eyes_and_hand_over_mouth: ~

div 当然好用啦,例如:

  • 当你需要额外的样式元素时,可以用 div

  • 当没有其他合适适合划分内容结构时,可以用 div

  • 当需要自定义 landmarks 时,可以用 div

尽管 dive 本身没有任何问题,但很多人(包括我)还是会在无意识地用到它的时候对它进行无情地吐槽。

众所周知,较大的 DOM 可能会给降低性能,过大的文档会很难读取,也很难进行 debug,但 dive 的问题不在于数量,而在于放置的位置。如果把 div 放到错误的地方,就会带来严重的负面效应。

下面举例说明:

detailssummary

如果你把 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

fieldsetlegend 元素那里获得标签。如果 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>

列表

ulol 只能直接包含 liscripttemplate 元素。把所有列表项目封装在 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ć

注册登录 后评论
    // 作者
    声网技术社区 发布于 声网开发者社区
    • 0
    // 本帖子
    // 相关帖子
    Coming soon...
    • 0
    div 太不好用了!声网技术社区 发布于 声网开发者社区