【譯】中止濫用div! HTML語義化介紹

banner

DIVS該中止(濫用)了

咱們喜歡(使用)<div>標籤。它們已經存在了幾十年,這幾十年來,當須要將一些內容包裹起來達到(添加)樣式或者佈局目的的時候,它們成爲首選元素。查看線上站點時,看到像下面這些內容的狀況依舊很常見:php

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

Hoo,那有不少的div標籤。可是,它有效。個人意思主要是,它具備你須要的結構。而且,我肯定在你完成樣式添加以後,它看起來會像你想要的那個樣子。然而,它有些嚴重的問題:html

  • 可訪問性 - 許多a11y tools很是智能,會盡力解析頁面結構,以幫助用戶按照頁面製做者的意圖來引導用戶,併爲用戶提供簡單的跳轉連接來指引他們到本身關心的頁面部分。然而,<div>標籤並無真正傳遞有關文檔結構的任何有用信息。世界上最聰明的a11y tool仍然不是人類,不能期望其解析classid屬性,或可以識別全世界開發人員命名塊元素的奇怪和狂野的方式。我能夠識別到class="article-header-level-2"是一個副標題,可是機器不能。(若是能夠的話,把它從我電腦中拿出來,可我也還沒準備好進行AGI革命呢。)html5

  • 可讀性 - 要閱讀此代碼,你須要仔細掃描類名,從<div class="..."></div>樣板之間挑選出來。一旦你(的代碼)深刻幾個層次,跟蹤哪一個</div>結束標記與哪一個<div ...>開始標記對應,那就變得很棘手了。你開始很是依賴IDE功能,例如着色不一樣的縮進級別突出顯示匹配的標記以跟蹤您的位置,而在較長的文檔中,它可能須要在這些功能之上進行大量的滾動。git

  • 一致性和標準 - 開始新的工做或轉移到新項目,而且必須從頭學習代碼庫中使用的讓人抓狂的標記,那可能會使人很沮喪。若是每一個人都有標準化的方法來標記web文檔中常見結構,那麼在不熟悉代碼庫的狀況下,均可以很容易的瀏覽HTML文件並快速處理它應該展現的內容。若是隻有一個這樣的標準...github

HTML5: 這個標準

HTML5並不新奇。這是輕描淡寫;最初的工做草稿於2008年1月(11年前)發佈,以徵求公衆意見,並於4年半前,2014年10月份成爲一個全面W3C的推薦。因此,就像它已經存在了一段時間。web

HTML5的主要進步之一是引入了一組標準化的語義元素。術語「語義」指的是單詞或事物的含義,所以」語義元素「是用於以更有意義的方式標記文檔結構的元素,這種方式能夠清楚地代表它們的用途和它們在文件中服務的目的是什麼。並且重要的是,因爲它們是標準化的,定義文檔的這些元素能夠被每一個人使用並理解,包括機器人。dom

我認爲HTML5規範自己在<div>元素定義下的一個註釋中很好地總結了這個問題:ide

註釋: 強烈建議做者將div元素視爲最後採起的元素,在沒有其它元素適合的(狀況下)。使用更合適的元素而不是div元素可使讀者更容易訪問,而且更容易爲做者提供可維護性。-- www.w3.org/TR/html5/gr…佈局

我將語義塊元素分爲兩類:主要結構內容指標。這些不是標準的條款或者其它條款;我在這篇文章中作了一些(區分)。但我認爲這種區分足夠有用。🤷‍♂️post

主要結構

有一個超級常見的模式,可在互聯網上的網站,教程甚至CSS庫中找到,而且有充分的理由。咱們常常將最頂層的頁面劃分爲三個區域:頁眉主頁頁腳,而後根據須要將這些區域劃分爲多個區域。我在上面的例子中包含了這個來證實這點:

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

我已經看過(而且使用過)這種模式好久了,以這種方式構造文檔很是有意義,既能夠讀取HTML,又能夠更加簡單地在CSS中設置頁面樣式。頁眉和頁腳元素頁可使用PHP或Rails/ERB等語言中的部分模版來更易於使用,由於你能夠在整個站點中包含常見的頁眉和頁腳部分:

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

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

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

因此這就是事情:每一個人都認爲這是一個很好的模式。這包括WHATWGW3C的人員,他們將模式標準化爲HTML5中的四個新元素,名稱很是清晰:<header>, <main>, <footer><section>

Bookends: <header><footer>

<header><footer>元素基本上是雙胞胎:它們在規範中的定義很是類似,並遵循相同的規則,關於它們被容許使用的位置,惟一區別在於它們的語義目的:頁眉在事物的前面,頁腳在事物的末尾。對於事物,個人意思不只僅是頁面的: 這對元素的設計用於文檔的任何部分,表明一大塊內容,具備明確的開頭和結尾。這能夠包括表格,文章,文章部分,社交媒體網站上的帖子,卡片等。

頁眉和頁腳在語義上接近sectioning rootsectioning content元素。像<body>, <blockquote>, <section>, <td>,<aside>等許多其它元素;若是你想了解完整的列表,就點擊上面的連接。輔助技術可使用這些元素和其它元素生成文檔大綱,這能夠幫助用戶更輕鬆的訪問它。在每一個sectioning root/content中,你不該該使用超過一個的<header><footer>。(一個就好,不能兩個相同)

做爲最後說明,<header>常常做爲其上下文保存標題元素(<h1>-<h6>)。這不是必須的,但能夠幫助將其它相關元素與標題分組,好比連接,圖片或子標題,而且能夠維持一直的結構,即便標題是<header>中的惟一元素。

好東西:<main>

第三個主要區域元素--<main>很特別。規範中說明了關於<main>的兩個很是重要的內容:

文檔的主要內容區域包括文檔的特定內容,且不包括在一組文檔中重複的內容,例如站點導航連接,版本信息,站點的徽標,橫幅和搜索表單(除非文檔或應用的主功能是一種搜索形式)-- www.w3.org/TR/html5/gr…

因此,<main>是你放置好東西的區域,是頁面的重要部分,特別是用戶訪問此頁面的緣由(或說目的),而不是您的站點。換句話來講,主要內容。😯😲🤯

全部其它東西,徽標、搜索表單和導航欄等均可以在<body>中的<header><footer>中,可是在<main>以外。

文檔中不能有多個可見的main元素。若是文檔中存在多個main元素,則必須使用隱藏屬性隱藏全部其它(main)實例。 -- www.w3.org/TR/html5/gr…

這很獨特。和<header><footer>(以及其它塊元素不一樣),<main>不能在任意切片內容的整個頁面中使用;它應該只被使用一次。或者更確切地說,它能夠在文檔中屢次被使用,可是一次只能看到一個<main>元素,全部其它的(

)必須被使用隱藏屬性隱藏,如CSS中的 display:none。若是您思考下,(你會明白)這在應用程序中預加載視圖是種頗有用的模式:建立一個新的 <mian hidden>,獲取用戶可能接下來查看的一些內容(例如:系列文中的下一篇,下一張幻燈圖放映等),而後,當用戶點擊 連接/按鈕加載該視圖時,經過在二者上切換 隱藏屬性,將當前的 <main>切換到預加載的(那個)。

在繼續以前,咱們暫停下並查看上面的示例。若是咱們使用<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>
複製代碼

那真的很棒!可是,還有不少工做要作。

分解:<section>

所以,咱們爲頁面提供了一個基本大綱:頁眉,頁腳和主要內容區域。如今是時候添加些美妙的內容了。

一般,你會但願將你的內容分解爲多個部分,尤爲是對像本文這樣的大量文本內容,由於沒人喜歡閱讀這些難以理解的文本牆。

Nobody likes a wall of text

<section>派上用場了。這是在系列規則中最簡單的一個:從結構上講,它基本上只是一個具備特殊含義的<div>。一個<section>開始一個新的"sectioning content"區域,所以它能夠有本身的<header><footer>

那麼,<section>和普通的舊<div>之間有什麼區別,而後,你應該在何時使用它們呢?好吧,容許我再次引用規範:

筆記:

元素不是通用容器元素。當一個元素僅是用於樣式目的或爲腳本編寫提供便利的時候,鼓勵做者使用[div](https://www.w3.org/TR/html5/grouping-content.html#elementdef-div)元素。通常規則是
元素僅在元素內容在文本[大綱](https://www.w3.org/TR/html5/sections.html#outline)中明確列出時候才適用。-- [https://www.w3.org/TR/html5/sections.html#the-section-element](https://www.w3.org/TR/html5/sections.html#the-section-element)

你知道,概述來講,HTML5規範其實是可讀的。它是那個比較可讀的規範之一。每當我瀏覽它以獲取快速答覆時,我都不可避免地學到一些意想不到的和有用的東西,尤爲是當我開始點擊連接的時候。有時(你也)試試吧!

簡而言之,若是要在目錄中列出文檔的一部分,請使用<section>。若是沒有,請使用<div>或其它元素。

內容指標

很好,咱們已經獲得了一個堅固的頁面結構。咱們已經明確標記了頁面的主要內容區域,而不只僅是單獨調整<div>,咱們已經調整出了頁眉,頁腳和章節。可是,確定還有比咱們的文檔更多的語義。

讓咱們來談談HTML5中添加的一些元素,它們傳達的內容語義而不是結構。

總體:<article>

<article>元素用於表示徹底獨立的內容區域,這些內容能夠從頁面中提取出來並放入另外一個內容中,而且仍然有意義。這多是文字文章或博客,但也可用於社交媒體帖子,如推特或臉書的牆貼。

HTML5規範建議文章總有一個標題,標識它是什麼,理想的狀況下使用標題元素(<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>旨在清楚地識別頁面上的主要導航塊,幫助用戶圍繞站點其他部分找到路徑的連接組(例如站點地圖或標題中的連接列表)或當前頁面(例如目錄)。

在咱們的示例頂部,讓咱們將<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倍,並且對於搜索引擎優化和可訪問性目的而言,其效率將提升100倍。

這些毫不是HTML中惟一的語義元素。有不少其它元素能夠幫助你標記和構建你的文本內容,嵌入媒體資源等等。若是你喜歡這個而且但願深刻挖掘,這裏有一些(標籤)能夠查看下。你可能認識一些:

這只是一個開始!就像我說的,當你開始閱讀HTML規範時,很難停下來。它是種很是豐富的語言,我認爲人們常常會低估這種語言。

原文: dev.to/kenbellows/…

文章首發:github.com/reng99/blog…

更多內容:github.com/reng99/blog…

相關文章
相關標籤/搜索