Community程式設計與開發github.com

jakubkrehel/better-typography

專注於字級、間距、字體大小、可變字型、OpenType 功能、換行、截斷以及其他能讓產品排版更出色的細節。

better-typography 是什麼?

這個技能(Skill)提供一套嚴謹且實用的 CSS 排版最佳實踐,幫助開發者或 AI 助手處理文字渲染、換行與行為控制。它涵蓋了從字型格式選擇(如 .woff2)、使用 CSS 屬性而非原始標籤(如 font-weight 取代 font-variation-settings)、到設計字級比例與語義化命名、行高與字距的調整(如標題使用 1.1,內文使用 1.5–1.6)。 技能特別強調「精準換行」:透過 text-wrap: balance(均衡分佈)、text-wrap: pretty(避免孤兒字)、overflow-wrap: break-word(強制斷行)與 white-space: nowrap(防止斷行)來優化排版。此外還包含響應式輸入框字型大小(16px 以防止 iOS 縮放)、底線設定(from-font 指標)、智慧標點(彎引號、en dash、單一字元的省略號)以及使用者選擇性(user-select: none)的正確用法。 此技能支援多種平台(如 Claude Code、Cursor、Codex),通過提供具體的 CSS 值、Tailwind 等效對照(於 css-cheat-sheet.md)以及衝突檢查表(如子標題不應壓過父標題),確保排版在各產品間保持一致且易於維護。最後,它定義了報告格式(HIGH/MEDIUM/LOW 嚴重性)與通過/阻擋條件,以便在審查中系統化地驗證與溝通排版問題。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/jakubkrehel/skills/tree/main/skills/better-typography

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

排版

排版大多意味著克制:適當的字級比例、舒適的間距、足夠的對比。標籤、表格儲存格、行銷標題與文章段落並不共用同一套規則。

審查時,請閱讀渲染後的頁面,而非掃描程式碼。不良的換行、孤兒字與截斷只會在實際內容長度下顯現。

所有修正都應使用專案的樣式系統,並使用下列確切數值,而非看似相似的等價物。速查表將每個宣告對應到其 Tailwind 等效值。

文字本身屬於 better-writing。語義化的標題結構屬於 better-accessibility。空間性的 RTL 佈局與邏輯屬性屬於 better-layout。對比測量屬於 better-colors。這個技能負責的是文字如何渲染、換行以及在混合方向內容中的行為。

提供正確的格式

在網頁上使用 .woff2,以獲得 Brotli 壓縮與廣泛支援。.woff 是針對非常老舊瀏覽器的備用方案。.ttf 與 .otf 是桌面格式,沒有網頁壓縮。檔案如何載入是專案自身的考量。

使用屬性而非原始標籤

當 CSS 屬性存在時,請使用它。使用 font-weight: 650 而非 font-variation-settings: "wght" 650。使用 font-optical-sizing: auto 而非 "opsz"。使用 font-variant-numeric: tabular-nums 而非 font-feature-settings: "tnum" 1。

屬性在非可變字型後備渲染時仍能持續運作。保留原始標籤給自定義軸線(例如 "GRAD" 80)與沒有對應屬性的特殊功能(例如 "ss01" 1)。軸線與功能標籤列在 variable-fonts-and-opentype.md。

載入預期的字重與樣式

瀏覽器會合成啟用字型家族未提供的字重或樣式,從而扭曲真實的字體。請載入設計所使用的字體。

font-synthesis: none 會關閉合成,但它會抹去強調效果而非報告問題。請務必在確認每個所需的粗體、斜體、小型大寫、上標與下標形式在後備堆疊中保持可區分後,才設定此屬性。

減少字型、尺寸與字重的數量

很少使用超過三種字型。字重與尺寸定義層級;過度使用會迅速傷害可讀性。為了對比而配對,而非為了相似:襯線標題搭配無襯線內文看起來是有意的,而兩個幾乎相同的無襯線字型則看起來像是錯誤。

在 18px 以下,請保持字重為 400 或更重。低於 300 的字重僅在 28px 以上時用於顯示用途;它們在文字尺寸下會消失。字型配對指南在 choosing-fonts.md。

使用帶有語義名稱的字級比例

定義一組少量的尺寸,並盡可能不偏離它。沒有背後系統的硬編碼尺寸在規模擴大時會失效。

像是 text-sm 這種獨立、預設的名稱,在使用規則明確時是可行的。在團隊中,請按用途命名尺寸(例如 text-body-sm),這樣規則才能經得起他人接手。比例建構在 spacing-and-sizing.md。

標題尺寸隨層級遞減

將標題層級對應到字級比例中遞減的步驟,使得視覺上較低階的標題永遠不會壓過其父層。相鄰層級在比例的小尺寸端可以共用一個尺寸,只要字重或間距能讓它們保持可區分。語義元素屬於 better-accessibility;此技能僅設定視覺處理方式。

依角色設定行高

標題較緊湊,約 1.1。內文 1.5 到 1.6。偏好使用無單位數值,這樣行高會隨字型大小縮放;固定的 24px 則不會。

緊湊的行高適用於短文字。任何換行到三行或以上的文字至少需要 1.4,即使在高度受限的行中也是如此。

依尺寸設定字距

大型標題通常看起來略帶負字距會更好。小型大寫標籤需要一點正字距,否則字母會感覺擁擠。閱讀尺寸的內文則兩者都不需要。

限制行長

過長的行列讓眼睛難以找到下一行。將長篇文字的行長限制在大約每行 60–75 個字符。任何單位都可以,只要存在一個上限且行長落在範圍內。請參閱 單位選擇與像素等價值。

有目的地換行

四個宣告,四個職責:

  • text-wrap: balance 將文字均勻分佈到各行。用於標題。
  • text-wrap: pretty 防止單個短詞落在最後一行。用於描述。
  • overflow-wrap: break-word 用於長詞、連結或 ID 可能超出容器的情況。
  • white-space: nowrap 用於標籤和徽章,換行會顯得不完整。

在長篇文字中跳過 balance 和 pretty。

對變化的數值使用表格數字

預設情況下,數字的寬度不同,因此計時器、計數器和價格在更新時會移動版面。對任何會變化的數值套用 font-variant-numeric: tabular-nums。

不遺失內容地截斷

對於單行,使用 text-overflow: ellipsis 搭配 overflow: hidden 和 white-space: nowrap。對於多行,使用 line-clamp。截斷會隱藏內容。當缺少的文字很重要時,請在工具提示或展開檢視中保留完整的數值。

自然書寫文案,用 CSS 設定樣式

以自然的大小寫儲存文字,並使用 text-transform 控制呈現方式,這樣重新設計永遠不需要重寫文案。

在渲染的文字中使用智慧標點:

  • 散文中使用彎引號,程式碼中使用直引號。
  • 範圍使用 en dash:2010–2020。
  • 使用單一字元的省略號,而非三個句點。
  • 使用   來將 16 px 保持在跨行斷開時不分離。
  • 使用 ­ 來指示長詞可以在何處斷開。

從字型取得底線設定

預設底線位於瀏覽器決定的位置。使用 text-underline-position: from-font 和 text-decoration-thickness: from-font 從字型自身的度量中拉取位置和粗細。使用 text-decoration-thickness、text-underline-offset 和 text-decoration-skip-ink 手動調整。

text-decoration-style 可以將線條繪製成點狀、虛線或波浪狀。點狀底線通常暗示某個詞攜帶額外資訊,例如縮寫或定義的術語。

顏色是真實底線中唯一能夠可靠動畫化的部分。因此,除非唯一動畫化的部分是顏色,否則請將底線建構為一個獨立元素,而不是使用 text-decoration。

行動裝置上的輸入框字型大小設為 16px

當輸入框的文字小於 16px 時,iOS Safari 會放大整個頁面。兩種修正方法能將字型大小固定在 16px,但外觀不同,請詢問設計偏好哪一種:

  • 在行動裝置上將輸入框字型大小調大(text-base sm:text-sm)。這會改變其在小型螢幕上的外觀。
  • 保持 font-size: 16px,並使用 transform: scale() 渲染預期尺寸,同時補償寬度和 line-height。在所有視口下都相同,但需要維護更多程式碼。

兩種配方都在 details-and-accessibility.md。

尺寸與對比下限

長篇內文從 16px(瀏覽器預設值)開始。只有在你能說出理由時才偏離它:字型偏小、行長較窄,或產品是密集的專業工具。

UI 文字可以更小。14px 是輸入框和選單的良好起點,13px 適用於說明文字,且很少低於 12px。在行動裝置上,輸入框仍然需要 16px。

當文字看起來對比較低時,使用 better-colors 測量渲染組合,並使用 better-accessibility 分類需求。除非被要求,否則不要改變顏色。

在根元素上啟用字型平滑

在 macOS 上,文字渲染得比預期更粗。在根佈局上套用一次 -webkit-font-smoothing: antialiased 和 -moz-osx-font-smoothing: grayscale,永遠不要在每個元件上單獨套用。Tailwind 的 antialiased 涵蓋了兩者。

語言與雙向行為

設定 lang,以便瀏覽器和輔助科技選擇正確的發音、引號和斷字。在文件層級或內容方向改變的邊界處設定 dir。保留數字順序,並使用 <bdi> 來隔離混合方向的數值。空間鏡像與邏輯 CSS 屬性屬於 better-layout。

保持有用的文字可選取

預設情況下,保持文字可選取。::selection 可以將品牌帶入閱讀體驗,只要選取的組合保持可讀。

user-select: none 屬於可拖曳或手勢驅動的表面,在這些表面上意外的選取會造成干擾。永遠不要在整個介面上使用,也永遠不要因為按鈕標籤可以被反白就使用。

在完成之前

錯誤修正
合成字體與設計不符載入真實字體;僅停用已驗證的合成模式
子標題在視覺上壓過父標題將該區塊的層級對應到遞減的尺寸步驟
因預設尺寸而選擇標題元素先選擇語義,然後在 CSS 中設定尺寸
段落最後一行出現孤兒字text-wrap: pretty
兩行標題不平衡text-wrap: balance
介面中使用對齊文字text-align: start;保留對齊給特定的編輯佈局
底線穿過下降部text-decoration-skip-ink: auto,from-font 度量
混合方向數值以錯誤順序渲染修正 lang/dir;使用 <bdi> 隔離數值
在應用程式 chrome 中停用選取恢復它;僅在與拖曳或手勢衝突時關閉
無視覺提示的額外資訊提示透過 text-decoration-style: dotted 使用點狀底線
在 14px 的 UI 文字上使用細/輕字重在 18px 以下使用字重 400+;細字重僅適用於顯示用途
在三行卡片描述上使用 leading-none任何換行到 3 行以上的文字至少需要 1.4

報告

嚴重性。 HIGH 使文字無法閱讀或截斷內容且無法恢復。MEDIUM 破壞了字型系統或標題層級。LOW 是孤立的微調。

驗證。 無瀏覽器:檢查每個標題層級的計算尺寸和字重,確認遞減;檢查宣告的行高和行長;檢查針對實際字串長度的截斷規則。有瀏覽器:調整視口大小以捕捉真實內容長度下的換行、孤兒字和截斷。報告你無法執行的每項檢查為 Not verified。

格式。 將發現結果分組到每個違反的原則下,按嚴重性排序,每個根本原因一行,列出其出現的每個位置:

嚴重性位置修改前修改後原因

位置 是 path/to/file:line。原因 指出原則和對使用者的影響。

當任何 HIGH 項目仍然存在時,以 Block 結束,否則以 Approve 結束,將表格中的其餘項目留作待辦事項。永遠不要 Approve 你未檢查的範圍。如果沒有可報告的項目,則聲明 "No actionable typography findings" 並報告驗證。

Individual skills in this repo

This repo contains 7 individual skills — each has its own dedicated page.

相關技能