你是如何理解 HTML 語義化的?(面試)
在了解 HTML 語義化之前,先科普一下下面幾個名詞:
語義:是語言所蘊含的意義 (語言的含義)。簡單的說,符號是語言的載體,符號本身沒有意義,只有賦予含義的符號才能夠被使用,此時語言就轉化為了信息。
SEO(Search Engine Optimization): 譯為搜索引擎優化,是一種 利用搜索引擎的規則提高網站在有關搜索引擎內的自然排名 的方式。能夠提高有效訪問量。
背景
最開始的時候,網頁是后臺去寫的,那個時候的 HTML 結構可能是一堆 table 推砌而成,連續 table 的嵌套讓頁面做出來之后難以維護。(原始/荒野階段)
后來,在沒有提出 HTML 結構語義化之前的 HTML 結構,相比荒野階段又有了一些改觀,就是 (美工階段),舉例來說就是:如果所有標簽都使用 div,只要靈活使用 CSS,你也能寫出視覺效果很好的頁面 (最泛濫的 div + CSS),但這就是一堆沒有語義的冷冰冰的標簽。。
雖然視覺上達到了要求,但是整個頁面一點語義也沒有。所以我們要盡可能避免使用一堆無意義的標簽去堆自己的 HTML 結構。
什么是語義化
這里的語義化,顧名思義,就是在書寫 HTML 結構的時候,要用相對應的有一定語義的標簽表示和標記。
更專業的來說就是,根據內容的結構化(內容語義化),選擇合適的標簽(代碼語義化),便于開發者閱讀和寫出更優雅的代碼的同時讓瀏覽器的爬蟲和機器更好地解析。
HTML 本身就是一門標記語言,所有標簽都是有自己的語義的,例如我們常用的:
- div:division (分隔)
- span: span (范圍)
- ol: Ordered List (排序列表)
- ul: Unordered List (不排序列表)
- li: List Item (列表項目)
- ......
HTML 語義化,不僅對書寫者自己來說,易于閱讀,其他人閱讀你的代碼和結構的時候也更容易理解,甚至是對于一些非開發者來說。
為什么要語義化
除了上述所說,具體為什么要語義化,有以下幾點原因:
- 各個語義化的標簽都或多或少帶著關方設定好的樣式,若是整個頁面是由 div + CSS 構成,那么如果 CSS 沒有加載出來,對頁面來說可能將是一場噩夢;
原因1:(當然上述是極端情況)為了在沒有 CSS 的情況下(純粹的 HTML 頁面),頁面也能呈現出很好的內容結構、代碼結構:裸奔更好看 - 各種標簽的靈活使用,而不是使用單一標簽實現頁面各種結構和內容,例如:元素的 alt 和 title 同時設置時,alt 作為圖片的替代文字出現,title 是圖片的解釋文字;label 標簽的活用;
原因2:極大程度利用標簽的特點,優化用戶體驗 - 和搜索引擎建立良好的溝通,有助于爬蟲爬取更多的有效信息:爬蟲依賴于標簽來確定上下文和各個關鍵字的權重;
原因3:有利于 SEO - 難免會有些特殊設備需要訪問網頁(例如:屏幕閱讀器、盲人閱讀器和移動設備等),此時代碼的語義化就顯得格外重要;
原因4:方便其他設備解析以語義化的方式來渲染網頁 - 語義化更具有可讀性,遵循 W3C 標準的團隊都遵循這個標準,可以減少差異化。
原因5:便于團隊開發和維護
怎樣做到 和 怎樣算是語義化的 HTML 結構
關于怎樣做到 HTML 語義化,我們需要注意以下幾點:
- 盡可能少的使用無語義的標簽 div 和 span;(其實它們也并非完全無語義,個人覺得是相對的);
- 在語義不明顯時,比如:既可以使用 div 也可以使用 p,那么盡量使用相對比較有語義化的標簽 p,因為 p 在默認情況下有上下間距,對兼容特殊終端有利;
- 不要使用純樣式標簽,如:b、font、u 等,改用 CSS 設置;
- 需要強調的文本,可以包含在 strong 或 em 標簽中,strong 默認樣式是加粗(不要用 b),em 是斜體(不要用 i);
- 使用表格時,標題要用 caption,表頭用 thead,主體部分用 tbody 包圍,尾部用 tfoot 包圍,表頭和一般單元格要區分開,表頭用 th,單元格用 td;
- 表單域要用 fieldset 標簽包起來,并用 legend 標簽說明表單的用途;
- 每個 input 標簽對應的說明文本都需要用 label 標簽,并且通過 input 設置 id 屬性,在 label 標簽中設置 for=
input的id
來讓說明文本和相對應的 input 關聯起來; - 補充:不僅寫 HTML 結構需要語義化,用語義化標簽,給元素寫 CSS 類名時,也要遵循語義化原則,不要隨便取名字就用,這樣以后重構或者閱讀代碼時,會很難讀懂。另外,最好使用英文,而不是用漢語拼音湊合代替(low)。
擴展
結構 (html) 才是重點,樣式 (css) 是用來修是結構的。所以要先確定 html,確定標簽,再來選用適合的 css。
當我們想表達文章的標題,我們或許會這樣寫:
<div class="title">我是標題</div>
這個時候看代碼的或者頁面的訪客或許可以理解我們的意思,但是 搜索引擎 / 特殊設備 就要反復揣摩了,它們只能通過分析源碼來體現或猜測網站想要表達的內容。然后我們像下面這樣:
<h1 class="title">這才是標題</h1>
h1 突出標題,用 strong 來突出關鍵字,就是語義化的體現。如果你還需要不同的呈現,再通過 css 去實現。
h1 擁有最高的權值,在一個頁面中最好只使用1個 h1 來突出內容,太多的 h1 會分散其整個頁面的權重,對搜索引擎也是非常不友好的。想要使用多個 h1~h6,可以使用 hgroup 標簽包住(html5 新增語義化標簽)。
總結
簡單的來說,就是當需要表達段落的時候用 p 標簽,需要表示標題的時候逐級用 h1-h6 標簽,整體文章用 article 標簽等。HTML 語義化就是使用語義化的標簽來實現 HTML (結構)語義化和 代碼 (標簽)語義化。因為這樣更能讓人讀懂頁面和代碼,更能發揮不同標簽不同場景下的功能,同時還對搜索引擎和特殊設備友好,大家都遵循規范,減少差異化,有利于開發和維護。
擴展:HTML 新增的語義化標簽
header
該元素代表** 網頁 或 section 的頁眉 (頭部)**。
通常包括 h1-h6
元素或 hgroup
,作為整個頁面或者一個內容塊的標題。也可以包裹一節的目錄部分,一個搜索框,一個 nav 或者任何相關的 logo。(如果標簽能自己存在,就不要用header)
整個頁面沒有限制 header 元素的個數,可以為每個內容塊增加一個 header 元素。
footer
該元素代表 網頁 或 section 的頁腳 (底部),通常也含有該節的一些基本信息,譬如:作者,相關文檔鏈接,版權資料等。如果footer元素包含了整個節,那么它們就代表附錄,索引,提拔,許可協議,標簽,類別等一些其他類似信息。沒有個數限制,除了包裹內容不一樣,其他跟 header 類似。
hgroup
該元素代表 網頁 或 section 的標題,當元素有多個層級時,該元素可以將 h1 到 h6 元素放在其內,譬如文章的主標題和副標題組合。
- 如果只需要一個h1-h6標簽就不用hgroup
- 如果有連續多個h1-h6標簽就用hgroup
- 如果有連續多個標題和其他文章數據,h1-h6標簽就用hgroup包住,和其他文章元數據一起放入header標簽
nav
該元素代表頁面導航鏈接區域,用于定義頁面的 主要導航部分。
有些時候在一些并不是主要導航部分的地方,譬如:側邊欄上目錄,面包屑導航,搜索樣式,或者下一篇上一篇文章,這些地方不適合就不要使用 nav 。事實上規范上說nav只能用在頁面主要導航部分上。頁腳區域中的鏈接列表,雖然指向不同網站的不同區域,譬如服務條款,版權頁等,這些footer元素就能夠用了。
aside
該元素被包含在 article 元素中作為主要內容的附屬信息部分,其中的內容可以是與當前文章的相關資料、標簽、名詞解釋等。(特殊的 section)
在 article 元素之外使用作為頁面或站點全局的附屬信息部分。沒有 article 與之對應,最好不用。最典型的是側邊欄,其中的內容可以是日志串連,其他組的導航,甚至廣告,這些內容相關的頁面。如果是廣告,其他日志鏈接或者其他分類導航可以用。
section
該元素代表文檔中的 “節” 或 “段”,“段” 可以是指一篇文章里按照主題的分段;“節” 可以是指一個頁面里的分組。其還通常帶標題,雖然html5中section會自動給標題h1-h6降級,但是最好手動給他們降級。
<section>
<h1>section是啥?</h1>
<article>
<h2>關于section</h1>
<p>section的介紹</p>
<section>
<h3>關于其他</h3>
<p>關于其他section的介紹</p>
</section>
</article>
</section>
一張頁面可以用section劃分為簡介、文章條目和聯系信息。不過在文章內頁,最好用article。section不是一般意義上的容器元素,如果想作為樣式展示和腳本的便利,可以用div。
article、nav、aside可以理解為特殊的section,所以如果可以用article、nav、aside就不要用section,沒實際意義的就用div。
article
該元素最容易跟 section 和 div 容易混淆,其實 article 代表一個在文檔,頁面或者網站中自成一體的內容,其目的是為了讓開發者獨立開發或重用。譬如論壇的帖子,博客上的文章,一篇用戶的評論,一個互動的widget小工具。(特殊的section)
除了它的內容,article會有一個標題(通常會在header里),會有一個footer頁腳。
如果在 article 內部再嵌套 article,那就代表內嵌的 article 是與它外部的內容有關聯的,如博客文章下面的評論。article 內部嵌套 article,有可能是評論或其他跟文章有關聯的內容。
<article>
<header>
<h1>一篇文章</h1>
<p><time pubdate datetime="2012-10-03">2012/10/03</time></p>
</header>
<p>文章內容..</p>
<article>
<h2>評論</h2>
<article>
<header>
<h3>評論者: XXX</h3>
<p><time pubdate datetime="2012-10-03T19:10-08:00">~1 hour ago</time></p>
</header>
<p>哈哈哈</p>
</article>
<article>
<header>
<h3>評論者: XXX</h3>
<p><time pubdate datetime="2012-10-03T19:10-08:00">~1 hour ago</time></p>
</header>
<p>哈?哈?哈?</p>
</article>
</article>
</article>
那 article 內部嵌套 section 一般是從屬關系,article 是大主體,section 是構成這個大主體的一部分。本網站的全部文章都是 article 嵌套一個個 section 章節,這樣能讓瀏覽器更容易區分各個章節所包括的內容。
<article>
<h1>前端技術</h1>
<p>前端技術有那些</p>
<section>
<h2>CSS</h2>
<p>樣式..</p>
</section>
<section>
<h2>JS</h2>
<p>腳本</p>
</section>
</article>
而 section 內部嵌套 article 相當于 section 將自成一體的 article 包裹,組成一個團體。
<section>
<h1>介紹: 網站制作成員配備</h1>
<article>
<h2>設計師</h2>
<p>設計網頁的...</p>
</article>
<article>
<h2>程序員</h2>
<p>后臺寫程序的..</p>
</article>
<article>
<h2>前端工程師</h2>
<p>給樓上兩位打雜的..</p>
</article>
</section>
- 自身獨立的情況下:用article
- 是相關內容:用section
- 沒有語義的:用div
HTML5節元素標簽包括body article nav aside section header footer hgroup ,還有h1-h6 address。
address 代表區塊容器,必須是作為聯系信息出現,郵編地址、郵件地址等等,一般出現在 footer。
h1-h6 因為 hgroup,section 和 article 的出現,h1-h6 定義也發生了變化,允許一張頁面出現多個 h1。