副标题和标题的 HTML

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您的旅程每个阶段提供云产品。 立即开始使用 $200 免费额度!

假设您遇到 双标题 情况。 一个小标题在另一个大标题之上。 我想说,这种情况每天出现很多次吧。 您会选择什么 HTML? 我要是不说,取决于具体情况? 但是您是否考虑了所有选项? 这些选项在语义和无障碍方面如何发挥作用?

正如我们有时在这里做的那样,让我们来回顾一下这些选项。

视觉示例

假设这些不是页面上的 <h1>。 并不是说其中一个是,事情就会有很大不同,但这只是为了设置场景。 我发现这种情况在小节或卡片中最为常见。

这里有一个例子,我的朋友前几天在聊天时提到的

这里有一个我前几天也做过的例子

这里是一个经典的卡片

选项 1:老式的 <h3> 然后是 <h2>

较小的标题在顶部,较大的标题在底部,显然 <h3> 总是比 <h2> 小,对吧?

<h3>Subheading</h3>
<h2>Heading</h2>

这可能是非常普遍的思路,也是我 最不喜欢的做法

我更希望看到类名被使用,这样样式就可以隔离到这些类名中。

<h3 class="card-subhead">Subheading</h3>
<h2 class="card-head">Heading</h2>

不要根据纯粹的视觉处理来做出语义上的选择,尤其是那些影响无障碍性的选择。

更大的奇怪之处是根本使用两个标题元素。 对单个内容使用两个标题感觉不太对劲。 这种组合感觉就像:“嘿,这里有一个新的主要部分,然后这里还有一个副标题,因为在这个小节中还有更多副标题,所以这个副标题只是用于第一个小节。” 但是之后就没有其他小节了,也没有其他副标题了。 即使这并不奇怪,副标题在前的顺序也很奇怪。

如果您要使用两个不同的标题元素,在我看来,较小的标题更有可能作为 <h2> 更合理,这让我们想到......

选项 2:小而强大的 <h2><h3>

如果我们有类名,并且副标题在上下文中是更主要的标题,那么我们可以这样做

<h2 class="card-subheading">Subheading</h2>
<h3 class="card-heading">Heading</h3>

仅仅因为 <h2> 在视觉上较小并不意味着它不能在文档大纲中仍然是主要的标题。 如果您查看上面 CodePen 中的示例,标题“Context Switching”感觉比后面的句子更适合作为标题。 我认为在较小的标题上使用 <h2> 很好,并且使结构更加“正常”(我想) <h2> 在前。

但是,对一个部分使用两个标题仍然感觉很奇怪。

选项 3:一个标题,一个 div

也许这两个中只有一个需要是标题? 这对我来说总体上感觉更正确。 我之前肯定这样做过

<div class="card-subheading">Subheading</div>
<h3 class="card-heading">Heading</h3>

感觉还可以,除了副标题可能包含相关内容,如果人们通过屏幕阅读器导航到标题,并从那里开始阅读,他们可能会错过这些内容。 我想您可以交换视觉顺序......

<hgroup> <!-- hgroup is deprecated, just defiantly using it anyway -->

  <h3 class="card-heading">Heading</h3>
  <div class="card-subheading">Subheading</div>

</hgroup>
hgroup {
  display: flex;
  flex-direction: column;
}
hgroup .card-subheading {
  /* Visually, put on top, without affecting source order */
  order: -1;
}

但我认为以这种方式打乱视觉顺序通常是不好的,比如,对有视力的屏幕阅读器用户来说很尴尬。 所以不要告诉任何人我向你展示了这个。

选项 4:将所有内容都放在一个标题中

既然我们无论如何都只显示一个标题的内容,那么似乎只使用一个标题是正确的。

<h2>
  <strong>Subheading</strong>
  Heading
</h2>

在其中使用 <strong> 元素为我们提供了在 CSS 中进行相同类型样式化的钩子。 例如......

h2 strong {
  display: block;
  font-size: 75%;
  opacity: 0.75;
}

这里的技巧是标题需要作为一个整体来运作/阅读。 因此,要么它们自然地一起阅读,要么您可以使用冒号 : 等等。

<h2>
  <strong>New Podcast:</strong>
  Struggling with Basic HTML
</h2>

ARIA 角色

事实证明,有一个专门用于字幕的 ARIA 角色

所以,就像

<h2 class="card-heading">Heading</h2>
<div role="doc-subtitle">Subheading</div>

我通常喜欢基于 ARIA 角色的样式(因为它要求正确使用它们),因此样式可以直接用它完成

[role="doc-subtitle"] { }

Steve 和 Léonie 的测试表明,浏览器通常将其视为“没有级别的标题”。 JAWS 是例外,它将其视为 <h2>。 这似乎没问题...... 也许吧? Steve 甚至认为将副标题放在前面是可以的

不好和丑陋

这里发生的事情是副标题为标题提供了总体上下文 - 有点像标记

<label for="card-heading-1">Subheading</label>
<h2 id="card-heading-1" class="card-heading">Heading</h2>

但我们这里没有处理表单元素,因此不建议这样做。 另一种使它成为单个标题的方法是使用伪元素来放置副标题,例如

<h2 class="card-heading" data-subheading="Subheading">Heading</h2>
.card-head::before {
  content: attr(data-subheading);
  display: block;
  font-size: 75%;
  opacity: 0.75;
}

曾经屏幕阅读器会忽略伪内容,但现在已经改善了,尽管还不完美。 这使得它只有稍微更易于使用,但文本仍然无法选择,也无法在页面上查找,因此我不希望这样做。