﻿# 網站建置不是件簡單的事 @ 跨瀏覽器網頁設計密技 (1)

自從上次發表【[網站建置不是件簡單的事 @ 打造網站的步驟](/post/2011/09/28/Building-Website-is-not-that-easy-the-SOP.aspx)】之後收到許多網友熱烈的迴響，因此萌生撰寫系列文章的想法，為了要延續【網站建置不是件簡單的事】系列，我想對設計師來說最痛苦的事莫過於**跨瀏覽器網頁設計**，我們通常在設計好網頁後，會進入「跨瀏覽器相容性測試」的步驟，這時幾乎 100% 都會遇到網頁相容性的問題，同一份網頁在不同瀏覽器裡顯示時多少都會有些差異，接下來的文章就是分享一些我們經常使用的跨瀏覽器網頁設計技巧，礙於篇幅考量，我會依據不同主題拆成多篇文章撰寫。

在本期文章中，我會先介紹 3 種不同的開發技巧，分別為：

1.  使用 DOCTYPE
2.  使用 CSS Reset
3.  使用 CSS Normalize

**(1) 使用 DOCTYPE**

微軟在 2001 年推出 Internet Explorer 6 瀏覽器，這個版本開始利用 DOCTYPE 區別「標準模式」與「相容模式」的網頁。我們可以說 IE 5.5 版本以前的瀏覽器呈現網頁的方式都統一稱為「相容模式」，而這種顯示模式的缺點就在於「沒有標準」，瀏覽器會用早期自訂的 HTML / CSS 規格來呈現網頁，並完全忽略 W3C 所規範的那些標準，如果你還在使用早期的 <TABLE> 排版方式，或許不會感受其差異，但如果你開始使用 DIV + CSS 等方式來排版網頁，就會感受到非常大的差別。

在 HTML 4.01 裡，<!DOCTYPE> 定義了三種標準模式：

**1\. 嚴格標準模式 ( HTML 4 Strict )**

在網頁的第一行宣告以下 DOCTYPE 會引導瀏覽器以「**嚴格標準模式**」顯示網頁：

```
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"        "http://www.w3.org/TR/html4/strict.dtd">
```

這意味著只要你在網頁中使用了 HTML 4.01 不支援的**標籤**或**屬性**，瀏覽器都會自動忽略其功能。例如：框架 (Frame) 功能將無法在這類網頁中使用，或是超連結 ( <A> ) 的 target 屬性也無法使用。

一般來說，網頁設計師通常不會選用這種模式來設計網頁。

**2\. 近似標準模式 ( HTML 4 Transitional )**

在網頁的第一行宣告以下 DOCTYPE 會引導瀏覽器以「**近似標準模式**」顯示網頁：

```
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"        "http://www.w3.org/TR/html4/loose.dtd">
```

在此模式下顯示網頁，會預設支援完整的 HTML 4.01 標籤與屬性，並且也會支援舊版 HTML 規格的標籤與屬性，不過這個版本依然不支援框架功能的使用！

這種模式也是最多網頁設計師採用的版本。

補充：由於 **近似標準模式** ( HTML 4 Transitional ) 不支援網頁框架 (Frame) 功能，以前最常看到網頁設計師因為在網頁中使用了框架卻怎樣都無法顯示出來而苦惱，最後把 DOCTYPE 移除掉後才能顯示出框架網頁，還因此認為 DOCTYPE 是個惡魔，覺得這東西少用為妙，這些都是錯誤的觀念。事實上，你只要將網頁的 DOCTYPE 切換成即將介紹的 **近似標準但支援框架模式** ( HTML 4 Frameset ) 即可！

**3\. 近似標準但支援框架模式 ( HTML 4 Frameset )**

在網頁的第一行宣告以下 DOCTYPE 會引導瀏覽器以「**近似標準但支援框架模式**」顯示網頁：

```
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"        "http://www.w3.org/TR/html4/frameset.dtd">
```

此模式與 **近似標準模式** ( HTML 4 Transitional ) 一模一樣，差別僅在於額外支援了框架相關的支援。

瞭解了以上三種網頁顯示模式對設計出跨瀏覽器的網頁十分重要，網頁設計師想要利用 CSS 設計出具有編排彈性又能夠跨瀏覽器顯示的網頁，必須要求瀏覽器使用「標準模式」來顯示網頁，否則網頁怎樣排版都不可能編排到一致的。

參考連結：

-   [The global structure of an HTML document](http://www.w3.org/TR/html4/struct/global.html)

**(2) 使用 CSS Reset**

在 W3C 制訂 HTML 與 CSS 規格時，並沒有強制規定各家瀏覽器應該怎樣實作每一個 HTML 標籤 (HTML Tag) 的 CSS 預設樣式為何，即便在 CSS 2.1 規格裡有提到 [Appendix D. Default style sheet for HTML 4](http://www.w3.org/TR/CSS2/sample.html)，但這裡也只是提供一個資訊參考的範例而已，並沒有強制瀏覽器應該怎樣實作標籤的預設樣式。另一方面來說，W3C 的規格也不應該定義這麼嚴格，因為瀏覽器可能會被安裝在各種螢幕大小或各式不同的作業系統平台上，若規定的太過死板，也會嚴重影響呈現網頁的彈性。

實務上來說，各家瀏覽器也的確設計出了彼此不相容的標籤預設樣式，例如不同標籤的 **外距** (margin)、**內距** (padding) 或 **字體大小** (font-size) 等，還有許多其他標籤也都存在著些微差異，有時候網頁設計師在調整這些差異時，因為要處理的瀏覽器版本太多，不但調到心生怨念，甚至還會抓狂痛哭。

因為這樣的問題，在網頁設計的領域中發展出一種稱為 CSS Reset 或 Reset CSS 的設計方法，你只要完整定義出一組可以覆蓋所有 HTML 標籤的 CSS 樣式表，把所有可能造成瀏覽器差異的樣式都定義出來，當成你網頁設計的樣式基礎，再從這個基礎上發展你所設計網站的樣式表，那麼就不會再發生特定標籤在不同瀏覽器有不一致的情況，也為你的「跨瀏覽器網頁設計」打下一個穩固的根基。

以下是 [Eric A. Meyer](http://meyerweb.com/eric/) 的 CSS Reset 版本（也許是最多人用的一份）：

```css
/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
	display: block;
}
body {
	line-height: 1;
}
ol, ul {
	list-style: none;
}
blockquote, q {
	quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
	content: '';
	content: none;
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}
```

基本上你也可以自行定義一份 CSS Reset 樣式，許多大型網站都是自行定義的，不過對於廣大網頁設計師來說，自行定義比較不符合成本，也不容易定義出完整的 CSS Reset 樣式組合，因此大多數人都會直接從網路上下載現成的 CSS Reset 版本，但是網路上的 CSS Reset 版本非常多，而且其設計的邏輯多少都會有些許差異，因此各版本之間是不太相容的。

由於使用 CSS Reset 的主要目的是為了替你的「跨瀏覽器網頁設計」打下一個穩固的根基，那麼這個根基就必須十分牢固，不可任意變動，否則影響到的將會是你整個網站的樣式。但是，網路上有些特定的 CSS Reset 版本會與特定 CSS Framework 或 JavaScript Framework 緊密的綁在一起，如果不小心混用的話，就會導致網頁上出現一些不必要的版面問題。尤其是你在一個網頁裡用了兩套以上不同的 CSS Framework 會更容易遇到這個問題。

舉個例子來說，如果今天你在網頁裡使用的是由 [Eric A. Meyer](http://meyerweb.com/eric/) 所設計的 [CSS Reset](http://meyerweb.com/eric/tools/css/reset/) 版本 (註：這是目前最被廣泛使用的 CSS Reset 版本)，而你的整個網站都是基於這個版本來設計 CSS 樣式，這時如果你載入其他現成的 UI 框架來使用（例如 [jQuery UI](http://jqueryui.com/) 這類的框架），就有可能導致這些透過 UI 框架輸出的樣式出現了些微改變 (例如多一條莫名的白線，或是整個版面跑掉等等)，遇到這種情況是十分棘手的。

還好，目前市面上那些能說得出名稱的 UI 框架，都對這類 CSS Reset 互相影響的情況做出了處理，也都有解決方法，各位詳讀這些 UI 框架的注意事項即可瞭解如何避免此類問題發生。

以下推薦幾套常用的 CSS Reset 版本給各位參考運用：

-   [CSS Tools: Reset CSS](http://meyerweb.com/eric/tools/css/reset/) \[ [直接下載](http://meyerweb.com/eric/tools/css/reset/reset.css) \]  
    目前最被廣泛使用的 CSS Reset 版本，由 Eric A. Meyer 所設計，支援 HTML5 語意標籤。
-   [HTML5 Reset Stylesheet | HTML5 Doctor](http://html5doctor.com/html-5-reset-stylesheet/)  
    這是 HTML5 Doctor 網站修改字 Eric A. Meyer 的版本。
-   [CSS Reset - YUI Library](http://yuilibrary.com/yui/docs/cssreset/)  
    由 Yahoo UI Library v3 所提供的 CSS Reset 版本。

其他與 CSS Reset 相關的參考連結如下：

-   [CSS Reset 是什麼? 能吃嗎?](http://blog.darkthread.net/post-2011-07-22-css-reset.aspx)
-   CSS Tip #1: Resetting Your Styles with CSS Reset

**(3) 使用 CSS Normalize**

如果你有看過 CSS Reset 的內容，你將會發現他基本上把所有標籤的預設樣式都歸 0，尤其是針對 margin, padding, border 這幾個樣式屬性，這樣的缺點在於套用 CSS Reset 上去之後，幾乎大部分的標籤，尤其是常用的 ol, ul, li 等標籤，就必須特別再定義過才能正常運作，否則就會導致預設的 HTML 結構呈現在頁面上時無法正常閱讀。

有別於 CSS Reset 的強勢作風，也有人開發出另一種 [CSS Normalize](https://necolas.github.io/normalize.css/) 版本，這類的 CSS 樣式表有個很大的特色就是保留原本預設 HTML 標籤的樣式，僅針對不同瀏覽器與各版本間不相容的標籤進行些微調整，盡量讓預設 HTML 標籤的樣式可以在各以在瀏覽器版本間擁有一致的呈現，如此一來，你就算使用預設標籤也能夠撰寫基本網頁，針對需要特殊處理的 HTML 定義不同的 CSS 即可。

目前在 Github 上有個 [normalize.css](https://github.com/necolas/normalize.css) 版本，它的 CSS Normalize 針對 HTML5 標籤進行設計，你可以同時運用在 HTML 4 與 HTML5 的網頁上，不失為有別於 CSS Reset 的好選擇。不過也請記得，CSS Normalize 與 CSS Reset 混合使用並沒什麼意義喔，二擇一即可。

參考連結：

-   [Normalize.css: Make browsers render all elements more consistently](https://necolas.github.io/normalize.css/)
-   [Normalize.css docs](https://github.com/necolas/normalize.css/wiki)
-   [What is the different between Normalize.css and Reset CSS?](http://stackoverflow.com/questions/6887336/what-is-the-different-between-normalize-css-and-reset-css)

**總結**

今天介紹的幾個觀念與技巧，是成為專業網頁設計師的必要條件，為了讓你的網頁能完美的呈現在使用者面前，你必須考量到各瀏覽器的特性，想做到這一點，你必須先養成使用 W3C 標準開發網頁的習慣，而使用 <!DOCTYPE> 則是養成習慣的第一步，瞭解了 <!DOCTYPE> 對瀏覽器顯示網頁的影響後，才能真正擁抱 W3C 標準，逐步提升網頁設計的專業技能。

使用 CSS 排版網頁，需為你的「跨瀏覽器網頁設計」打下一個穩固的根基，你必須選用一個標準的 CSS Reset 或 CSS Normalize 樣式，然後再基於這個樣式設計出整個網站所需的 CSS 樣式表，這樣才能確保你所設計的 CSS 樣式能一致的呈現在不同瀏覽器上。然而，使用 CSS Reset/Normalize 樣式必須注意與其他 UI 框架的相容性問題，如真有衝突發生，你可以選擇用其他 UI 框架，或是使用特定 UI 框架的標準作法來避免衝突，千萬不可修改當初採用的 CSS Reset/Normalize 版本，否則很有可能影響到整個網站的樣式設計，反而得不償失。
