[譯] 不要再用這麼多 div 了,試試語義化標籤吧

原文連接:Stop using so many divs! An intro to semantic HTML,by Ken Bellowsphp

好多 div

咱們都喜歡使用 <div> 寫網頁。它已經存在幾十年了。幾十年來,當你出於樣式或結構的考慮須要將一些東西包裝到一塊兒時,<div> 已經成爲首選元素。如今的線上網站廣泛能看到下面的代碼結構:html

<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>
複製代碼

用了不少 <div> 啊。無論怎麼說,這樣用也是有效的。個人意思是說,這是咱們須要的結構,並且也能依照設計完成樣式寫書。但這裏面有些大問題:html5

  1. 可訪問性:許多 a11y 工具都很聰明。它們會盡力解析頁面結構,幫助用戶按照開發者的意圖瀏覽頁面結構,併爲用戶提供輕鬆的跳轉點(jump points),快速導航到頁面的某個部分。但 <div> 並不能提供有關文檔結構的任何有用信息。世界上最聰明的 a11y 工具說到底也不是人,不能指望它經過解析 class 和 id 就能明白全世界開發者各類怪異和狂野的命名方式。我能知道 class="article-header-level-2" 是一個副標題,但機器人不能。(若是真的能夠,請你把它從個人計算機中請出,我尚未作好 AGI 革命 到來的準備。)
  2. 可讀性:閱讀上面的代碼,咱們須要仔細查看類名,還要分清楚是哪一個 <div class="..."></div> 上的。不過,一旦進入到深幾個層次的標記,就很難分清楚哪些 </div> 結束標記對應的 <div...> 開始標記在哪裏。而後,咱們就很是依賴 IDE 提供的爲 不一樣的縮進級別着色突出顯示匹配的標籤 等功能,來搞清楚當前所處的位置。若是文檔內容很長的話,可能還要藉助大量滾動。
  3. 一致性和標準。當開始一項新任務或轉移到一個新項目時,從頭學習整個代碼庫中使用的全部瘋狂標記約定可能會使人沮喪。若是你們都用一種標準化的方法來標記 Web 文檔裏的通用結構,那麼即便對於不熟悉的代碼庫,咱們也能經過瀏覽 HTML 文件,快速了它的意思。這個標準就是 HTML5。

HTML5

HTML5 不是什麼新東西了。簡單介紹一下:它是在 2008 年 1 月(12 年前!)發佈了最初的工做草案徵求公衆意見,並於 2014 年 10 月成爲 W3C 推薦標準。也就是說,HTML5 正式存在都 5 年多了。markdown

HTML5 的主要進步之一是引入了標準化的 語義元素。「語義」是指單詞或事物的含義,所以「語義元素」就是爲了用更有 意義的 方式標記文檔結構的元素。語義標籤能夠清楚地代表元素的 用途 和在文檔裏所起的做用。並且,因爲是標準化的,因此用這些元素定義文檔,不只開發者,就連機器人都能順利的理解和使用。dom

其實 HTML5 標準在 定義 <div> 元素時的一個 note 它的使用場景:ide

NOTE:工具

除非是沒有其餘合適的元素了,強烈建議做開發者(Author)將 div 元素視爲最後的選擇。使用更合適的元素而非 div 能夠爲讀者提供更好的可訪問性,並且代碼也更易維護。oop

— www.w3.org/TR/html5/gr…post

我將語義塊元素分爲兩類:主要結構(primary structure) 和  指示內容(content indicators)。這些不是標準術語,是我爲這篇文章總結的,我認爲這種區分更利於咱們學習。學習

主要結構

如今的互聯網網站、教程甚至 CSS 庫中可以找到一種超級通用的模式。頁面的最頂層一般分爲三個區域:headermainfooter,這些區域還能夠進一步劃分紅不一樣的 section。上面示例中代碼就證實了個人觀點:

<div class="container" id="的">...</div>
<div class="container" id="main">
    ...
    <div class="article-section">...</div>
    ...
</div>
<div class="container" id="footer">...</div>
複製代碼

我已經看過(並使用)這個模式幾十年了,以這種方式構造文檔很是有意義,既能夠提升 HTML 的可讀性,也能夠簡化頁面樣式。header 和 footer 元素也能與 PHP 或 Rails/ERB 等語言中的部分模板更好的協做使用,好比你能夠在整個站點中使用統一頁眉和頁腳:

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

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

<?php include 'footer.php'; ?>
複製代碼

你們都以爲這是一個很好的模式,包括在 WHATWG 和 W3C 的朋友們。因而 HTML5 就引入了 4 個看名字就知道其含義的標準化語義元素:<header><main><footer><section>

書立:<header> 和 <footer>

<header><footer> 元素是一對雙胞胎:關於能夠在文檔裏的哪裏使用的規則在規範裏的定義很類似,惟一的區別是:<header> 放在事物的開始,<footer> 放在事物的結尾。所謂「事物」,不只指頁面的 元素:這對元素能夠在文檔中任何具備清晰開始和結尾的內容塊中使用。這些內容塊能夠是表單、文章、文章中的某個部分、社交媒體網站上的帖子、卡片等。

<header> 和 <footer>  在語義上是在最近的 「secioning root」或「sectioning content」元素裏使用的。這些元素由 <body><blockquote><section><td><aside> 和許多其餘元素構成(若是須要查看完整的列表,請單擊上面的連接)。輔助技術可使用這些元素和其餘元素來生成文檔的大綱,幫助用戶更輕鬆地瀏覽文檔。同時須要注意的是,每一個 sectioning root/content 只能有一個 <header><footer>(每一個最多出現一次,不可能同時兩次)。

最後要注意的是,<header> 中一般會包含標題元素(<h1>~<h6>)。固然,不是必定要有的,但能夠幫助其餘相關元素與標題組合,好比:連接、圖像或子標題。即便 <header> 中只包含一個標題元素,也能保持它在結構上的一致。

好東西:<main>

第三個主要的 regoin 元素是 <main>,它比較特殊。規範中對它作了兩點重要說明:

文檔的 <main> 包含該文檔獨一無二的內容。它不包括文檔中的重複內容,好比網站導航連接、版權信息、網站 Logo、Banner 以及搜索表單(除非文檔或應用的主要功能是表單搜索功能)。

www.w3.org/TR/html5/gr…

所以 <main> 中放置的是一個頁面裏好的、重要的內容,它是用戶爲何 訪問這個頁面的主要緣由,而不是你的站點。換句話說,主要內容。😯😲🤯

其餘的像 Logo、搜索表單、導航啦這些東西能夠放在 <body> 的 <header><footer> 裏面,<main> 的外面。

一個文檔中最多隻能有一個 <main> 元素。若是文檔中包含多個 <main> 元素,則其餘的必須使用 hidden 屬性 隱藏。

www.w3.org/TR/html5/gr…

這很獨特。與 <header><footer>(以及大多數的其它塊狀元素)不一樣的是,<main> 不能在整個頁面裏的任意 sectioning content 中使用,它能且只能使用一次。或者能夠屢次使用,但一次只能讓一個 <main> 元素可見,其它的則要經過 hidden 屬性隱藏,效果等同於 CSS 的 display: none

細想一下,這個限制對在應用程序添加預加載視圖的功能很是有用:建立一個新的 <main hidden>,獲取用戶接下里可能要查看的內容(例如,系列中的下一篇文章,幻燈片演示裏的下一張幻燈片等等)。當用戶單擊連接/按鈕時,經過切換當前 <main> 和預加載的 <main hidden> 中的 hidden 屬性實現視圖切換功能。

接下去講以前,咱們先暫停一下,回顧下以前講過的內容。文章開始的代碼 ,使用 <header><footer><main> 修改以後,變爲下面這樣了:

<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>
複製代碼

很好!不過還有不少工做要作。

拆分:<section>

至此,咱們獲得了頁面的基本大綱:頁眉、頁腳和主要內容區域。如今是時候添加一些美妙的內容了。

咱們一般會將內容細分紅多個 section,尤爲是對下面這樣,包含大量文本內容的文章。沒有人喜歡閱讀這樣的文本牆。

沒人喜歡讀這樣的文本牆

這就是引入 <section> 的意義所在。<section> 的規則是最簡單的:結構上來講,它基本上就是一個具備特殊的語義的 <div><section> 開啓一個新的「sectioning content」區域,因此它能夠有本身的 <header><footer>

那麼,<section> 和普通 <``div``>之間的區別是什麼。何時用 <div>,又是何時使用 <section> 呢?我再次引用規範來解答:

NOTE:

<section> 不是通用容器元素。若是這是爲了樣式目的或方便編寫腳本代碼,那麼鼓勵開發者使用 <div>。通常規則是,若是元素內容須要出如今文檔 大綱 中,那麼這些內容就要使用  <section> 元素包裝。

www.w3.org/TR/html5/se…

順便說一句,HTML5 規範很容易閱讀。每次爲了獲得答案快速瀏覽時,我都會不可避免地學到一些意想不到的有用信息,尤爲是在我開始點擊連接時。有空試試看吧!

簡而言之——若是你須要將這部份內容出如今目錄中,那麼就使用 <section> 吧;若是不須要,那就使用 <div> 或其餘元素吧。

指示內容

咱們已經獲得了一個結構牢固的頁面了。沒有隻用 <div>,咱們明確標記了頁面的主要內容區域,還標識了頁眉、頁腳和 section,可是絕對還有比咱們文檔中使用的更多語義元素。

接下來,咱們再談談 HTML5 中添加的其它一些元素,這些元素傳達的是 內容 語義而非 結構 語義。

徹底獨立的內容:<article>

<article> 元素用來表示徹底獨立的內容區域。這塊內容區域即便被放入另外一個頁面,仍然有意義。好比,這多是篇文章或帖子,但也多是一篇推文或者或 Facebook 牆貼之類的社交媒體內容。

HTML5 規範建議 <article> 都要有一個標題,來標識它的含義,最好使用標題元素(<h1>~<h6>)。<article> 元素中能夠包含 <header><footer><section> 元素,所以你確實能夠用它在另外一個頁面中嵌入完整的文檔片斷及其須要的全部結構。

回到最初的例子,咱們使用 <article> 和討論過的一些其餘元素來重寫 class="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>
複製代碼

是否是可讀性多了好多?不僅是更易於閱讀了,輔助技術也能識別這個結構。機器人不能老是辨別出正確的類名含義,卻能理解這些結構。

<nav>

這個元素比其餘元素更出名。由於 <nav> 是爲了清楚地標識頁面上的主要導航塊,幫助用戶導航到網站的其餘部分(好比站點地圖或 <header> 中的連接列表)或導航當前頁面(好比標識目錄)。

上面的例子中,咱們爲 <header> 中的連接應用 <nav>

<nav>
    <a href="/">Home</a>
    <a href="/about">About</a>
    <a href="/archive">Archive</a>
</nav>
複製代碼

修改沒有改變頁面結構,不須要看 <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>
複製代碼

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>
複製代碼

要我說,如今的寫法比開始的寫法可讀性提升了 100 倍,同時對 SEO 和輔助設備也友好了 100 倍。

固然,HTML 中的語義元素決不止這些,還有許多其餘的元素來幫助咱們標記和構造文本和嵌入式媒體等。若是你對語義標籤的學習還未知足,想要更加深刻地瞭解。這裏列出一些供你參考,其中一些也可能已經認識了:

本篇文章只是起了個頭。當你開始閱讀 HTML 規範時,發現根本停不下來。它是一門很是豐富的語言,我認爲你們低估了 HTML 在網站裏所起的做用。

(正文完)


廣告時間(長期有效)

我有一位好朋友開了一間貓舍,在此幫她宣傳一下。如今貓舍裏養的都是布偶貓。若是你也是個愛貓人士而且有須要的話,不妨掃一掃她的【閒魚】二維碼。不買也沒關係,看看也行。

(完)

相關文章
相關標籤/搜索