次世代 Hugo

無駄を削ぎ、本質を研ぐ

Modern CSS Reset

Sam Xiao's Avatar 2025-07-22

不同瀏覽器對 HTML Tag 都有其預設 CSS Style,為了讓個瀏覽器表現一致,建議使用 CSS Reset 將所有預設 CSS Style 清除。

Version

CSS 3

Modern CSS Reset

/* Box sizing rules */
*,
*::before,
*::after {
  box-sizing: border-box;
}

/* Prevent font size inflation */
html {
  text-size-adjust: none;
}

/* Remove default margin in favour of better control in authored CSS */
body,
h1,
h2,
h3,
h4,
p,
figure,
blockquote,
dl,
dd {
  margin-block-end: 0;
}

/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */
ul,
ol {
  list-style: none;
}

/* Set core body defaults */
body {
  line-height: 1.5;
  min-height: 100vh;
}

/* Set shorter line heights on headings and interactive elements */
h1,
h2,
h3,
h4,
button,
input,
label {
  line-height: 1.1;
}

/* Balance text wrapping on headings */
h1,
h2,
h3,
h4 {
  text-wrap: balance;
}

/* A elements that don't have a class get default styles */
a:not([class]) {
  color: currentcolor;
  text-decoration-skip-ink: auto;
}

/* Make images easier to work with */
img,
picture {
  display: block;
  max-width: 100%;
}

/* Inherit fonts for inputs and buttons */
input,
button,
textarea,
select {
  font-size: inherit;
  font-family: inherit;
}

/* Make sure textareas without a rows attribute are not tiny */
textarea:not([rows]) {
  min-height: 10em;
}

/* Anything that has been anchored to should have extra scroll margin */
:target {
  scroll-margin-block: 5ex;
}
  • 簡單的 CSS reset

Line 1

/* Box sizing rules */
*,
*::before,
*::after {
  box-sizing: border-box;
}

是現代 CSS reset 中非常重要的一行,它的目的是讓元素的寬高行為更可預測、更好掌控:

  • *:所有 HTML 元素
  • *::before:所有 HTML 元素最前面的內容
  • *::after:所有 HTML 元素最後面的內容
  • box-sizing: border-box:使用 border-box 而非預設的 content-box

所有元素與它們的裝飾內容 before/after 在計算 寬高時,都要把 paddingborder 算進去,也就是我們 width 設定多少就是多少,不會再另外加上 paddingborder,這樣可以避免排版錯亂,是最基本的現代 reset 寫法之一

Line 8

/* Prevent font size inflation */
html {
  text-size-adjust: none;
}

用來控制瀏覽器是否允許 自動縮放文字大小 (特別是在行動裝置上):

  • html:在 <html> 標籤下所有元素
  • text-size-adjust: none:瀏覽器 不要 自動調整文字大小

有些手機裝置會根據使用者設定 如放大文字 強制放大部分網站的字體,若你在設計中已經明確設定字級比例與響應式排版,這個自動調整反而會 破壞設計

Line 13

/* Remove default margin in favour of better control in authored CSS */
body,
h1,
h2,
h3,
h4,
p,
figure,
blockquote,
dl,
dd {
  margin-block-end: 0;
}

用於取消這些元素底部的預設垂直間距:

  • margin-block-end: 0;:將部分 HTML 元素的 margin-bottom 設定為 0

為了支援 多語言 書寫方向,如 英文中文從上到下,而 阿拉伯文希伯來文 等可能是 從右到左 或其他方向,使用 margin-block-* 可以根據 書寫方向 自動適應,是更 語意化現代化 的寫法

Line 27

/* Remove list styles on ul, ol elements, which suggests default styling will be removed */
ul,
ol {
  list-style: none;
}

移除 <ul><ol> 元素的 預設 list 樣式 (例如圓點或編號):

  • list-style: none<ul><ol>純結構用,不需要預設樣式

Line 33

/* Set core body defaults */
body {
  line-height: 1.5;
  min-height: 100vh;
}

常見的基礎樣式設定:

  • line-height: 1.5:設定文字行距是字體大小的 1.5 倍,可以讓文字排版更易讀,避免文字太擠
  • min-height: 100vh:讓 <body>最小高度 等於 瀏覽器視窗高度

當頁面內容很少時 (例如只有一段文字),若不設 min-height: 100vh,整個 <body> 可能高度只有幾十像素,看起來像 空白破碎的頁面,設成 100vh,就能保證:即使內容很少,頁面也會占滿整個視窗高度

Line 39

/* Set shorter line heights on headings and interactive elements */
h1,
h2,
h3,
h4,
button,
input,
label {
  line-height: 1.1;
}

為特定元素設定 較緊密行高

  • h1h2h3h4:預設的標題行高常常 過高(有些瀏覽器預設為 1.35 ~ 1.5),標題通常是 單行文字(或只需 小行距),所以設定為 1.1 看起來更緊湊、俐落。特別是當字體大小很大時,過高的行距會導致段落看起來 鬆散
  • buttoninputlabel:這些元素預設 行高不一致,且在不同瀏覽器差異很大。統一設定 line-height: 1.1 可以讓它們的 垂直置中 與高度行為更一致。對於按鈕、輸入框的可點擊區域與排版高度更易掌控

Line 50

/* Balance text wrapping on headings */
h1,
h2,
h3,
h4 {
  text-wrap: balance;
}

讓標題文字在換行時變得更美觀、更平衡:

  • text-wrap: balance:讓多行文字 自動換行 時盡量 平均分配 字數與長度,避免出現像這樣的視覺破碎

這是 CSS 的一個新屬性 (在 2023 年後被 Chrome 和部分瀏覽器開始支援)

Line 58

/* A elements that don't have a class get default styles */
a:not([class]) {
  color: currentcolor;
  text-decoration-skip-ink: auto;
}

針對 未加 class 的連結 <a> 元素 做的樣式微調,具有良好的語意性與設計兼容性:

  • a:not([class]):選中所有沒有 class 屬性的 <a> 元素
  • color: currentcolorcurrentcolor 是一個 CSS 關鍵字,代表 目前文字顏色,讓 連結顏色 跟隨 父元素文字顏色 (不是預設藍色)
  • text-decoration-skip-ink: auto:讓 連結底線避開文字筆劃,讓底線更美觀、可讀性更高,如 g, y, p, j 等

Line 64

/* Make images easier to work with */
img,
picture {
  display: block;
  max-width: 100%;
}

針對圖片的排版表現進行最佳化設定:

  • img, picture:選取所有 <img> 以及 <picture> 標籤的元素
  • display: block:從預設 inline 改成 block
  • max-width: 100%:當圖片寬度超過容器寬度時,會自動縮小到容器寬度內,可避免圖片溢出、破版,使圖片具備響應式能力 (Responsive Images)
  • <img><picture> 預設為 inline,會像文字一樣排列,導致以下問題:
    • 圖片下方會出現多餘空隙 (因為文字 baseline 對齊)
    • 與周圍元素的排版對齊較難控制
  • 改成 block 後:
    • 圖片變成 區塊級元素,不再有 baseline 空隙
    • 更容易控制 marginpadding排版
    • 可避免圖片底下出現 奇怪的縫隙 (常發生在未加 reset 的頁面中)

Line 71

/* Inherit fonts for inputs and buttons */
input,
button,
textarea,
select {
  font-size: inherit;
  font-family: inherit;
}

針對 表單元素樣式一致性調整,目的是讓它們的 字體風格周圍一致,不被瀏覽器預設樣式干擾:

  • input, button, textarea, select:這四種都是常見的表單元件。各瀏覽器對它們預設的樣式 (尤其是字體) 差異非常大
  • font-size: inherit字體大小 繼承自 父元素,而不是使用瀏覽器 預設
  • font-family: inherit字體家族 繼承自 父元素,而不是使用瀏覽器 預設

某些瀏覽器 (特別是 iOS Safari) 會把 inputtextarea 預設設為 系統字體,導致整個頁面看起來不協調

Line 80

/* Make sure textareas without a rows attribute are not tiny */
textarea:not([rows]) {
  min-height: 10em;
}

<textarea>預設高度調整邏輯:

  • textarea:not([rows]):選取所有沒有設定 rows 屬性的 <textarea>
  • min-height: 10em:設定文字區域最小高度為 10em,意思是10 倍的字體高度,假設使用者字體大小為 16px,那就是:10em × 16px = 160px 高度

Line 85

/* Anything that has been anchored to should have extra scroll margin */
:target {
  scroll-margin-block: 5ex;
}

用來解決 滾動定位後目標元素被頂部遮住 的問題:

  • :target:CSS 選擇器,選中 URL 中 錨點指向元素
  • scroll-margin-block: 5ex:表示 當元素被捲動到畫面時,保留上方 (或下方,取決於書寫方向) 5ex 的空間,如避免錨點被 <header> 擋住

Conclusion

  • CSS 許多預設值並不完美,透過 CSS Reset 能讓 CSS 更合理

Reference

Andy Bell, A (More) Modern CSS Reset