别再用那么多 div 了!语义化 HTML 入门 div 的玩法 HTML5:如此标准 主结构 内容指示器 结论

2025-05-27

别再用那么多 div 了!语义化 HTML 入门

Div 已播放完毕

HTML5:这样的标准

主要结构

内容指标

结论

Div 已播放完毕

我们都喜欢<div>标签。它们已经存在了几十年,几十年来,当你需要将一些东西包裹在一个块中以用于样式或结构目的时,它们一直是你的首选元素。在生产网站上,仍然经常看到这样的内容:



<div class="container" id="header">
    <div class="header header-main">Super duper best blog ever</div>
    <div class="site-navigation">
        <a href="/">Home</a>
        <a href="/about">About</a>
        <a href="/archive">Archive</a>
    </div>
</div>
<div class="container" id="main">
    <div class="article-header-level-1">
        Why you should buy more cheeses than you currently do
    </div>
    <div class="article-content">
        <div class="article-section">
            <div class="article-header-level-2">
                Part 1: Variety is spicy
            </div>
            <!-- cheesy content -->
        </div>
        <div class="article-section">
            <div class="article-header-level-2">
                Part 2: Cows are great
            </div>
            <!-- more cheesy content -->
        </div>
    </div>
</div>
<div class="container" id="footer">
    Contact us!
    <div class="contact-info">
        <p class="email">
            <a href="mailto:us@example.com">us@example.com</a>
        </p>
        <div class="street-address">
            <p>123 Main St., Suite 404</p>
            <p>Yourtown, AK, 12345</p>
            <p>United States of America</p>
        </div>
    </div>
</div>


Enter fullscreen mode Exit fullscreen mode

哎呀,代码量可真够大的<div>。而且,它确实管用。我是说,基本上管用。它拥有你需要的结构,而且我相信等你完成样式设计后,它看起来会和你预期的一样。但它也有一些大问题:

  • 可访问性- 许多 a11y 工具都非常智能,它们会尽力解析页面结构,以便按照页面作者的意图引导用户浏览,并为用户提供便捷的跳转点,让他们快速跳转到他们关注的页面部分。但<div>这些工具实际上并没有提供任何关于文档结构的有用信息。世界上最智能的 a11y 工具仍然不是人类,无法指望它能够解析属性classid并识别世界各地开发人员为区块命名的各种奇特方式。我能识别出那class="article-header-level-2"是副标题,但机器人却不能。(如果它能识别,那就把它从我的电脑里删掉吧,我还没准备好迎接通用人工智能 (AGI) 革命。)

  • 可读性- 要阅读此代码,您需要仔细扫描类名,从<div class="..."></div>样板代码中找出它们。一旦深入到标记的几层,就很难区分哪些</div>结束标签与哪些开始标签对应<div...>。您开始非常依赖 IDE 的功能,例如为不同的缩进级别着色突出显示匹配的标签,以便跟踪当前位置。而在较大的文档中,您可能需要在这些功能上进行大量滚动。

  • 一致性和标准——开始一份新工作或接手一个新项目,不得不从头学习代码库中各种各样复杂的标记约定,这可能会让人感到沮丧。如果每个人都有一种标准化的方式来标记 Web 文档中的通用结构,那么在不熟悉的代码库中浏览 HTML 文件并快速掌握其含义就会容易得多。要是真的有这样的标准就好了……

HTML5:这样的标准

HTML5并非新事物。这么说还真是轻描淡写。最初的工作草案早在 2008 年 1 月(11 年前!)就已发布公开征求意见,并于 2014 年 10 月(4 年半前)正式成为W3C 推荐标准。所以,它已经存在一段时间了。

HTML5 的主要进步之一是引入了一套标准化的语义元素。“语义”指的是一个词或一个事物的含义,因此“语义元素”旨在以更有意义的方式标记文档的结构,使其用途清晰并在文档中发挥什么作用。更重要的是,由于它们是标准化的,这些元素能够以一种每个人都能使用和理解的方式定义文档,包括机器人。

我认为 HTML5 规范本身在元素定义下的注释中很好地总结了这个问题<div>

注意:
强烈建议作者将 div 元素视为万不得已的选择,因为没有其他合适的元素可用。使用更合适的元素代替 div 元素,可以提高读者的可访问性,也方便作者维护。——
https://www.w3.org/TR/html5/grouping-content.html#the-div-element

我将语义块元素分为两类:主要结构内容指示符。它们并非标准术语,只是我为了本文而编造的。但我认为这种区分已经足够有用了。🤷‍♂️

主要结构

互联网上的各个网站、教程,甚至 CSS 库中,都存在一个非常常见的模式,而且理由充分。我们通常将页面最顶层划分为三个区域:headermainfooter,然后根据需要将这些区域划分为多个部分。我在上面的例子中就包含了这一点,以证明这一点:



<div class="container" id="header">...</div>
<div class="container" id="main">
    ...
    <div class="article-section">...</div>
    ...
</div>
<div class="container" id="footer">...</div>


Enter fullscreen mode Exit fullscreen mode

这种模式我已经见过(并且使用)几十年了,用这种方式构建文档非常有意义,不仅能提高 HTML 的可读性,还能方便用 CSS 修改页面样式。页眉和页脚元素还能让 PHP 或 Rails/ERB 等语言的部分模板更易于使用,因为你可以在整个网站中使用通用的页眉和页脚部分模板:



<?php include 'header.php'; ?>

<div id="main">...</div>

<?php include 'footer.php'; ?>


Enter fullscreen mode Exit fullscreen mode

事情是这样的:每个人都同意这是一个值得遵循的好模式。这其中就包括 WHATWG 和 W3C 的成员,他们在 HTML5 中将该模式标准化为四个新元素,并赋予了它们清晰的名称:<header><main><footer><section>

书挡:<header><footer>

<header>元素<footer>本质上是孪生兄弟:它们在规范中的定义非常相似,并且遵循相同的使用规则,唯一的区别在于它们的语义用途:页眉位于内容的开头,页脚位于内容的结尾。我所说的“内容”不仅仅指<body>页面的内容:这对元素旨在用于文档中任何代表具有明确开头和结尾的内容块的部分。这可以包括表单、文章、文章的章节、社交媒体网站上的帖子、卡片等等。

页眉和页脚在语义上附加到最近的“节根”“节内容”元素。这些元素包括<body><blockquote><section><td><aside>以及许多其他元素;如果您想查看完整列表,请点击上方链接。辅助技术可以使用这些元素和其他元素来生成文档的大纲,以帮助用户更轻松地浏览文档。您不应该为每个节根/内容设置多个页眉<header><footer>页脚。(每个元素一个可以,但不能设置两个相同的元素。)

最后需要注意的是,<header>s 通常会包含标题元素 ( <h1>- <h6>),用于上下文。这并非必需,但有助于将其他相关元素(例如链接、图片或副标题)与标题组合在一起,即使标题是 中唯一的元素,也能帮助保持一致的结构<header>

好东西:<main>

第三个主要区域元素<main>比较特殊。规范中提到了关于 的两件非常重要的事情<main>

文档的主要内容区域包括该文档独有的内容,但不包括在一组文档中重复的内容,例如站点导航链接、版权信息、站点徽标和横幅以及搜索表单(除非文档或应用程序的主要功能是搜索表单)。—
https://www.w3.org/TR/html5/grouping-content.html#elementdef-main

所以<main>,关键在于你把好内容、页面的重要部分、用户访问这个页面的原因,而不是你网站的总体情况放在哪里。换句话说,就是主要内容。😯😲🤯

所有其他东西,徽标、搜索表单和导航等,都可以放在 内<header><footer>之外<body><main>

文档中可见的main 元素不得超过一个。如果文档中存在多个 main 元素,则所有其他元素都必须使用hidden 属性隐藏。——
https://www.w3.org/TR/html5/grouping-content.html#elementdef-main

这非常独特。与<header><footer>(以及大多数其他块元素)不同,<main>它不能在整个页面的任意分段内容中使用;它应该使用一次且只能使用一次。或者更确切地说,它可以在一个文档中多次使用,但<main>一次只能显示一个元素;所有其他元素必须使用hidden属性隐藏,其作用基本类似于display: none;CSS。仔细想想,这暗示了一种在应用程序中预加载视图的非常有用的模式:创建一个新的<main hidden>,获取用户接下来可能查看的一些内容(例如,系列中的下一篇文章,幻灯片中的下一张幻灯片等),当用户点击链接/按钮加载该视图时,<main>通过切换两者的 属性将当前视图与预加载的视图交换hidden

<header>在继续之前,让我们先暂停一下,回顾一下上面的例子。如果我们使用、<main><footer>作为文章的主体结构,效果会是这样的:



<header>
    <h1>Super duper best blog ever</h1>
    ...
</header>
<main>
    <h2>Why you should buy more cheeses than you currently do</h2>
    ...
</main>
<footer>
    Contact us!
    <div class="contact-info">this.is.us@example.com</div>
</footer>


Enter fullscreen mode Exit fullscreen mode

这已经好多了!但还有很多工作要做。

分解一下:<section>

至此,我们已经有了页面的基本轮廓:页眉、页脚和主要内容区域。现在是时候添加一些精彩的内容了。

通常,您需要将内容分成几个部分,特别是对于像本文这样的大量文本内容,因为没有人喜欢阅读难以理解的长篇文字。

文字墙

没人喜欢长篇大论的文字

这就是<section>关键所在。这条规则就规则而言是最简单的:从结构上讲,它基本上只是一个<div>具有特殊语义的 。 A<section>开始一个新的“分区内容”区域,因此它可以拥有自己的<header>和/或<footer>

<section>那么,a和普通的 old之间有什么区别<div>?什么时候应该使用它们?好吧,请允许我再次引用规范:

注意:
<section>元素并非通用容器元素。当仅需将元素用于样式设置或方便脚本编写时,建议作者使用<div>元素。一般规则是,<section>只有当元素的内容在文档大纲中明确列出时该元素才适用。——
https://www.w3.org/TR/html5/sections.html#the-section-element

顺便说一句,HTML5 规范其实非常易读。它是目前可读性较高的规范之一。每次我浏览它寻找快速答案时,总能学到一些意想不到的有用信息,尤其是在点击链接的时候。有时间不妨试试!

简而言之,如果您要在目录中列出文档的这一部分,请使用<section>。如果不是,请使用<div>或其他名称。

内容指标

好的,我们的页面结构已经很清晰了。<div>我们不再只是到处乱扔 s 符号,而是明确标记了页面的主要内容区域,并标出了页眉、页脚和各个部分。但对于我们的文档来说,语义肯定不止于此。

让我们来讨论一下 HTML5 中添加的一些传达内容语义而不是结构的元素。

整个过程:<article>

<article>元素用于表示一个完全独立的内容区域,它可以从你的页面中抽离出来,并放入另一个页面,且仍然具有其自身的含义。这可以是一篇文字文章或博客文章,也可以用于社交媒体帖子,例如推文或 Facebook 留言板。

HTML5 规范建议文章始终包含一个标题来标识其内容,最好使用标题元素 ( <h1>- <h6>)。An<article>还可以包含<header><footer><section>元素,因此您可以使用它将完整的文档片段及其所需的所有结构嵌入到另一个页面中。

回到上面的例子,让我们class="article-*"使用<article>和一些我们讨论过的其他元素来重写这些元素。



<article>
    <header>
        <h1>Why you should buy more cheeses than you currently do</h1>
    </header>
    <section>
        <header>
            <h2>Part 1: Variety is spicy</h2>
        </header>
        <!-- cheesy content -->
    </section>
    <section>
        <header>
            <h2>Part 2: Cows are great</h2>
        </header>
        <!-- more cheesy content -->
    </section>
</article>


Enter fullscreen mode Exit fullscreen mode

这难道不是比原文可读性强多了?而且,它不仅更容易阅读,而且对辅助技术也更有用;机器人不一定能理解你特定的类名模式,但它们可以遵循这个结构。

出行方式:<nav>

这个元素比其他元素更为人所知。<nav>旨在清楚地识别页面上的主要导航块,帮助用户找到网站其余部分的链接组(例如站点地图或标题中的链接列表)或当前页面(例如目录)。

在我们上面的例子中,让我们将 应用于<nav>标题中的那组链接。



<nav>
    <a href="/">Home</a>
    <a href="/about">About</a>
    <a href="/archive">Archive</a>
</nav>


Enter fullscreen mode Exit fullscreen mode

根本不改变结构,但你一眼就知道它是什么,而不需要阅读和处理类名来<div>弄清楚,更重要的是机器人也可以找到它。

联系方式:<address>

我们要讨论的最后一个元素是<address>。此元素用于调出联系信息,通常用于主页中<footer>标记企业的邮寄地址、电话号码、客服邮箱地址等。

有趣的是,关于如何在元素内标记内容的规则<address>尚未确定。规范中提到,还有其他几个规范也涉及这个问题,而提供这种粒度的规范可能超出了HTML本身的范围。

一种常见的解决方案是RDFa,它也是W3C 规范,它使用标签上的属性来标记数据的不同组成部分。以下是我们示例中的页脚在使用<address>元素和 RDFa 标记后可能的样子:



<footer>
    <section class="contact" vocab="http://schema.org/" typeof="LocalBusiness">
        <h2>Contact us!</h2>
        <address property="email">
            <a href="mailto:us@example.com">us@example.com</a>
        </address>
        <address property="address" typeof="PostalAddress">
            <p property="streetAddress">123 Main St., Suite 404</p>
            <p>
                <span property="addressLocality">Yourtown</span>,
                <span property="addressRegion">AK</span>,
                <span property="postalCode">12345</span>   
            </p>
            <p property="addressCountry">United States of America</p>
        </address>
    </section>
</footer>


Enter fullscreen mode Exit fullscreen mode

RDFa 确实有点冗长,但它在标记数据方面非常方便。如果您想了解更多关于 RDFa 的信息,以下是一些链接:

结论

好的,我们已经讲了很多,并且已经看到很多内容零零碎碎地应用到我们的示例中。现在让我们把它们放在一起,看看它是什么样子。



<header>
    <h1>Super duper best blog ever</h1>
    <nav>
        <a href="/">Home</a>
        <a href="/about">About</a>
        <a href="/archive">Archive</a>
    </nav>
</header>
<main>
    <article>
    <header>
        <h1>Why you should buy more cheeses than you currently do</h1>
    </header>
    <section>
        <header>
            <h2>Part 1: Variety is spicy</h2>
        </header>
        <!-- cheesy content -->
    </section>
    <section>
        <header>
            <h2>Part 2: Cows are great</h2>
        </header>
        <!-- more cheesy content -->
    </section>
</article>
</main>
<footer>
    <section class="contact" vocab="http://schema.org/" typeof="LocalBusiness">
        <h2>Contact us!</h2>
        <address property="email">
            <a href="mailto:us@example.com">us@example.com</a>
        </address>
        <address property="address" typeof="PostalAddress">
            <p property="streetAddress">123 Main St., Suite 404</p>
            <p>
                <span property="addressLocality">Yourtown</span>,
                <span property="addressRegion">AK</span>,
                <span property="postalCode">12345</span>   
            </p>
            <p property="addressCountry">United States of America</p>
        </address>
    </section>
</footer>


Enter fullscreen mode Exit fullscreen mode

如果你问我,这比原始示例的可读性高 100 倍,并且对于 SEO 和可访问性目的而言也将有效 100 倍。

这些绝不是 HTML 中唯一的语义元素。还有很多其他元素可以帮助标记和构建文本内容、嵌入媒体等。如果您喜欢并想深入了解,可以查看以下几个元素。您可能会认识其中一些:

这仅仅是个开始!就像我说的,当你开始阅读 HTML 规范时,很难停下来。它是一门极其丰富的语言,我认为人们太经常低估它了。

文章来源:https://dev.to/kenbellows/stop-using-so-many-divs-an-intro-to-semantic-html-3i9i
PREV
使用 Next.js 将 WordPress 配置为无头 CMS
NEXT
在 JavaScript 中确定“this”的超级简单方法