Try   HackMD

CSS Reset

tags: HTML&CSS

W3C 協會在制訂 HTML 與 CSS 網頁設計標準時,針對不同的 HTML 標籤都會有預設的 CSS 樣式設定,例如預設的字體大小、margin、padding 等等。

但 W3C 只有提供參考範例,並沒有強制規定不同瀏覽器使用一致的 CSS 樣式。在瀏覽器百家爭鳴的背景下,開發者經常遇到不同瀏覽器(例如 IE、firefox、chrome、Safari)各自帶有不同的 CSS 預設值,導致他們難以確保網頁在各種瀏覽器上都能呈現一致地樣式,需要花費許多心力針對每個瀏覽器做調整。

知名的 CSS 大師 Eric Meyer 在 2017 年提出了 CSS reset 的概念,目的就是為了解決不同瀏覽器之間的預設樣式差異,以確保網頁在各種瀏覽器上都能呈現一致的外觀。

使用 CSS reset 的好處

  • 確保跨瀏覽器的一致性
  • 簡化 CSS 開發過程

不同版本的 CSS Reset

根據作者不同的開發需求與偏好,也出現了許多不同的 CSS reset 版本。最常見的版本包括這兩種:

除此之外也還有許多其他不同版本的 CSS reset 工具,也有基於上述版本再做調整的版本。要選用哪一個 CSS reset 版本並沒有絕對的答案,取決於設計、開發的需求、個人與開發團隊的偏好,

Reset CSS

https://meyerweb.com/eric/tools/css/reset/

/* 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;
}

可以看到 Erice Meyer 版本的 Reset CSS 將大多數不一致的地方都重置了,例如:

  • margin、padding、border、outline、列表樣式直接通通都歸零
  • 文字大小都設置成 font-size: 100%;
  • 行高統一設置成 line-height: 1;

優點是重置了所有不一致的樣式,缺點是重置後需要再重新定義所有元素的樣式。

雖然這個版本解決了樣式不統一的問題,但有時候我們仍然希望一些有用的、常用的 HTML 標籤能保有一些預設的樣式。例如 <ol><li>的預設項目符號樣式、<h1>~<h6>預設的字體大小與行高設定,於是又有了 Normalize.css。

Normalize.css

https://nicolasgallagher.com/about-normalize-css/

Normalize.css 的目標是在保留有用的預設樣式的同時,解決不同瀏覽器與各版本之間不一致的標籤樣式。

The aims of normalize.css are as follows:

  • Preserve useful browser defaults rather than erasing them.
  • Normalize styles for a wide range of HTML elements.
  • Correct bugs and common browser inconsistencies.
  • Improve usability with subtle improvements.
  • Explain the code using comments and detailed documentation.

Normalize.css 的官方頁面提到它的目標是:

  • 保留有用的瀏覽器預設樣式,而不是清除它們
  • 為廣泛的 HTML 元素提供樣式規範
  • 修正 bug 與瀏覽器的不一致
  • 透過一些微調來提升可用性
  • 使用註解以及詳細的文件來解釋程式碼

保留預設樣式

它將 HTML5 元素引入到一致的樣式基礎上,並提供一些微調,以確保不同瀏覽器與版本之間都能呈現一致的外觀。

上面提到 Meyer 版本的 Reset CSS 清除了所有字體的樣式,但在 Normailize.css 版本則可以看到 h1~h6 則保留了預設樣式。另外詳細比較會發現每個瀏覽器的 body 邊距都不同,因此它也將 body 的 margin 統一設為 0。

/**
 * Remove the margin in all browsers.
 */

body {
  margin: 0;
}

文件保有清楚的註解

在官方的 GitHub 上都有詳細的 README 可以閱讀。此外,每一個 CSS 樣式設定都會加上註解來說明是要解決什麼問題。在它的 CSS 文件上就能看到所有的註解。

與 Reset CSS 相比,Normalize.css 是個持續有在優化的專案,也被廣泛使用在許多知名的網站以及框架上,像是 BootstrapCSS tricksGitHub;另外也有針對 Normalize.css 微調的版本像是 Tailwind CSS 所使用的 modern-normalize

在 Codepen 上設置 CSS reset

Codepen 的 CSS 設定裡,提供了三種樣式可勾選:

  • Normalize:使用 Normalize.css 版本
  • Reset:使用 Meyer 的 Reset CSS 版本
  • Neiter:使用瀏覽器預設的版本

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

其他常用的 CSS 重置樣式

在開發的時候除了使用 CSS reset 工具之外,也經常會手動設定一些常用的樣式,來確保網頁的外觀呈現符合預期。

box-sizing

CSS 中 box-sizing 的初始值為 content-box(元素本身的寬度和高度),如果又在該元素設定了 border 或是 padding,會讓元素在視覺上看起來變大了。設定 box-sizing: border-box; 可以確保元素的寬度和高度包含了 border 與 padding,讓元素符合預期的寬高。

/* 全站適用 */
*,*::before,*::after{
  box-sizing: border-box;
}

關於盒模型(box model)的說明可以進一步參考:CSS 盒模型 Box Model

img 消除多餘空白

CSS 中 img 預設都會有 3px 的 margin。

開發上也經常會設定以下的 CSS 樣式,來消除 img 下方的多餘空白:

img {
    display: block;
}

/* OR */

img {
    vertical-align: middle;
}

a 連結的樣式

實務上常將 <a> 標籤改為 display:block; ,方便點擊

a {
    display: block;
}

另外,我們也會希望先定義好連結的樣式,及在不同狀態下呈現不同樣式:

a {
  text-decoration: none;
  color: #007bff;
}

a:hover {
  text-decoration: underline;
}

a:visited {
  color: purple;
}