HTML 規範
文檔類型
推薦使用 HTML5 的文檔類型申明: <!DOCTYPE html>
.javascript
(建議使用 text/html 格式的 HTML。避免使用 XHTML。XHTML 以及它的屬性,好比application/xhtml+xml
在瀏覽器中的應用支持與優化空間都十分有限)。css
HTML 中最好不要將無內容元素[1] 的標籤閉合,例如:使用 <br>
而非 <br />
.html
HTML 驗證
通常狀況下,建議使用能經過標準規範驗證的 HTML 代碼,除非在性能優化和控制文件大小上不得不作出讓步。java
使用諸如 W3C HTML validator 這樣的工具來進行檢測。git
規範化的 HTML 是顯現技術要求與侷限的顯著質量基線,它促進了 HTML 被更好地運用。web
不推薦canvas
- <title>Test</title>
- <article>This is only a test.
推薦瀏覽器
- <!DOCTYPE html>
- <meta charset="utf-8">
- <title>Test</title>
- <article>This is only a test.</article>
省略可選標籤
HTML5 規範中規定了 HTML 標籤是能夠省略的。但從可讀性來講,在開發的源文件中最好不要這樣作,由於省略標籤可能會致使一些問題。安全
省略一些可選的標籤確實使得頁面大小減小,這頗有用,尤爲是對於一些大型網站來講。爲了達到這一目的,咱們能夠在開發後期對頁面進行壓縮處理,在這個環節中這些可選的標籤徹底就能夠省略掉了。性能優化
腳本加載
出於性能考慮,腳本異步加載很關鍵。一段腳本放置在 <head>
內,好比<script src="main.js"></script>
,其加載會一直阻塞 DOM 解析,直至它徹底地加載和執行完畢。這會形成頁面顯示的延遲。特別是一些重量級的腳本,對用戶體驗來講那真是一個巨大的影響。
異步加載腳本可緩解這種性能影響。若是隻需兼容 IE10+,可將 HTML5 的 async 屬性加至腳本中,它可防止阻塞 DOM 的解析,甚至你能夠將腳本引用寫在 <head>
裏也沒有影響。
如需兼容老舊的瀏覽器,實踐代表可以使用用來動態注入腳本的腳本加載器。你能夠考慮 yepnope 或labjs。注入腳本的一個問題是:一直要等到 CSS 對象文檔已就緒,它們纔開始加載(短暫地在 CSS 加載完畢以後),這就對須要及時觸發的 JS 形成了必定的延遲,這多多少少也影響了用戶體驗吧。
終上所述,兼容老舊瀏覽器(IE9-)時,應該遵循如下最佳實踐。
腳本引用寫在 body 結束標籤以前,並帶上 async 屬性。這雖然在老舊瀏覽器中不會異步加載腳本,但它只阻塞了 body 結束標籤以前的 DOM 解析,這就大大下降了其阻塞影響。而在現代瀏覽器中,腳本將在 DOM 解析器發現 body 尾部的 script 標籤才進行加載,此時加載屬於異步加載,不會阻塞 CSSOM(但其執行仍發生在 CSSOM 以後)。
全部瀏覽器中,推薦
- <html>
- <head>
- <link rel="stylesheet" href="main.css">
- </head>
- <body>
- <!-- body goes here -->
-
- <script src="main.js" async></script>
- </body>
- </html>
只在現代瀏覽器中,推薦
- <html>
- <head>
- <link rel="stylesheet" href="main.css">
- <script src="main.js" async></script>
- </head>
- <body>
- <!-- body goes here -->
- </body>
- </html>
語義化
根據元素(有時被錯誤地稱做「標籤」)其被創造出來時的初始意義來使用它。打個比方,用 heading 元素來定義頭部標題,p 元素來定義文字段落,用 a 元素來定義連接錨點,等等。
有根據有目的地使用 HTML 元素,對於可訪問性、代碼重用、代碼效率來講意義重大。
如下示例列出了一些的語義化 HTML 主要狀況:
不推薦
- <b>My page title</b>
- <div class="top-navigation">
- <div class="nav-item"><a href="#home">Home</a></div>
- <div class="nav-item"><a href="#news">News</a></div>
- <div class="nav-item"><a href="#about">About</a></div>
- </div>
-
- <div class="news-page">
- <div class="page-section news">
- <div class="title">All news articles</div>
- <div class="news-article">
- <h2>Bad article</h2>
- <div class="intro">Introduction sub-title</div>
- <div class="content">This is a very bad example for HTML semantics</div>
- <div class="article-side-notes">I think I'm more on the side and should not receive the main credits</div>
- <div class="article-foot-notes">
- This article was created by David <div class="time">2014-01-01 00:00</div>
- </div>
- </div>
-
- <div class="section-footer">
- Related sections: Events, Public holidays
- </div>
- </div>
- </div>
-
- <div class="page-footer">
- Copyright 2014
- </div>
推薦
- <!-- The page header should go into a header element -->
- <header>
- <!-- As this title belongs to the page structure it's a heading and h1 should be used -->
- <h1>My page title</h1>
- </header>
-
- <!-- All navigation should go into a nav element -->
- <nav class="top-navigation">
- <!-- A listing of elements should always go to UL (OL for ordered listings) -->
- <ul>
- <li class="nav-item"><a href="#home">Home</a></li>
- <li class="nav-item"><a href="#news">News</a></li>
- <li class="nav-item"><a href="#about">About</a></li>
- </ul>
- </nav>
-
- <!-- The main part of the page should go into a main element (also use role="main" for accessibility) -->
- <main class="news-page" role="main">
- <!-- A section of a page should go into a section element. Divide a page into sections with semantic elements. -->
- <section class="page-section news">
- <!-- A section header should go into a section element -->
- <header>
- <!-- As a page section belongs to the page structure heading elements should be used (in this case h2) -->
- <h2 class="title">All news articles</h2>
- </header>
-
- <!-- If a section / module can be seen as an article (news article, blog entry, products teaser, any other
- re-usable module / section that can occur multiple times on a page) a article element should be used -->
- <article class="news-article">
- <!-- An article can contain a header that contains the summary / introduction information of the article -->
- <header>
- <!-- As a article title does not belong to the overall page structure there should not be any heading tag! -->
- <div class="article-title">Good article</div>
- <!-- Small can optionally be used to reduce importance -->
- <small class="intro">Introduction sub-title</small>
- </header>
-
- <!-- For the main content in a section or article there is no semantic element -->
- <div class="content">
- <p>This is a good example for HTML semantics</p>
- </div>
- <!-- For content that is represented as side note or less important information in a given context use aside -->
- <aside class="article-side-notes">
- <p>I think I'm more on the side and should not receive the main credits</p>
- </aside>
- <!-- Articles can also contain footers. If you have footnotes for an article place them into a footer element -->
- <footer class="article-foot-notes">
- <!-- The time element can be used to annotate a timestamp. Use the datetime attribute to specify ISO time
- while the actual text in the time element can also be more human readable / relative -->
- <p>This article was created by David <time datetime="2014-01-01 00:00" class="time">1 month ago</time></p>
- </footer>
- </article>
-
- <!-- In a section, footnotes or similar information can also go into a footer element -->
- <footer class="section-footer">
- <p>Related sections: Events, Public holidays</p>
- </footer>
- </section>
- </main>
-
- <!-- Your page footer should go into a global footer element -->
- <footer class="page-footer">
- Copyright 2014
- </footer>
多媒體回溯
對頁面上的媒體而言,像圖片、視頻、canvas 動畫等,要確保其有可替代的接入接口。圖片文件咱們可採用有意義的備選文本(alt),視頻和音頻文件咱們能夠爲其加上說明文字或字幕。
提供可替代內容對可用性來講十分重要。試想,一位盲人用戶如何能知曉一張圖片是什麼,要是沒有 @alt 的話。
(圖片的 alt 屬性是可不填寫內容的,純裝飾性的圖片就可用這麼作:alt=""
)。
不推薦
- <img src="luke-skywalker.jpg">
推薦
- <img src="luke-skywalker.jpg" alt="Luke skywalker riding an alien horse">
儘可能用 alt 標籤去描述圖片,設想你須要對於那些只能經過語音或者看不見圖片的用戶表達圖片究竟是什麼。
不推薦
- <img src="huge-spaceship-approaching-earth.jpg" alt="Header image">
推薦
- <img src="huge-spaceship-approaching-earth.jpg" alt="A huge spaceship that is approaching the earth">
關注點分離
理解 web 中如何和爲什麼區分不一樣的關注點,這很重要。這裏的關注點主要指的是:信息(HTML 結構)、外觀(CSS)和行爲(JavaScript)。爲了使它們成爲可維護的乾淨整潔的代碼,咱們要儘量的將它們分離開來。
嚴格地保證結構、表現、行爲三者分離,並儘可能使三者之間沒有太多的交互和聯繫。
就是說,儘可能在文檔和模板中只包含結構性的 HTML;而將全部表現代碼,移入樣式表中;將全部動做行爲,移入腳本之中。
在此以外,爲使得它們之間的聯繫儘量的小,在文檔和模板中也儘可能少地引入樣式和腳本文件。
清晰的分層意味着:
- 不使用超過一到兩張樣式表(i.e. main.css, vendor.css)
- 不使用超過一到兩個腳本(學會用合併腳本)
- 不使用行內樣式(
<style>.no-good {}</style>
)
- 不在元素上使用 style 屬性(
<hr style="border-top: 5px solid black">
)
- 不使用行內腳本(
<script>alert('no good')</script>
)
- 不使用表象元素(i.e.
<b>
, <u>
, <center>
, <font>
, <b>
)
- 不使用表象 class 名(i.e. red, left, center)
不推薦
- <!DOCTYPE html>
- <html>
- <head>
- <link rel="stylesheet" href="base.css">
- <link rel="stylesheet" href="grid.css">
- <link rel="stylesheet" href="type.css">
- <link rel="stylesheet" href="modules/teaser.css">
- </head>
- <body>
- <h1 style="font-size: 3rem"></h1>
- <b>I'm a subtitle and I'm bold!</b>
- <center>Dare you center me!</center>
- <script>
- alert('Just dont...');
- </script>
- <div class="red">I'm important!</div>
- </body>
- </html>
推薦
- <!DOCTYPE html>
- <html>
- <head>
- <!-- Concatinate your style sheets into a single one -->
- <link rel="stylesheet" href="main.css">
- </head>
- <body>
- <!-- Don't use style attributes but assign sensible classes and apply styles in the stylesheet -->
- <h1 class="title"></h1>
- <!-- Don't use presentational elements and assign sensible classes -->
- <div class="sub-title">I'm a subtitle and I'm bold!</div>
- <!-- Maybe your comments get centered in your presentation but that decision is up to the stylesheet -->
- <span class="comment">Dare you center me!</span>
- <!-- You wanted to make it red because it's important so then also name the class important and decide in the stylesheet
- what you want to do with it -->
- <div class="important">I'm important!</div>
-
- <!-- Put all your scripts into files and concatinate them into a single one -->
- <script async src="main.js"></script>
- </body>
- </html>
HTML 內容至上
不要讓非內容信息污染了你的 HTML。如今貌似有一種傾向:經過 HTML 來解決設計問題,這是顯然是不對的。HTML 就應該只關注內容。
HTML 標籤的目的,就是爲了避免斷地展現內容信息。
- 不要引入一些特定的 HTML 結構來解決一些視覺設計問題
- 不要將
img
元素當作專門用來作視覺設計的元素
如下例子展現了誤將 HTML 用來解決設計問題的這兩種狀況:
不推薦
- <!-- We should not introduce an additional element just to solve a design problem -->
- <span class="text-box">
- <span class="square"></span>
- See the square next to me?
- </span>
- .text-box > .square {
- display: inline-block;
- width: 1rem;
- height: 1rem;
- background-color: red;
- }
推薦
- <!-- That's clean markup! -->
- <span class="text-box">
- See the square next to me?
- </span>
- /* We use a :before pseudo element to solve the design problem of placing a colored square in front of the text content */
- .text-box:before {
- content: "";
- display: inline-block;
- width: 1rem;
- height: 1rem;
- background-color: red;
- }
圖片和 SVG 圖形能被引入到 HTML 中的惟一理由是它們呈現出了與內容相關的一些信息。
不推薦
- <!-- Content images should never be used for design elements! -->
- <span class="text-box">
- <img src="square.svg" alt="Square" />
- See the square next to me?
- </span>
推薦
- <!-- That's clean markup! -->
- <span class="text-box">
- See the square next to me?
- </span>
- /* We use a :before pseudo element with a background image to solve the problem */
- .text-box:before {
- content: "";
- display: inline-block;
- width: 1rem;
- height: 1rem;
- background: url(square.svg) no-repeat;
- background-size: 100%;
- }
Type 屬性
省略樣式表與腳本上的 type 屬性。鑑於 HTML5 中以上二者默認的 type 值就是 text/css 和 text/javascript,因此 type 屬性通常是能夠忽略掉的。甚至在老舊版本的瀏覽器中這麼作也是安全可靠的。
不推薦
- <link rel="stylesheet" href="main.css" type="text/css">
- <script src="main.js" type="text/javascript"></script>
推薦
- <link rel="stylesheet" href="main.css">
- <script src="main.js"></script>
可用性
若是 HTML5 語義化標籤使用得當,許多可用性問題已經引刃而解。ARIA 規則在一些語義化的元素上可爲其添上默認的可用性角色屬性,使用得當的話已使網站的可用性大部分紅立。假如你使用 nav
, aside
,main
, footer
等元素,ARIA 規則會在其上應用一些關聯的默認值。
更多細節可參考 ARIA specification
另一些角色屬性則可以用來呈現更多可用性情景(i.e. role="tab"
)。
Tab Index 在可用性上的運用
檢查文檔中的 tab 切換順序並傳值給元素上的 tabindex,這能夠依據元素的重要性來從新排列其 tab 切換順序。你能夠設置 tabindex="-1"
在任何元素上來禁用其 tab 切換。
當你在一個默認不可聚焦的元素上增長了功能,你應該老是爲其加上 tabindex
屬性使其變爲可聚焦狀態,並且這也會激活其 CSS 的僞類 :focus
。選擇合適的 tabindex
值,或是直接使用 tabindex="0"
將元素們組織成同一 tab 順序水平,並強制干預其天然閱讀順序。
微格式在 SEO 和可用性上的運用
若是 SEO 和可用性環境條件容許的話,建議考慮採用微格式。微格式是經過在元素標籤上申明一系列特定數據來達成特定語義的方法。
谷歌、微軟和雅虎對如何使用這些額外的數據必定程度上的達成一致,若是正確的使用,這將給搜索引擎優化帶來巨大的好處。
你能夠訪問 schema.org 得到更多內容細節。
看一個電影網站的簡單例子:
不帶微格式
- <div>
- <h1>Avatar</h1>
- <span>Director: James Cameron (born August 16, 1954)</span>
- <span>Science fiction</span>
- <a href="../movies/avatar-theatrical-trailer.html">Trailer</a>
- </div>
帶有微格式
- <div itemscope itemtype ="http://schema.org/Movie">
- <h1 itemprop="name">Avatar</h1>
- <div itemprop="director" itemscope itemtype="http://schema.org/Person">
- Director: <span itemprop="name">James Cameron</span> (born <span itemprop="birthDate">August 16, 1954)</span>
- </div>
- <span itemprop="genre">Science fiction</span>
- <a href="../movies/avatar-theatrical-trailer.html" itemprop="trailer">Trailer</a>
- </div>
ID 和錨點
一般一個比較好的作法是將頁面內全部的頭部標題元素都加上 ID. 這樣作,頁面 URL 的 hash 中帶上對應的 ID 名稱,即造成描點,方便跳轉至對應元素所處位置。
打個比方,當你在瀏覽器中輸入 URL http://your-site.com/about#best-practices
,瀏覽器將定位至如下 H3 上。
- <h3 id="best-practices">Best practices</h3>
格式化規則
在每個塊狀元素,列表元素和表格元素後,加上一新空白行,並對其子孫元素進行縮進。內聯元素寫在一行內,塊狀元素還有列表和表格要另起一行。
(若是因爲換行的空格引起了不可預計的問題,那將全部元素併入一行也是能夠接受的,格式警告總好過錯誤警告)。
推薦
- <blockquote>
- <p><em>Space</em>, the final frontier.</p>
- </blockquote>
-
- <ul>
- <li>Moe</li>
- <li>Larry</li>
- <li>Curly</li>
- </ul>
-
- <table>
- <thead>
- <tr>
- <th scope="col">Income</th>
- <th scope="col">Taxes</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>$ 5.00</td>
- <td>$ 4.50</td>
- </tr>
- </tbody>
- </table>
HTML 引號
使用雙引號(「」) 而不是單引號(」) 。
不推薦
- <div class='news-article'></div>
推薦
- <div class="news-article"></div>
[1]: 此處的空白元素指的是如下元素:area
, base
, br
, col
, command
, embed
, hr
, img
, input
, keygen
,link
, meta
, param
, source
, track
, wbr