Community影像github.com

佈局 (Layout)

決定產品 UI 中元素的位置、間距與尺寸,使用統一的間距比例尺與嚴格的決策順序,確保佈局穩定且可預測。

佈局 (Layout) 是什麼?

這個技能定義了在 Web 產品 UI 中如何結構化空間與元素。它強制執行一套 4px 基底的間距比例尺(如 `--space-xs` 為 4px,`--space-xl` 為 24px),並要求開發者遵循固定的決策順序:從外殼結構、內容欄寬度、空間分組、對齊、尺寸(密度與點擊區域)、最差情況資料、容器響應,到最後以 2 倍解析度進行像素測量驗證。此技能支援所有現代瀏覽器與 UI 框架,並以 SKILL.md 文件與引用文件(如 `spacing-and-density.md`、`shell-and-responsive.md`)詳細說明每個步驟。其核心目標是消除佈局偏移、保證 RTL 支援、確保群組間距足夠清晰、並透過邏輯屬性與容器查詢取代裝置查詢,使佈局更具可維護性。對於開發者而言,這是一套可以減少設計決策疲勞的系統化規則,同時提升產品的一致性和可訪問性。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/nkurunziza-saddy/hmm-interfaces/tree/HEAD/layout

Installed? Explore more 影像 skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

在你喜歡的 AI 中提問

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

說明文件

佈局

這個技能決定元素的位置、間距與尺寸。它會以相同的順序做出相同的決定,並根據實際渲染出的像素來檢查結果。

在任何決策之前,請套用 product-ui §1(品味日誌與優先順序)及 §5(哪些技能負責哪些部分)。

依此順序決定

  1. 外殼 (Shell)。 為畫面的各個區域命名:側邊欄、工具列、內容區、檢查器。每個區域最多只能有一個滾動擁有者或無。詳細內容與寬度:shell-and-responsive.md。原因:外殼決定了內部佈局必須容納的每一種寬度。
  2. 寬度與邊長 (Width and Measure)。 根據內容設定內容欄:表單 440px,閱讀區 720px 且內文以 type 的邊長 (66ch) 為上限,資料區 1200px。欄位絕不因畫面寬而伸長。原因:超過 75 個字元會讓讀者迷失方向,而拉伸的表單會讓視線在畫面上遊移。
  3. 空間 (Space)。 只使用下方的比例尺,不使用其他值。先用空間分組;當空間無法承載時,才添加底色,然後才是分隔線。spacing-and-density.md。
  4. 對齊 (Align)。 選取共同的邊緣,並將所有元素放在那些邊緣上。1–4px 的偏差即為錯誤。在視覺上幾何形狀看起來不對的地方,進行光學校正。spacing-and-density.md。
  5. 尺寸 (Size)。 為該區域選擇密度模式,然後再設定點擊區域。spacing-and-density.md。
  6. 最差情況資料 (Worst-case Data)。 在宣告完成前,為最長、最短、缺失、翻譯後以及仍在載入中的內容調整盒模型大小。stability-and-text.md。
  7. 適配 (Adapt)。 讓結構對其容器做出響應,而不是對裝置做出響應。shell-and-responsive.md。
  8. 測量 (Measure)。 以 2 倍解析度渲染,測量間隙與邊緣,並修正像素所顯示的問題。measure.md。

比例尺

單一比例尺,4px 基底。絕不撰寫不在步驟中的間距值。原因:非標準值 (10px, 14px, 18px) 會讓韻律無法察覺也無法維持。

| Token | px | 典型用法 | | --- | --- | | --space-xs | 4 | 標籤與其說明之間;標籤與圖示之間 | | --space-sm | 8 | 群組內項目之間;控制項 padding 區塊方向 | | --space-md | 12 | 有邊框的控制項之間;控制項 padding 內聯方向 | | --space-lg | 16 | 欄位之間;緊湊卡片 padding | | --space-20 | 20 | 卡片內區塊之間 | | --space-xl | 24 | 群組之間;舒適卡片 padding | | --space-2xl | 32 | 區段之間 | | --space-3xl | 48 | 頁面第一個標題上方 | | --space-4xl | 64 | 頁面最後一個區塊下方 |

1–2px 的光學對齊微調是唯一不在比例尺上的值。為它們命名 (--play-nudge: 2px)。

無需參考文件的規則

  • 用空間分組。 組與組之間的間隔至少是組內間距的 2 倍:組內 8px 表示組間 16px 或更多。各處間距相等會使分組變得模糊,而這種模糊是功能性錯誤。
  • 先移除線,再添加線。 先使用空間,其次是底色,最後才是分隔線,且僅用於密集資料。原因:每一條線都需要注意力,而空間能免費提供相同的資訊。
  • 兩者之間的元素,其上方的空間等於下方的空間。 原因:一個更靠近某個相鄰元素的事物,會被認為屬於該元素。
  • 控制項必須看起來像控制項。 按鈕、連結或切換開關具有形狀、底線或工具列位置。靜態文字永遠不應使用這些樣式。原因:偽裝成文字的控制項會被隱藏,而偽裝成控制項的文字會收集無效點擊。
  • 動作應位於其所操作的資料上方,絕不位於其下方。設定某個項目的控制項應放在其旁邊。
  • 主要內容放在前方並處於起始側。 視覺順序等於 DOM 順序:永遠不要使用 order、row-reverse 或網格放置來重新排列內容。原因:鍵盤與螢幕閱讀器的順序遵循 DOM。
  • 對於需要鏡像翻轉的情況,使用邏輯屬性(margin-inline-start、padding-block、inset-inline-end、text-align: start)。原因:如此一來,無需第二張樣式表即可支援 RTL。
  • 切勿將關鍵控制項放在視窗或側邊欄的底部邊緣。 原因:使用者有時會將視窗部分移出螢幕。
  • 滾動顯示了被隱藏的內容。 超出邊緣的內容應有可見的提示:16–32px 的預覽或漸層淡出效果。
  • 沒有任何東西會偏移。 懸停、選取和聚焦永遠不應改變元素的大小。已載入的資料應佔用骨架所佔的盒模型。

常見問題對照表

錯誤寫法正確寫法原因
在表單中使用 gap: 12px 且在其 fieldset 之間使用 gap: 12px內部使用 gap: 8px,之間使用 gap: 24px群組之間需要至少 2 倍的間隔
padding: 10px 14pxpadding: var(--space-sm) var(--space-md)只能使用比例尺步驟
標題 x=24,描述 x=26兩者都在 x=241–4px 的偏差會被視為明顯的錯誤
16×16 的圖示按鈕,padding: 016px 的字形,::before { inset: -12px } 以獲得 40px 的目標滑鼠目標應為 40px
.row + .row { margin-top: 8px } 搭配行上的懸停與點擊.row { padding-block: 4px },無 margin行之間的間隙會變成死區並使懸停效果閃爍
.menu { width: 200px }width: max-content; min-width: 160px; max-width: 320px選單應貼合其最長標籤的寬度
在卡片上使用 @media (max-width: 768px)在卡片的上層元素上使用 @container (width < 400px)位於窄側邊欄中的卡片應根據自身寬度響應,而非根據畫面寬度
img 無尺寸,隨後卡片跳動設定 width、height 或 aspect-ratio在圖片位元組載入前,盒模型就已存在
固定頁首,定位點落在其下方在滾動容器上設定 scroll-padding-block-start: 56px焦點與定位點永遠不會位於 chrome 之下

完成前

在 diff 中搜尋以下模式,然後進行驗證。

模式修正
margin、padding 或 gap 的值不在比例尺內取最接近的步驟值
在內部與群組之間使用了相同的單一 gap 值內部值 ≤ 之間值的一半
純圖示按鈕小於 24px,或小於 40px 但無 ::before使用偽元素擴大
在可點擊的行或選單項目之間使用 gap 或 margin將 padding 加在項目內部
在選單、按鈕或文字框上使用固定 width使用 max-content、min-width、max-width;文字框使用 min-height
在可重複使用的元件內部使用 @media (max-width...在其上層元素上使用 @container
外殼使用 height: 100vh改用 100dvh
包含長文字的 1fr 軌道或 flex 子項使用 minmax(0, 1fr) 或 min-width: 0
在需鏡像的 UI 中使用 margin-left、padding-right、left: 0、text-align: left改用邏輯屬性形式
固定頁首或頁尾沒有 scroll-padding-block將其設為 chrome 的高度
骨架行的高度或欄寬度與已載入的內容不同使它們匹配
img 沒有尺寸或 aspect-ratio添加一個

使用 measure.md 進行驗證:以 2 倍解析度在 390px 與外殼的最大寬度下渲染,執行指令碼,裁剪每個候選區塊並計算像素。然後在固定 chrome 存在的情況下,使用 Tab 鍵遍歷畫面,並載入最長的字串。將無法檢查的項目回報為「未驗證」。

Individual skills in this repo

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

nkurunziza-saddy/break

Stress-tests a piece of UI with worst-case data and every reachable state, then reports what broke with a numbered fix for each. Use it when the user types /break, or asks to "break this", "stress-test", "try the worst case", "what happens with long names", "check the empty and error states" or "find the edge cases" on a component or screen.

nkurunziza-saddy/motion

Builds motion for product UI on the web. It decides whether something should move at all, then why, which tool (CSS transition, WAAPI, Motion, spring), which properties, curve, duration, interruption, exit and reduced-motion path, and it writes the code. Also covers stagger and choreography, gestures (drag, flick, sheets), motion tokens and animation performance.

nkurunziza-saddy/pick-library

Picks the right library for a frontend task from a curated, status-checked list, instead of hand-rolling it or installing an abandoned package. Use it when the user asks "what should I use for…", "is there a library for…", or names a package, and when you are about to build a toast, command menu, drawer, date picker, table, virtual list, drag and drop, chart, OTP input, animated number, theme switch, form validation…

nkurunziza-saddy/surfaces

What product UI is made of on the web. It sets elevation levels with exact shadow recipes for light and dark mode, when to use a shadow and when a border, the transparent border for forced-colours mode, a small radius scale with concentric nesting, image outlines, every interactive state as a surface change (hover, pressed, selected, disabled, focus-visible), icons (one set, currentColor, outline and fill, stroke tha…

相關技能