黏性與浮動 UI 系統
目的
黏性與浮動 UI 系統提供一套設計持續可見、固定在視埠內且可響應滾動的介面元件的方法論。它確保關鍵控制項——例如主要導航、驅動轉換的行動呼籲(CTA)、情境式實用小工具以及快速動作按鈕——在使用者主動滾動時仍能輕鬆存取。
一個設計良好的黏性與浮動系統,解決了立即動作可用性與主要內容消費之間的空間張力。它能防止版面疲勞、保護視埠免受過多視覺雜訊干擾、尊重行動裝置的物理安全區域(如裝置瀏海和系統 Home Indicator),並嚴格減輕鍵盤焦點遮蔽失敗(WCAG 2.2 SC 2.4.11)的風險。
使用案例
- 漸進式導航頁首: 向下滾動時隱藏頁首(最大化閱讀區域),向上滾動時顯示頁首(讓導航立即可用)。
- 行動裝置持久底部 Dock: 在行動版型中,包含主要轉換動作(例如「加入購物車」、「立即預訂」、「申請」)的浮動或固定底部工具列。
- 黏性側邊欄小工具: 情境式子導航、分享列或產品購買配置,能隨主要內容區域滾動,但在到達結構邊界前鎖定在特定位置。
- 浮動動作按鈕(FAB): 固定在視埠上的觸發器,用於快速高頻動作,例如「回到頂端」導航、直接支援對話或購物車抽屜。
- 定位錨點與閱讀進度條: 追蹤視埠完成率或提供頁面主體子章節直接連結的黏性元素。
何時不應使用
- 資料密集的 SaaS 儀表板: 當螢幕空間被表格資料、工作畫布或鎖定在視埠的面板嚴重壓縮時;請改用
dashboard-layout-system。 - 短頁面/單視埠頁面: 當整個頁面內容適合單一螢幕檢視,且無需滾動即可存取時。
- 敘事驅動的實驗性網站: 當刻意選擇視覺迷失感或沉浸式 3D 空間流程,而非標準導航實用性時。
- 鍵盤優先的表單: 在多欄位表單頁面中,黏性按鈕在行動虛擬鍵盤上會遮擋並覆蓋作用中的輸入欄位。
輸入
- 內容與敘事結構: 頁面的線框順序(來自
section-composition-system),用以了解黏性元素應在何時何地啟動。 - 裝置視埠限制: 鎖定行動裝置、平板與桌面的中斷點,以在固定工具列與浮動側邊容器之間調整版面。
- 主要與次要 CTA: 識別需要持續可見的轉換目標。
- Z-Index 分層策略: 在
elevation-and-depth-system中建立的疊加關係與層級,以防止視覺重疊衝突。 - 系統安全區域指標: 硬體安全區域內縮值(
env(safe-area-inset-bottom)、瀏海),以防止與裝置 chrome 重疊。
輸出
- 黏性行為規範: 明確定義滾動觸發器、動畫閾值以及進入/退出轉換公式。
- 行動裝置底部 Dock 版面: 為行動螢幕最佳化的空間配置藍圖,詳細說明目標尺寸、安全區域偏移和對比度要求。
- 遮蔽緩解圖: 顯示如何保持黏性覆蓋層不阻擋已聚焦元素的設計定義(WCAG 2.2 SC 2.4.11)。
- 桌面側邊欄/小工具鎖定規範: 定義滾動側邊元素必須貼齊並鎖定的邊界規則(頁首、頁尾、章節結束點)。
工作流程
1. 建立視埠分區與空間預算
在定位持久層之前,先定義「視覺安全區域」以確保內容可讀性。
- 15% 預算規則: 黏性元素在任何裝置螢幕上,不得佔用超過總垂直視埠的 15%。
- Z-Index 分配: 使用
elevation-and-depth-system層級分配清晰的疊加值。- 漸進式頁首:
z-index: 100(第 3 層:黏性) - 行動裝置底部 Dock:
z-index: 150(第 3 層:黏性/浮動) - 浮動動作按鈕:
z-index: 200(第 3 層:浮動觸發器)
- 漸進式頁首:
- 避免堆疊重疊: 永遠不要讓黏性頁首和黏性底部工具列同時靜止不動,若它們會擁擠螢幕;確保它們有足夠的呼吸空間,或是在特定狀態下隱藏其中一個。
2. 設計漸進式頁首行為
固定的黏性頁首佔據了寶貴的垂直像素。實作「漸進式」模型:
- 預設狀態: 透明或與頁面背景整合的頁首。
- 向下滾動(閾值 > 100px): 順暢地將頁首向上移出視野(
transform: translateY(-100%)),最大化內容掃描區域。 - 向上滾動(增量 > 15px): 立即或順暢地將頁首移回視野,套用實心或模糊的背景表面(
backdrop-filter: blur(8px))並加上微妙的陰影,以表示與頁面本文分離。 - 邊界停止: 一旦捲軸回到視埠頂端(scrollY < 50px),停用向上滾動轉換,讓頁首恢復其原始的靜態版面。
3. 設計行動裝置持久底部 Dock
底部持久工具列是行動轉換的主要驅動力,但非常容易受到物理和視覺干擾。
- 物理安全區域: 始終使用 CSS 環境變數來錨定工具列的底部邊緣:
padding-bottom: calc(var(--base-padding) + env(safe-area-inset-bottom))。這確保它能整齊地位於 iOS Home Indicator 和 Android 導航列之上,而不會與互動觸發器重疊。 - 進入滾動觸發器: 不要在初始 Hero 視埠中顯示行動底部 Dock。等到使用者滾動超過 Hero 區段的主要內嵌 CTA 後(閾值 > 100% VH),再讓 Dock 從底部滑入(從
translateY(100%)轉換為translateY(0))。 - 版面分割: 將 Dock 限制為一個主要動作按鈕(例如「加入購物車」)和一個次要實用按鈕/徽章(例如「價格」或「儲存」),以保持點擊目標極度簡潔。
4. 建構桌面黏性側邊欄與小工具
側邊欄小工具在與深層主要內容欄位一同滾動時,必須鎖定在視埠焦點中:
- 容器隔離: 側邊欄必須位於一個與主要內容區域高度相符的欄位容器內。
- Position Sticky 規範: 使用
position: sticky; top: calc(var(--header-height) + var(--space-l));來設定小工具樣式。這可防止小工具滑到主導航列後面或與其重疊。 - 頁尾邊界鎖定: 確保黏性小工具的父層欄位具有
overflow: visible(或妥善包含在 Grid 彈性容器內),讓瀏覽器自然地在頁尾或底部區段處停止小工具的滾動。
5. 防止鍵盤焦點遮蔽(無障礙核心)
網頁設計中最常見的無障礙失敗之一,是當鍵盤 Tab 使用者聚焦到某個連結時,該連結卻被黏性頁首或底部 Dock 遮擋(違反 WCAG 2.2 SC 2.4.11 焦點不被遮蔽)。
- Scroll Margin Top: 為所有目標區段、標題(
h2、h3)和關鍵互動目標套用全域的scroll-margin-top::target, [id] { scroll-margin-top: calc(var(--header-height) + var(--space-m)); } - 焦點內距: 如果互動元素接收到鍵盤焦點,瀏覽器檢視必須滾動,使該元素完全位於任何持久黏性覆蓋層的邊界之外且可見。
- 逃生口: 如果從黏性元素開啟了模態框或下拉選單,則應鎖定焦點(使用
focus-trap-implementation),並將背景頁面內容設為inert。
6. 設計浮動動作按鈕(FAB)與回到頂端觸發器
FAB 位於視埠較低的角落,提供快速、次要的全域公用程式。
- 基於閾值的進入: 在使用者滾動至少兩個完整視埠之前(scrollY > 200% VH),隱藏「回到頂端」觸發器。觸發後,以淡入和縮放效果顯示它(從
scale(0.8); opacity: 0;轉換為transform: scale(1); opacity: 1;)。 - 視埠偏移: 在桌面上,FAB 至少應距離右側視埠邊緣
24px,在行動裝置上則為16px。 - 避免目標阻擋: 將 FAB 定位在與主要內容閱讀線水平相反的位置。確保它們在滾動到頁面底部時,不會阻擋頁尾中的連結、社群圖示或內嵌導航。
決策規則
- 靜態與漸進式頁首: 如果網站是任務繁重的 Web 入口網站或電子商務商店,且搜尋和篩選功能經常被使用,請使用靜態黏性頁首。對於文章版面、內容行銷或銷售著陸頁(垂直閱讀區域是優先考量),請使用漸進式黏性頁首。
- 底部 Dock 與內嵌 CTA: 在行動裝置上,如果頁面包含單一高價值轉換目標(例如註冊或購買),請使用底部固定 CTA。如果頁面有多個競爭且優先權相同的動作,請勿使用底部 Dock。
- FAB 尺寸與觸控區域: 確保浮動觸發器是圓形或圓角卡片。視覺元素直徑至少為
48px,實際互動點擊容器必須滿足至少44x44px的最小足跡(WCAG 2.2 建議),以方便拇指操作。 - 漸進式模糊與純色: 使用
backdrop-filter: blur(8px)搭配輕微透明的顏色(例如rgba(255, 255, 255, 0.8)),而非完全不透明的背景。這能維持視覺深度感,並讓使用者感知到黏性框架後方的滾動進度。
限制條件
- 無障礙(WCAG AA 最低標準):
- SC 2.4.11 焦點不被遮蔽(最低標準): 高對比的焦點環絕不可被黏性元素隱藏。確保元素可以順暢地以 Tab 鍵操作,而不會被頁首或頁尾阻擋。
- SC 2.5.8 目標尺寸(最低標準): 黏性工具列和 FAB 中的所有互動目標必須至少為 24x24px,對於行動底部 Dock 的主要拇指觸發器,建議尺寸為 44x44px。
- 無 Tab 陷阱: 鍵盤使用者必須能夠使用標準的
Tab/Shift+Tab導航進入和離開黏性工具列控制項。
- 響應式(版面穩定性):
- 黏性層絕不能造成水平視埠溢出。使用基於百分比的寬度或
left: 0; right: 0;的版面,並搭配精確的 box-sizing 限制。 - 在行動裝置上,將桌面黏性側邊欄轉換為簡單的內嵌面板,或將其收合至底部抽屜中。
- 黏性層絕不能造成水平視埠溢出。使用基於百分比的寬度或
- 版面位移緩解(CLS):
- 千萬不要在沒有保留其原始空間體積的情況下,動態地將元素從
position: static更改為position: fixed。切換為fixed會立即使其原始容器高度崩潰,導致巨大的累計版面位移(CLS)。相反地,應該使用position: sticky(它會保留版面空間),或在預先保留的容器內切換樣式。
- 千萬不要在沒有保留其原始空間體積的情況下,動態地將元素從
常見失敗模式
- 焦點阻擋面紗: 鍵盤使用者以 Tab 鍵瀏覽頁面,但焦點環落在完全被黏性頁首隱藏的連結上,使它們無法被看見。
- iOS Home Indicator 重疊: 在行動底部工具列上未添加
env(safe-area-inset-bottom),導致原生 OS 滑動手勢條直接壓在「立即購買」按鈕上。 - 抖動的滾動迴圈: 使用 JavaScript 設定一個恰好在邊界線觸發的滾動轉換,導致黏性工具列在可見與隱藏狀態之間快速視覺抖動。
- 視埠三明治: 在小型行動裝置上同時啟用一個厚的黏性頁首和一個厚的黏性底部工具列,將可讀螢幕空間縮小到僅剩可憐的 40% 視窗。
- CLS 瞬間崩潰: 在滾動時將頁首切換為
fixed,導致主要頁面內容瞬間向上彈跳80px,使使用者迷失方向。
驗證標準
- 視埠面積檢查: 黏性元素在桌面或行動裝置上絕不佔用超過垂直視埠的 15%。
- 焦點保護(SC 2.4.11): 所有鍵盤聚焦的元素在持久黏性元素的邊界之外保持完全可見。已設定全域
scroll-margin-top。 - 行動安全區域對齊: 行動底部 Dock 明確使用
env(safe-area-inset-bottom)以防止與裝置控制項重疊。 - 觸發閾值邏輯: 行動底部 Dock 在初始 Hero 視埠中保持隱藏,僅在通過 Hero CTA 後才淡入/移入。
- 版面位移預防: 漸進式頁首和黏性側邊欄小工具使用
position: sticky樣式,或放置在預先測量好的容器中,以保證零累計版面位移(CLS)。 - 無重疊衝突: 疊加上下文 z-index 已清楚對映並記錄,以防止重疊視覺錯誤。
- 目標足跡: 行動 Dock 觸發器和 FAB 符合 44x44px 的觸控目標偏好設定。