骨架狀態系統
目的
骨架狀態系統提供了一套設計介面「載入中」狀態的方法論。與一般的旋轉圖示或進度條不同,骨架使用「骨骼」(低擬真形狀)來近似最終版面,從而減少使用者的感知等待時間,並透過預先保留必要空間來防止版面位移(Cumulative Layout Shift, CLS)。
使用情境
- 數據密集的儀表板: 多個小工具以不同速度載入時。
- 內容摘要: 滾動瀏覽文章、產品或社群貼文的列表。
- 圖片密集網格: 為高解析度圖片保留空間,防止頁面「跳動」。
- 搜尋與篩選視圖: 即時回饋系統正在處理查詢。
- 單頁應用程式(SPA): 管理路由切換時的過渡,因為資料是非同步取得的。
何時不該使用
- 即時互動: 如果內容在 300ms 內載入完成,骨架可能會造成「閃爍」而分散注意力。
- 簡單、低上下文載入: 對於單一按鈕或小型標籤等小元素,使用標準的旋轉圖示或「載入中...」文字更為合適。
- 靜態內容: 硬編碼或快取且立即渲染的內容。
- 高速即時資料: 如果資料變化速度極快,導致骨架不斷出現與消失,可能會造成視覺疲勞。
輸入
- 目標佈局: 元件或頁面最終「完全載入」的設計。
- 內容變數: UI 中哪些部分是動態的(文字、圖片、價格、頭像)?
- 空間尺寸: 最終元素的確切高度、寬度與長寬比。
- 品牌色調: 用於「骨骼」基底與閃爍效果的主要與次要顏色。
輸出
- 骨架藍圖: 顯示骨骼排列方式的低擬真地圖。
- 骨骼規格: 形狀(圓形 vs. 矩形)與尺寸(固定 vs. 百分比)的定義。
- 過場策略: 骨架淡出與內容淡入的規則。
- 無障礙需求: 關於
aria-busy和aria-hidden實作的指引。
工作流程
1. 測繪「目標」幾何形狀
將最終元件分解為基本的幾何基本元素:
- 圓形: 用於頭像、圖示或圓角按鈕。
- 矩形(圓角): 用於卡片、圖片容器與文字區塊。
- 線條: 用於單行文字(標題、中繼資料)。
2. 定義骨骼層級
並非每個元素都需要骨骼。專注於結構性的「錨點」:
- 主要骨骼: 最大的視覺元素(例如產品圖片)。
- 次要骨骼: 標題與主要中繼資料。
- 三級骨骼: 小型中繼細節或操作按鈕(如果過小,通常可以省略)。
3. 建立空間匹配(CLS 規則)
確保骨架的尺寸與最終內容的容器完全相符:
- 長寬比: 為骨骼使用固定長寬比(例如影片使用 16:9),使其在資產載入時不會改變大小。
- 文字尺寸: 使用與所代表文字的 line-height 和近似寬度相符的骨骼。
4. 設計節奏與閃爍效果
骨架應該感覺「有生命力」但不分散注意力:
- 基底顏色: 使用低對比度的中性顏色(例如淺灰色)。
- 閃爍效果(脈衝): 套用從左到右移動的微妙漸層動畫。
- 同步: 如果螢幕上有多個骨架,確保它們的動畫同步,以避免視覺混亂。
- 減少動畫: 將閃爍關鍵影格動畫包裹在
@media (prefers-reduced-motion: reduce)查詢中,停用移動效果,並退回到靜態或輕微不透明脈衝的骨骼。
5. 定義「交接」過渡
規劃骨架的退出方式:
- 時機: 為真實內容使用短暫的淡入(例如 200ms),以防止生硬的「快照」過渡。
- 交錯: 對於列表,決定項目是一次全部出現,還是逐個載入時出現。
決策規則
- 300ms 規則: 僅在載入預計超過 300ms 時才顯示骨架。
- 骨骼準確性: 骨骼應代表容器,而非特定的資料。例如,文字骨骼應該是簡單的長條,而不是模仿特定字母的鋸齒狀線條。
- 行數: 對於多行文字,使用 2 或 3 個不同寬度的骨骼(例如最後一行為 60% 寬度),以模擬自然段落流程。
- 旋轉圖示 vs. 骨架:
- 對頁面層級或區塊層級的過渡使用骨架。
- 對小型局部操作(例如「儲存中...」按鈕狀態)使用旋轉圖示。
限制條件
- 無障礙: 骨架必須標記
aria-hidden="true",以便螢幕閱讀器不會嘗試「讀取」空的長條。父容器應在載入時使用aria-busy="true",並理想上保留一個視覺隱藏的aria-live="polite"區域來宣告「載入中」以及內容取代骨架後的完成狀態——請勿對骨架骨骼本身使用aria-live。應尊重prefers-reduced-motion以處理閃爍效果。 - 對比度: 骨架顏色必須與背景區分開來,但對比度不宜過高,以免看起來像活動中的內容。
- 響應式設計: 骨架骨骼必須使用與最終內容相同的網格/flex 邏輯來進行縮放。
常見失敗模式
- 「CLS 跳動」: 骨架高度為 200px,但被高度為 300px 的內容取代,導致頁面「跳動」。
- 閃爍過度: 動畫過快或對比度過高,導致暈眩或分心。
- 內容-骨骼不匹配: 為方形圖片使用圓形骨骼,或反之。
- 過度複雜: 試圖將每個微小圖示都重建成骨骼,導致版面混亂的「幽靈」佈局。
- 「靜態骨架」: 沒有任何動畫的骨架,可能被誤認為是損壞或空白的頁面。
驗證標準
- 骨架尺寸與最終「載入」狀態完全相符(零 CLS)。
- 使用固定容器保留圖片/影片的長寬比。
- 閃爍動畫細微且從左到右移動。
- 文字密集區域使用模擬自然行長的骨骼。
- 骨架元素套用了
aria-hidden="true",且載入容器使用aria-busy="true"。 - 閃爍動畫尊重
prefers-reduced-motion: reduce。 - 從骨架到內容的過渡是平滑淡入(約 200ms)。
- 載入時間快於 300ms 時不會顯示骨架。