大家好我是落塵,一名新進晉級的菜鳥小編,也是一名前端開發攻城獅,從今天起帶大家重新理解前端,重新學習前端,讓大家有新的理解,每天都會更新些前端知識,如果小主們覺得還可以那就關注一下吧!
今天這篇是我們正式開篇的第一篇文章,我想和你聊聊 HTML。
我猜屏幕那一邊的你估計會說:「HTML 我很熟悉了,每天寫,這不是初級程式設計師才學的內容麼,這我還能不會嗎?」
其實在我看來,HTML 並不簡單,它是典型的「入門容易,精通困難」的一部分知識。深刻理解 HTML 是成為優秀的前端工程師重要的一步。
我們在上一篇文章中講到了,HTML 的標籤可以分為很多種,比如 head 裡面的元信息類標籤,又比如 img、video、audio 之類的替換型媒體標籤。我今天要講的標籤是:語義類標籤。
語義類標籤是什麼,使用它有什麼好處?語義類標籤也是大家工作中經常會用到的一類標籤,它們的特點是視覺表現上互相都差不多,主要的區別在於它們表示了不同的語義,比如大家會經常見到的 section、nav、p,這些都是語義類的標籤。
語義是我們說話表達的意思,多數的語義實際上都是由文字來承載的。語義類標籤則是純文字的補充,比如標題、自然段、章節、列表,這些內容都是純文字無法表達的,我們需要依靠語義標籤代為表達。
在講語義之前,我們來說說為什麼要用語義。
現在我們很多的前端工程師寫起代碼來,多數都不用複雜的語義標籤, 只靠 div 和 span 就能走天下了。
這樣做行不行呢?毫無疑問答案是行。那這樣做好不好呢?按照正確的套路,我應該說不好,但是在很多情況下,答案其實是好。
這是因為在現代網際網路產品裡,HTML 用於描述「軟體界面」多過於「富文本」,而軟體界面裡的東西,實際上幾乎是沒有語義的。比如說,我們做了一個購物車功能,我們一定要給每個購物車裡的商品套上 ul 嗎?比如說,加入購物車這個按鈕,我們一定要用 Button 嗎?
實際上我覺得沒必要,因為這個場景裡面,跟文本中的列表,以及表單中的 Button,其實已經相差很遠了,所以,我支持在任何「軟體界面」的場景中,直接使用 div 和 span。
不過,在很多工作場景裡,語義類標籤也有它們自己無可替代的優點。正確地使用語義標籤可以帶來很多好處。
不過,不恰當地使用語義標籤,反而會造成負面作用。這裡我們舉一個常見的誤區作為例子。我們都知道 ul 是無序列表,ol 是有序列表,所以很多接觸過語義這個概念,半懂不懂的前端工程師,特別喜歡給所有並列關係的元素都套上 ul。
實際上, ul 是長成下面的這種樣子的 (以下來自 HTML 標準)。
I have lived in the following countries:
Switzerland
Norway
United Kingdom
United States
ul 多數出現正在行文中間,它的上文多數在提示:要列舉某些項。但是,如果所有並列關係都用 ul,會造成大量冗餘標籤。
錯誤地使用語義標籤,會給機器閱讀造成混淆、增加嵌套,給 CSS 編寫加重負擔。
所以,對於語義標籤,我的態度是:「用對」比「不用」好,「不用」比「用錯」好。當然了,我覺得有理想的前端工程師還是應該去追求「用對」它們。
與 JavaScript 這樣嚴格的程式語言相比,HTML 中語義標籤的使用更接近我們平常說話用的自然語言。我們說話並沒有唯一的標準措辭,語義標籤的使用也是一樣。下面,我挑選了幾種(我認為)比較重要的語義標籤使用場景,來為你介紹一下。
作為自然語言延伸的語義類標籤其實語義問題不僅僅屬於理科,它還是個文科問題。
所以我們這裡講語義標籤的使用的第一個場景,也是最自然的使用場景,就是:作為自然語言和純文本的補充,用來表達一定的結構或者消除歧義。
我們先來看看「表達一定的結構」這個場景。
在日語中,有一個語法現象叫做:ルビ,它的讀音是 ruby(著名的 ruby 語言就是據此命名的),它中文的意思大約類似於注音或者意思的註解,它的形式可以看下圖:
圖中的例子選自動畫片《某科學的超電磁炮》第二季第一話。圖中把 teleport 放在空間移動上方的用法,就是日文中 ruby 的用法。「空間移動」是動畫中白井黑子的技能,這裡動畫字幕上寫的是「空間移動」,動畫裡的臺詞則用了英文發音「Teleport」,這裡就形成了一個使用 ruby 的場景。
ruby 的這個形式,在中國的網友中間最近被玩出了新花樣,比如表情包。
有時候微信聊天,不能用 ruby 這樣的東西真的是好急啊,只好用括號代替,效果真是差了不少。
在 HTML5 中,就引入了這個表示 ruby 的標籤,它由 ruby、rt、rp 三個標籤來實現。
所以說,這些情況裡存在的語義,其實原本就存在了,只是我們用純文字是沒法表達的,HTML 作為一種「超文本」語言,支持這些文字表達就是必要的了。
還有一種情況是,HTML 的有些標籤實際上就是必要的,甚至必要的程度可以達到:如果沒有這個標籤,文字會產生歧義的程度。
這裡我們可以介紹一下 em 標籤。
複製代碼
我們看看這句話,看上去它很清楚,但是實際上,這句話放到不同上下文中,可能表達完全不同的意思。
複製代碼
再比如:
複製代碼
試著讀一讀,這兩段裡面的「今天我吃了一個蘋果」,你是不是發現讀音不自覺地發生了變化?
實際上,不僅僅是讀音,這裡的意思也發生了變化。前一段中,表示我今天吃的是蘋果,而不是別的什麼東西,後一段中,則表示我今天只吃了一個蘋果,沒有多吃。
當沒有上下文時,如何消除歧義呢?這就要用到我們的 em 標籤了。em 表示重音:
今天我吃了一個 <em> 蘋果 </em>。
今天我吃了 <em> 一個 </em> 蘋果。
複製代碼
通過 em 標籤,我們可以消除這樣的歧義。
一些文章常常會拿 em 和 strong 做對比,實際上,我們只要理解了 em 的真正意思,它和 strong 可謂天差地別,並沒有任何混淆的可能。
作為標題摘要的語義類標籤介紹完自然語言的語義場景後,我想介紹的另一個語義重要使用場景,就是文章的結構。中國古代小說就形成了「章 - 回」的概念,西方的戲劇也有幕的區分,所以人類的自然語言作品也是如出一轍。
HTML 也應該支持這樣的需求。HTML 語義標籤中,有不少是用於支持這樣的結構的標籤。
語義化的 HTML 能夠支持自動生成目錄結構,HTML 標準中還專門規定了生成目錄結構的算法,即使我們並不打算深入實踐語義,也應該儘量在大的層面上保證這些元素的語義化使用。
首先我們需要形成一個概念,一篇文檔會有一個樹形的目錄結構,它由各個級別的標題組成。這個樹形結構可能不會跟 HTML 元素的嵌套關係一致。
例如:
<h1>HTML 語義 </h1>
<p>balah balah balah balah</p>
<h2> 弱語義 </h2>
<p>balah balah</p>
<h2> 結構性元素 </h2>
<p>balah balah</p>
.
複製代碼
這段 HTML 幾乎是平鋪的元素,但是它的標題結構是:
h1-h6 是最基本的標題,它們表示了文章中不同層級的標題。有些時候,我們會有副標題,為了避免副標題產生額外的一個層級,我們使用 hgroup 標籤。
我們來看下有 / 無 hgroup 的對比:
<h1>JavaScript 對象 </h1>
<h2> 我們需要模擬類嗎?</h2>
<p>balah balah</p>
.
複製代碼
此段生成以下標題結構:
<hgroup>
<h1>JavaScript 對象 </h1>
<h2> 我們需要模擬類嗎?</h2>
</hgroup>
<p>balah balah</p>
.
複製代碼
這一段生成以下標題結構:
我們通過兩個效果的對比就可以知道,在 hgroup 中的 h1-h6 被視為同一標題的不同組成部分。
從 HTML 5 開始,我們有了 section 標籤,這個標籤可不僅僅是一個「有語義的 div」,它會改變 h1-h6 的語義。section 的嵌套會使得其中的 h1-h6 下降一級,因此,在 HTML5 以後,我們只需要 section 和 h1 就足以形成文檔的樹形結構:
<section>
<h1>HTML 語義 </h1>
<p>balah balah balah balah</p>
<section>
<h1> 弱語義 </h1>
<p>balah balah</p>
</section>
<section>
<h1> 結構性元素 </h1>
<p>balah balah</p>
</section>
.
</section>
複製代碼
這段代碼同樣會形成前面例子的標題結構:
作為整體結構的語義類標籤我們想介紹的最後一個場景是,隨著越來越多的瀏覽器推出「閱讀模式」,以及各種非瀏覽器終端的出現,語義化的 HTML 適合機器閱讀的特性變得越來越重要。
應用了語義化結構的頁面,可以明確地提示出頁面信息的主次關係,它能讓瀏覽器很好地支持「閱讀視圖功能」,還可以讓搜尋引擎的命中率提升,同時,它也對視障用戶的讀屏軟體更友好。
我們正確使用整體結構類的語義標籤,可以讓頁面對機器更友好。比如,這裡一個典型的 body 類似這樣:
<body>
<header>
<nav>
……
</nav>
</header>
<aside>
<nav>
……
</nav>
</aside>
<section>……</section>
<section>……</section>
<section>……</section>
<footer>
<address>……</address>
</footer>
</body>
複製代碼
在 body 下面,有一個 header,header 裡面是一個 nav,跟 header 同級的有一個 aside,aside 裡面也有一個 nav。接下來是文章的整體,也就是一個一個的 section。section 裡面可能還有嵌套,但是我們就不管了,最後是一個 footer,這個 footer 裡面可能有 address 這樣的內容。
除此之外,還有 article,article 是一種特別的結構,它表示具有一定獨立性質的文章。所以,article 和 body 具有相似的結構,同時,一個 HTML 頁面中,可能有多個 article 存在。
一個典型的場景是多篇新聞展示在同一個新聞專題頁面中,這種類似報紙的多文章結構適合用 article 來組織。
<body>
<header>……</header>
<article>
<header>……</header>
<section>……</section>
<section>……</section>
<section>……</section>
<footer>……</footer>
</article>
<article>
……
</article>
<article>
……
</article>
<footer>
<address></address>
</footer>
</body>
複製代碼
body 裡面有自己的 header 和 footer,然后里面是豎篇的 article,每一個 article 裡面都有自己的 header、section、footer。這是一個典型的多文章結構。
在這個結構裡,我們看到了一些新標籤,我也來逐個介紹一下。
header 和 footer 一般都是放在 article 或者 body 的直接子元素,但是標準中並沒有明確規定,footer 也可以和 aside,nav,section 相關聯(header 不存在關聯問題)。
aside 很容易被理解為側邊欄,實際上二者是包含關係,側邊欄是 aside,aside 不一定是側邊欄。
aside 和 header 中都可能出現導航(nav 標籤),二者的區別是,header 中的導航多數是到文章自己的目錄,而 aside 中的導航多數是到關聯頁面或者是整站地圖。
最後 footer 中包含 address,這是個非常容易被誤用的標籤。address 並非像 date 一樣,表示一個給機器閱讀的地址,而是表示「文章(作者)的聯繫方式」,address 明確地只關聯到 article 和 body。
總結至此,我們可以回答是否要語義化的問題:我們應該分開一些場景來看語義,把它用在合適的場景下,可以獲得額外的效果。本篇文中,我們至少涉及了三個明確的場景:
自然語言表達能力的補充;
文章標題摘要;
適合機器閱讀的整體結構。
大家好我是落塵,希望我分享的文章大家能夠喜歡,也希望大家多多支持,多多轉發;小主們若是喜歡,就掃碼關注一下我,每天都會給大家分享好的文章;