Communitygithub.com

wensity/wensity-typography

在 Web UI 中設定與修正排版:選擇載入字型、建立具名角色的字型階層、設定行高、字距、行長與斷行,以及為數字、連結和程式碼設定樣式。在建立頁面、章節或元件,或在 React、Next.js、Tailwind CSS 或 CSS 中變更字型、文字大小、階層、行高、字距、文字換行或字型載入時使用;也適用於標題或內文看起來不對勁、擁擠、千篇一律或難以閱讀的情況。若編輯內容未更動文字樣式,則跳過此技能。

wensity-typography 是什麼?

此技能提供了一套完整且基於原則的網頁排版系統,專為需要在 React、Next.js、Tailwind CSS 或原生 CSS 專案中設定、修正或審查文字樣式的開發者與 AI 代理器設計。它不僅是隨機的 CSS 屬性,而是一個從字型選擇到最終渲染檢查的系統化方法。核心原則包含:偏好使用一種或多種無襯線字型(最多三種,包含等寬字型)及最多三種字重來建立階層;透過「角色」(如 display、title、body)而非固定像素來定義字型階層,並提供行高、字距與大小的具體建議數值;詳細指導行長控制(約 65 字符)、斷行及避免排版陷阱(如全大寫標籤、斜體、置中段落)。此技能也涵蓋無障礙對比度、表格數字、連結樣式,以及使用 next/font 等現代字型載入技術來避免版面位移(CLS),確保高效能且穩定的使用者體驗。

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

在你喜歡的 AI 中提問

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

說明文件

Wensity Typography

在介面中,文字承擔了絕大部分的工作。把它用對,一個樸素的頁面看起來就像經過設計;用錯,再多色彩與動態也無法挽救。此技能提供了一個可一次性設定的系統,以及可隨處套用的規則。

以下數值均為預設值。若專案已有字型系統,請保留它並改善其使用方式。僅在要求時才取代它。

1. 選擇字型家族

  • 通常一個家族就夠了。 一個具有實際字重範圍的優質無襯線字型,就能涵蓋展示、標題、內文與 UI。只有在第一個字型無法勝任特定角色時,才加入第二個家族:例如為行銷頁面加入一個有性格的展示用無襯線字型,或為程式碼與資料加入等寬字型。
  • 僅限無襯線:無襯線且無斜體。 標題、內文、引言與圖說都使用直立無襯線字型。在網頁產品上,襯線標題或斜體行看起來就像模板戲服,即使在部落格、文件與奢華頁面上也應避免;應使用字重、大小與間距來傳達語氣。
  • 除等寬字型外,最多兩個家族。 第三個文字家族會顯得猶豫不決。
  • 根據主題選擇,而非習慣。 不要每個專案都用同一種字體。詢問產品在印刷或硬體上看起來像什麼,然後選擇具有該特質的字體:
產品感覺像可選用免費範例
精確工具(開發工具、資料、基礎設施)緊湊的 grotesk,資料用等寬字Geist, Switzer, Onest; Geist Mono, JetBrains Mono
沉穩的金融或健康(金融、保險、診所)穩定的 neo-grotesk 或 humanist 無襯線字Inter, Public Sans, Source Sans 3
友善的消費性產品(社群、美食、旅遊、教育)較圓潤的 geometric 或 humanist 無襯線字Plus Jakarta Sans, Figtree, Nunito Sans, DM Sans
自信的品牌或新創行銷頁面在展示尺寸下有個性的無襯線字General Sans, Manrope, Bricolage Grotesque, Space Grotesk
閱讀與出版(文件、部落格、雜誌)具有真實文字剪裁的沉穩無襯線字,同一家族內使用緊湊標題Inter, Satoshi, Source Sans 3
時尚、編輯或奢華精緻的展示用無襯線字,設定為大且緊湊,僅用於標題Satoshi, General Sans, Clash Grotesk
  • 檢查字體能否勝任工作: 你需要的字重(通常是 400, 500, 600)、表格數字、良好的標點符號、你出貨的語言,以及如果你使用多種字重,則需要變數版本。

2. 定義角色,而非大小

以工作職責來命名文字。元件使用角色名稱;只有角色定義包含像素值。七個角色幾乎能涵蓋所有介面:

角色用途行銷頁面App UI
display頁面主標題,每頁一個48 至 80px,字重 600,行高 0.95 至 1.05,字距 -0.03em 至 -0.04em少用
title頁面與區段標題32 至 44px,字重 600,行高 1.1,字距 -0.02em20 至 24px,字重 600,行高 1.25,字距 -0.01em
heading卡片、面板與子區段標題20 至 24px,字重 600,行高 1.25,字距 -0.01em15 至 16px,字重 600,行高 1.4
body段落16 至 18px,字重 400,行高 1.55 至 1.6514 至 15px,字重 400,行高 1.5
label按鈕、輸入欄位、導航、表格標題14 至 15px,字重 500,行高 1.313 至 14px,字重 500,行高 1.3
caption輔助文字、後設資料、時間戳記13 至 14px,字重 400,行高 1.4512 至 13px,字重 400,行高 1.4
code行內程式碼、程式碼區塊、ID周圍文字的 0.9em,等寬字相同

階層規則:

  • 階層必須明顯。 相鄰角色在大小上至少相差約 20%,或是一個大小階層加上一個字重階層(14px 500 的 label 放在 13px 400 的 caption 上面可以;但 15px 400 與 16px 400 做不同工作則不行)。
  • 比例有幫助,但表格為準。 行銷頁面適合 1.25 到 1.333 的比例;密集的 App UI 適合 1.125 到 1.2。四捨五入到整數像素。
  • 最多三種字重: 一般(400)、中等(500)用於標籤、半粗(600)用於標題與展示。階層感也來自大小、顏色與空間,所以不需要五種字重。如果 600 在大尺寸展示行上看起來太重,請使用 500 作為展示字重,而不是增加第四種字重。
  • 僅在行銷頁面上對 display 與 title 使用流體大小: font-size: clamp(2.5rem, 1.5rem + 4vw, 5rem)。保持內文與 UI 文字固定,以便密集的版面保持可預測。
  • 內文基線: 行銷與閱讀頁面為 16px,密集的 App UI 為 14px。行動裝置上輸入文字為 16px,否則 iOS Safari 會在聚焦欄位時放大頁面。

在 Tailwind CSS v4 中,一次性定義角色(將字型家族名稱替換為你選擇的):

@theme {
  --text-display: clamp(2.75rem, 1.6rem + 4.2vw, 5rem);
  --text-display--line-height: 1;
  --text-display--letter-spacing: -0.035em;
  --text-display--font-weight: 600;

  --text-title: 2.25rem;
  --text-title--line-height: 1.1;
  --text-title--letter-spacing: -0.02em;
  --text-title--font-weight: 600;

  --text-heading: 1.25rem;
  --text-heading--line-height: 1.3;
  --text-heading--letter-spacing: -0.01em;
  --text-heading--font-weight: 600;

  --text-body: 1rem;
  --text-body--line-height: 1.6;

  --text-label: 0.875rem;
  --text-label--line-height: 1.3;
  --text-label--font-weight: 500;

  --text-caption: 0.8125rem;
  --text-caption--line-height: 1.45;
}

然後在標記中使用 text-display、text-title、text-body,而不是 text-[44px] 或一長串的 text-4xl leading-tight tracking-tight。在 Tailwind v3 中,將相同的值放在 theme.extend.fontSize 下,作為 [size, { lineHeight, letterSpacing, fontWeight }] 元組。

3. 行高與字距

  • 行高隨著字型大小增加而減少。 Display 0.95 至 1.05,titles 1.1 至 1.2,body 1.5 至 1.65,labels 1.2 至 1.35。一個 64px 的標題若行高為 1.5,會散成獨立的行。
  • 大字緊湊字距,內文無字距。 Display -0.03em 至 -0.04em,titles -0.02em,headings -0.01em,body 與 labels 為 0。不要緊於 -0.05em;字母會開始碰觸。根據你選擇的字體用肉眼調整。
  • 小寫內文與介面文字無正字距。 正字距只對全大寫文字有幫助,而全大寫文字應該少見(見第 6 節)。
  • 寬行需要更多行距。 如果內文接近 75 個字符,請使用行高 1.6 或更高;在 50 個字符時,1.5 就夠了。
  • 淺色文字在深色背景上看起來更重且更緊。 在深色主題中,將內文行高大約增加 0.05。

4. 行長與斷行

  • 內文:每行 60 到 75 個字符。 在段落上設定 max-width: 65ch,而不是在整個頁面上。圖說與輔助文字可以更窄。
  • 展示標題:每行大約 12 到 20 個字符。 一個橫跨 1440px 螢幕的標題只有一行就沒有形狀。使用 max-width(以 ch 為單位)或容器寬度來限制它。
  • 平衡標題,美化段落換行:
h1, h2, h3, .text-display, .text-title { text-wrap: balance; }
p, li, figcaption { text-wrap: pretty; }

兩者都是漸進增強:舊版瀏覽器會忽略它們。balance 會平均分配標題行的長度;pretty 會防止段落最後一行只有一個詞。

  • 僅在片語之間手動斷行,並在文字渲染的所有寬度下檢查。一個在手機上落在行中間的 <br> 比預設換行更糟。優先使用 max-width 而不是 <br>。
  • 長詞與 URL 在使用者內容中需要在其容器上設定 overflow-wrap: anywhere,否則它們會在行動裝置上將版面推向側邊。
  • 截斷是最後手段。 在緊湊的 UI 中截斷單行標籤(Tailwind 中的 truncate)。如果隱藏的部分很重要,請讓完整文字可透過鍵盤和觸控存取(可聚焦元素上的工具提示、可展開的列、詳細檢視);僅有 title 屬性是不夠的。永遠不要截斷使用者必須閱讀才能操作的內文或任何內容。
  • 多行截斷(line-clamp-2):保持被截斷文字的行高在 1.3 或以上,以便下伸部(g, y, p)不會被切斷。不要在截斷內部添加底部內距;它會顯示下一行的頂部。

5. 文字顏色與對比

  • 三種文字顏色就夠了: 主要(標題與內文)、次要(輔助文字、圖說、佔位文字)與停用。將它們定義為 token。避免透過動態降低不透明度來製作第四種。
  • 對比度底線(WCAG 2.2 AA): 內文與小文字為 4.5:1,24px 及以上的文字(或 18.66px 粗體)為 3:1。次要文字和佔位文字也需要 4.5:1。只有停用控制項中的文字可以豁免。
  • 在深色背景上使用近白色,而非純白色,用於長篇文字(大約 90% 到 94% 亮度)。純白色在近黑色上會刺眼。
  • 在彩色或著色表面上, 將次要文字色調向表面色相傾斜,而不是使用中性灰,後者在顏色上看起來很髒。

6. 應避免的事項

  • 眉毛與前導文字: 在標題上方的小號全大寫字母間距標籤("FEATURES", "WHY US", "HOW IT WORKS")。不要使用它們。它們是模板 UI 最明顯的標誌。如果標題需要上下文,請寫一個更好的標題。
  • 一般來說,全大寫標籤, 包括側邊欄、設定面板、卡片、頁尾和示範控制項中的小節標題。句子大小寫閱讀速度更快;給小標題字重(500 或 600)和次要文字顏色。將全大寫保留給真正的縮寫(API, URL)。
  • 漸層文字和標題中的一個彩色詞。 強調來自大小、字重與位置,而不是塗料。
  • 斜體,隨處可見。 使用字重表示強調,並將引言設定為直立,旁邊加上規則或更大的尺寸。
  • 襯線字型。 展示用襯線和文字用襯線在網頁產品上看起來都像戲服。請改用有個性的無襯線字型。
  • 將等寬字型用作裝飾。 等寬字型用於程式碼、資料、ID、按鍵和欄位中的數字。行銷頁面上的等寬標籤是一種戲服。
  • 超過兩行的置中段落。 僅置中短標題和單行 CTA。
  • 在網路上使用左右對齊文字。 沒有連字符號會產生白河。
  • 除連結外,對任何東西使用底線。

7. 數字、程式碼與資料

  • 任何需要對齊或更新的事物中使用表格數字: 表格、價格、計時器、計數器、統計資料。font-variant-numeric: tabular-nums;(Tailwind tabular-nums)。沒有它,計數數字會因為數字寬度變化而橫向抖動。
  • 帶斜線的零 用於可能混淆 0 和 O 的 ID 和代碼:font-variant-numeric: tabular-nums slashed-zero;。
  • 將數字對齊在表格儲存格末端(text-align: end),以便小數點對齊。文字欄對齊在開頭。
  • 程式碼: 等寬字型,大小約為周圍文字的 0.9em,以便其 x 高度匹配。行內程式碼獲得淡色背景和 0.2em 水平內距,無邊框。程式碼區塊獲得約 1.6 的行高和水平捲動,永遠不要使用會破壞縮排的換行。
  • 按鍵(<kbd>)使用 caption 大小的等寬字型。

8. 連結

在連續文字中為連結加底線;僅靠顏色對色盲讀者來說是不夠的。將其範圍限定在散文,以便導覽列表和按鈕不會有底線(.prose 是任何包裹你的文章或長篇內容的元素):

:where(p, td, dd, figcaption, blockquote) a,
:where(.prose, article) li a {
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

導覽、按鈕和卡片連結不需要底線;它們的位置已經說明它們是可互動的。

9. 載入字型而不造成版面位移

  • Next.js: 使用 next/font(next/font/google 或 next/font/local)。它會自行託管、預載入並產生具有匹配度量標準的後備字型,因此頁面在字型到達時不會跳動。將其公開為 CSS 變數,並使用 @theme inline 將主題字型映射到它(以便在使用處讀取變數,而不是在 :root 處解析一次):
// app/layout.tsx
import { Onest } from "next/font/google";
const sans = Onest({ subsets: ["latin"], variable: "--font-brand", display: "swap" });
// <html lang="en" className={sans.variable}>
@theme inline {
  --font-sans: var(--font-brand), ui-sans-serif, system-ui, sans-serif;
}
  • 光學尺寸: 具有 opsz 軸的字體(Inter, Roboto Flex, Fraunces)只有在載入時才會獲得該軸:Inter({ subsets: ["latin"], axes: ["opsz"] })。保持 font-optical-sizing: auto,以便小文字獲得更堅固的剪裁,大文字獲得更精緻的剪裁。
  • 其他情況: 自行託管 WOFF2,font-display: swap,僅預載入折疊上方使用的一或兩個檔案,並在本地後備字型上設定 size-adjust、ascent-override 和 descent-override,以便交換不會造成版面位移。
  • 僅載入你使用的部分。 偏好一個變數字型檔案而不是六個靜態字重。子集化到你出貨的腳本。

10. 渲染細節

  • 在深色主題上,-webkit-font-smoothing: antialiased 可以讓 macOS 上的淺色文字看起來不那麼腫脹。淺色主題保持預設值。
  • 將 ::selection 設定為品牌色調並保持可讀性。瀏覽器預設的藍色是頁面未完成的跡象。
  • 在文案中使用真正的標點符號:彎引號(“ ” ‘ ’)、省略號字元(…)和尺寸中的乘號(×)。
  • 尊重使用者設定:以 rem 為單位設定文字大小,永遠不要阻止縮放,並檢查文字在 200% 文字大小以及較大的字母和行間距時是否仍然合適。

11. 完成前檢查

  • 每個文字樣式都來自已命名的角色;沒有雜散的像素大小。
  • 相鄰角色在大小或大小加上字重上明顯不同。
  • 最多兩個家族加上等寬字型,最多三種字重,全部已載入。
  • 內文 16px(密集 UI 14px),行動裝置上輸入欄位 16px。
  • 段落限制在大約 65ch;展示行大約 12 到 20 個字符。
  • 標題已平衡,段落已美化換行。
  • 沒有眉毛標題、沒有漸層文字、沒有全大寫標籤、沒有斜體、沒有襯線。
  • 數值對比度符合 AA 標準;深色主題使用近白色。
  • 數字使用表格數字,程式碼使用等寬字型。
  • 字型已使用 next/font 或等效方法載入,不會造成版面位移。
  • 選取範圍樣式已設定。

Individual skills in this repo

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

相關技能