# CSS Reset
###### tags: `HTML&CSS`
W3C 協會在制訂 HTML 與 CSS 網頁設計標準時,針對不同的 HTML 標籤都會有預設的 CSS 樣式設定,例如預設的字體大小、margin、padding 等等。
但 W3C 只有提供參考[範例](https://www.w3.org/TR/CSS2/sample.html),並沒有強制規定不同瀏覽器使用一致的 CSS 樣式。在瀏覽器百家爭鳴的背景下,開發者經常遇到不同瀏覽器(例如 IE、firefox、chrome、Safari...)各自帶有不同的 CSS 預設值,導致他們難以確保網頁在各種瀏覽器上都能呈現一致地樣式,需要花費許多心力針對每個瀏覽器做調整。
知名的 CSS 大師 Eric Meyer 在 2017 年提出了 CSS reset 的概念,目的就是為了解決不同瀏覽器之間的預設樣式差異,以確保網頁在各種瀏覽器上都能呈現一致的外觀。
## 使用 CSS reset 的好處
- 確保跨瀏覽器的一致性
- 簡化 CSS 開發過程
## 不同版本的 CSS Reset
根據作者不同的開發需求與偏好,也出現了許多不同的 CSS reset 版本。最常見的版本包括這兩種:
- [Reset CSS](https://meyerweb.com/eric/tools/css/reset/) - Eric Meyer 版本
- [Normalize.css](https://nicolasgallagher.com/about-normalize-css/) - Nicolas Gallagher 版本
除此之外也還有許多其他不同版本的 CSS reset 工具,也有基於上述版本再做調整的版本。要選用哪一個 CSS reset 版本並沒有絕對的答案,取決於設計、開發的需求、個人與開發團隊的偏好,
## Reset CSS
https://meyerweb.com/eric/tools/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;
}
```
可以看到 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 的官方頁面](https://nicolasgallagher.com/about-normalize-css/)提到它的目標是:
- 保留有用的瀏覽器預設樣式,而不是清除它們
- 為廣泛的 HTML 元素提供樣式規範
- 修正 bug 與瀏覽器的不一致
- 透過一些微調來提升可用性
- 使用註解以及詳細的文件來解釋程式碼
### 保留預設樣式
它將 HTML5 元素引入到一致的樣式基礎上,並提供一些微調,以確保不同瀏覽器與版本之間都能呈現一致的外觀。
上面提到 Meyer 版本的 Reset CSS 清除了所有字體的樣式,但在 Normailize.css 版本則可以看到 `h1~h6` 則保留了預設樣式。另外詳細比較會發現每個瀏覽器的 body 邊距都不同,因此它也將 body 的 margin 統一設為 0。
```css
/**
* Remove the margin in all browsers.
*/
body {
margin: 0;
}
```
### 文件保有清楚的註解
在官方的 GitHub 上都有詳細的 [README](https://github.com/necolas/normalize.css/) 可以閱讀。此外,每一個 CSS 樣式設定都會加上註解來說明是要解決什麼問題。在它的 [CSS 文件](https://github.com/necolas/normalize.css/blob/master/normalize.css)上就能看到所有的註解。
與 Reset CSS 相比,Normalize.css 是個持續有在優化的專案,也被廣泛使用在許多知名的網站以及框架上,像是 [Bootstrap](https://getbootstrap.com/docs/3.4/css/#overview-normalize)、[CSS tricks](https://css-tricks.com/)、[GitHub](https://github.com/);另外也有針對 Normalize.css 微調的版本像是 Tailwind CSS 所使用的 [modern-normalize](https://github.com/sindresorhus/modern-normalize)。
## 在 Codepen 上設置 CSS reset
Codepen 的 CSS 設定裡,提供了三種樣式可勾選:
- Normalize:使用 Normalize.css 版本
- Reset:使用 Meyer 的 Reset CSS 版本
- Neiter:使用瀏覽器預設的版本

## 其他常用的 CSS 重置樣式
在開發的時候除了使用 CSS reset 工具之外,也經常會手動設定一些常用的樣式,來確保網頁的外觀呈現符合預期。
### box-sizing
CSS 中 `box-sizing` 的初始值為 `content-box`(元素本身的寬度和高度),如果又在該元素設定了 border 或是 padding,會讓元素在視覺上看起來變大了。設定 `box-sizing: border-box;` 可以確保元素的寬度和高度包含了 border 與 padding,讓元素符合預期的寬高。
```css
/* 全站適用 */
*,*::before,*::after{
box-sizing: border-box;
}
```
關於盒模型(box model)的說明可以進一步參考:[CSS 盒模型 Box Model](/xK3ffUwbQHyzKvxgU0vF4A)
### img 消除多餘空白
CSS 中 `img` 預設都會有 3px 的 margin。
開發上也經常會設定以下的 CSS 樣式,來消除 img 下方的多餘空白:
```css
img {
display: block;
}
/* OR */
img {
vertical-align: middle;
}
```
### a 連結的樣式
實務上常將 `<a>` 標籤改為 `display:block;` ,方便點擊
```css
a {
display: block;
}
```
另外,我們也會希望先定義好連結的樣式,及在不同狀態下呈現不同樣式:
```css
a {
text-decoration: none;
color: #007bff;
}
a:hover {
text-decoration: underline;
}
a:visited {
color: purple;
}
```