溢位

CSS Podcast - 034:溢位

如果內容超出父項範圍,您可以選擇多種處理方式。你可以捲動畫面來新增額外空間、裁剪溢出的邊緣、以省略號表示截斷處等等。針對手機應用程式和多種螢幕尺寸開發時,溢位問題尤其重要。

CSS 提供兩種不同的剪裁選項;text-overflow 可協助處理個別文字行,而 overflow 屬性則可協助控制方塊模型中的溢位。

單行溢位與 text-overflow

在包含文字節點的任何元素上使用 text-overflow 屬性,例如段落 <p>。這個屬性會指定文字在元素可用空間不足時的顯示方式。網頁上所有可檢視的 HTML 文字都位於文字節點中。如要使用 text-overflow,您需要單行未換行的文字,因此也必須將 overflow 設為 hidden,並提供可防止換行的 white-space 值。

p {
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
}

使用溢位屬性

您可以在元素上設定溢位屬性,控管子項需要的空間超出可用空間時的行為。這可能是刻意為之,例如在 Google 地圖等互動式地圖中,使用者會平移大型圖片,而圖片會裁剪成特定大小。也可能是無意間發生,例如使用者在即時通訊應用程式中輸入的訊息過長,無法完整顯示在文字泡泡中。

溢位可分為兩部分。父項元素具有不會變更的嚴格限制空間。您可以將其視為視窗。子項元素是希望與父項之間有更多空間的內容。您可以將此視為透過視窗看到的內容。管理溢出內容有助於引導視窗如何為這項內容設定影格。

在垂直和水平軸上捲動

overflow-y 屬性會控制裝置可視區域垂直軸的實體溢位,因此會向上和向下捲動。

overflow-x 屬性會控制裝置檢視區塊水平軸的溢位,因此會向左和向右捲動。

捲動方向的邏輯屬性

Browser Support

  • Chrome: 135.
  • Edge: 135.
  • Firefox: 69.
  • Safari: not supported.

Source

overflow-inlineoverflow-block 屬性會根據文件方向和書寫模式設定溢位。

overflow 簡寫

overflow 簡寫可在一行中同時設定 overflow-xoverflow-y 樣式:

overflow: hidden scroll;

如果指定兩個關鍵字,第一個會套用至 overflow-x,第二個則套用至 overflow-y。否則,overflow-xoverflow-y 會使用相同的值。

進一步瞭解 overflow 屬性可用的值和關鍵字

overflow: visible (預設)
如未設定屬性,網頁的預設值為 overflow: visible。這可確保內容不會意外遭到隱藏,並遵循「絕不隱藏內容」或「精確版面配置的安全版面配置」的核心原則。
overflow: hidden
overflow: hidden 內容會沿指定方向裁剪,且不會提供捲軸來顯示內容。
overflow: scroll
overflow: scroll 可啟用捲軸,讓使用者捲動瀏覽內容。即使內容未溢出,也會顯示捲軸。舉例來說,如果容器日後可能會根據大小調整而變成可捲動,這就是減少日後版面配置位移的好方法,也能讓使用者在視覺上做好準備,迎接可捲動區域。
overflow: clip
overflow: hidden 類似,overflow: clip 會將內容裁剪至元素的邊框間距方塊。cliphidden 的差異在於,clip 關鍵字也會禁止所有捲動,包括程式輔助捲動。
overflow: auto
最後,最常用的值是 overflow: auto。這項設定會尊重使用者的偏好設定,並視需要顯示捲軸,但預設會隱藏捲軸,並將捲動責任交給使用者和瀏覽器。

捲動和溢位

許多這類 overflow 行為都會導入捲軸,但有幾種特定的捲動行為和屬性可協助您控管溢位容器的捲動。

捲動和無障礙功能

請務必確保可捲動區域可接受焦點,讓鍵盤使用者可以按 Tab 鍵前往方塊,然後使用方向鍵捲動。

如要允許捲動方塊接受焦點,請新增 tabindex="0"、具有 aria-labelledby 屬性的名稱,以及適當的 role 屬性。例如:

<div tabindex="0" role="region" aria-labelledby="id-of-descriptive-text">
    content
</div>

接著,您可以使用 CSS 指出方塊已成為焦點,並使用 outline 屬性提供視覺提示,表示方塊現在可捲動。

在「使用 CSS 強制執行無障礙功能」中,Adrian Roselli 示範如何使用 CSS 避免無障礙功能回歸。舉例來說,只有在使用正確的屬性時,才開啟捲動功能並新增焦點指標。只有當方塊具有 tabindexaria-labelledbyrole 屬性時,下列規則才會讓方塊可捲動。

[role][aria-labelledby][tabindex] {
  overflow: auto;
}

[role][aria-labelledby][tabindex]:focus {
  outline: .1em solid blue;
}

方塊模型中的捲軸位置

捲軸會占用邊框間距方塊內的空間,如果使用 inline 而非 overlaid,捲軸可能會與其他元素爭奪空間。方塊模型模組會進一步說明這個潛在的版面配置位移來源。

根捲軸與隱含捲軸

您可能會發現,部分捲軸具有「下拉以重新整理」行為和其他特殊行為,特別是在開發行動裝置和混合式應用程式時。這項捲動行為發生在根捲動器上。一個頁面只會有一個根捲軸。根據預設,documentElement 是網頁的根捲軸,但只要變更根捲軸的元素,特殊行為就能套用至 documentElement 以外的捲軸,我們將這個新捲軸稱為隱含根捲軸。

如要建立根捲軸,您可以將容器設為固定位置,確保容器涵蓋整個檢視區塊,並使用 z 索引將容器置於捲軸頂端,這就是所謂的「捲軸升級」。請參閱這個頁面,體驗根捲動器與巢狀隱含捲動器。

影片顯示具有彈跳行為和新樣式功能的根捲軸,
相較於捲動沒有強化捲動行為的隱含捲軸。

設定捲軸樣式

您可以設定捲軸樣式,將其納入網站設計。scrollbar-color 設定捲軸的滑桿和凹槽顏色。

如要變更捲軸寬度,請使用 scrollbar-width。您無法將此屬性設為任意長度,但可以指定要使用 thin 捲軸或 none

scroll-behavior

Browser Support

  • Chrome: 61.
  • Edge: 79.
  • Firefox: 36.
  • Safari: 15.4.

Source

scroll-behavior 可讓您選擇由瀏覽器控制元素捲動。您可以藉此指定如何處理網頁內瀏覽 (例如 .scrollTo() 或連結)。

搭配 prefers-reduced-motion 時,可根據使用者偏好設定指定捲動行為,特別實用。

@media (prefers-reduced-motion: no-preference) {
  .scroll-view {
    scroll-behavior: auto;
  }
}

overscroll-behavior

Browser Support

  • Chrome: 63.
  • Edge: 18.
  • Firefox: 59.
  • Safari: 16.

Source

如果您曾捲動至強制回應疊加層的結尾,然後繼續捲動,導致疊加層後方的頁面移動,這就是捲動鏈結或向上冒泡至父項捲動容器。overscroll-behavior 屬性可防止溢位捲動洩漏至父項容器 (稱為捲動鏈結)。

捲動貼齊

捲動通常很順暢,可讓您將內容放置在 scrollport 內的任何位置。對於某些設計 (例如圖片庫或模擬網頁/投影片的內容),您可能希望內容貼齊捲動檢視區塊。

設定捲動容器

如要啟用捲動貼齊功能,請將 scroll-snap-type 新增至捲動容器。首先,請定義捲動貼齊的軸向。可以是邏輯屬性 (blockinline)、實體屬性 (xy),或是 both

您也可以定義捲動貼齊的嚴格程度。預設嚴格程度為 proximity,表示捲動容器會盡可能對齊。您也可以將嚴格程度設為 mandatory,確保捲動容器一律會對齊。

.scroll-container {
    scroll-snap-type: block mandatory;
}

捲動貼齊功能會將元素對齊捲動容器的完整界線,但如果捲動容器的部分內容無法顯示,會發生什麼情況?舉例來說,您可能有一個固定標頭,會疊加在捲動容器的部分位置。 tuck 屬性可協助將貼齊的元素對齊捲動容器的可見部分。scroll-padding

控制可對齊的元素

如要讓元素可對齊格線,請將 scroll-snap-align 屬性設為 startendcenter。如果捲動貼齊方向為 both,您可以設定兩個值。這項設定會決定元素邊緣是否要與捲動埠邊緣對齊,或是要置中。

您可以使用 scroll-margin 調整對齊元素邊緣周圍的間距:

捲動至元素時,scroll-margin 也會用於設定邊框間距:

如要讓捲動更具黏性,可以在捲動容器中為項目新增 scroll-snap-stop: always。但不會阻止您在單次捲動時略過多個項目。如果捲動動作結束時,捲動會因慣性繼續,捲動會在下一個對齊位置結束,而不是繼續捲動。

隨堂測驗

文字溢位和元素溢位是否相同?

true
與元素溢位相比,文字溢位較為特殊。
false
文字溢位通常是指行內溢位,而元素溢位則是指區塊溢位。

overflow 屬性接受 2 個關鍵字,第一個關鍵字是哪個軸?

橫向
🎉
直向
幾乎在所有情況下,傳遞兩個簡寫值時,第一個值都是水平方向。

捲軸顯示和內嵌時,會佔用方塊模型中的哪個空間?

內容方塊
請再試一次!
邊框間距方塊
overlay 模式下的捲軸會與邊框間距重疊,而 inline 模式下的捲軸則會加入邊框間距。
邊框方塊
請再試一次!
邊界方塊
請再試一次!

如要擷取巢狀內隱式捲動器中捲動產生的額外動量,您會使用哪個屬性?

scroll-behavior
請再試一次!
scroll-hint
請再試一次!
overscroll-behavior
將這個屬性設為 contain 會導致捲動受限。
scroll-padding
請再試一次!
overscroll-effect
請再試一次!

哪個值會宣告捲動容器必須盡可能停在已對齊的元素上?

required
答錯了。
mandatory
答對了!
0px
答錯了。
proximity
答錯了。

scrollbar-width 的有效值為何?

5px
答錯了。
thin
答對了!
medium
答錯了。
none
答對了!

資源

Smashing Magazine 的 CSS 溢位和資料遺失