留白的調整使用 clamp() 以最小值~最大值進行可變的實作方式,最近相當常見。
作為回應式設計相當便利的做法,但在考慮 無障礙的放大顯示(縮放) 時,確實存在一些需要注意的陷阱。
常見的 clamp() 指定範例
例如,在使用 clamp() 調整留白時,通常會這樣撰寫。
:root {
--clamp-base: 16;
--clamp-viewport-min: 375;
--clamp-viewport-max: 1440;
--spacing-lg-min: 24;
--spacing-lg-max: 48;
--spacing-lg-slope: calc(
(var(--spacing-lg-max) - var(--spacing-lg-min)) / (var(--clamp-viewport-max) - var(--clamp-viewport-min))
);
--spacing-lg-intersection: calc(
(var(--spacing-lg-max) - var(--clamp-viewport-max) * var(--spacing-lg-slope)) / var(--clamp-base)
);
--spacing-lg: clamp(
calc(var(--spacing-lg-min) / var(--clamp-base) * 1rem),
calc(var(--spacing-lg-intersection) * 1rem + 100 * var(--spacing-lg-slope) * 1vw),
calc(var(--spacing-lg-max) / var(--clamp-base) * 1rem)
);
}
詳細說明從略,
- 在智慧型手機上為
--spacing-lg-min的尺寸 - 在 PC 上為
--spacing-lg-max的尺寸 - 在此期間內可以靈活流暢地伸縮
因此非常易於使用的模式。
無障礙設計的陷阱是什麼?
問題出現在嘗試符合WCAG 2.0 成功準則 1.4.4「文字大小調整」的時候。
此準則原本是在智慧型手機普及之前制定的,目的是「在個人電腦上放大至200%仍能瀏覽」,但智慧型手機瀏覽器也適用相同條件。
實際上在智慧型手機上放大至200%時,通常會發生以下現象。
- 由於文字放大(縮放)的進行,以
rem單位為基準的間距也一起被放大。 - 結果導致環繞原有內容的邊距變得過度寬闊。
- 因此內容顯示區域變得極端狹窄,造成版面混亂或難以閱讀的狀況。
※ 不過從現實的角度來看,即使是被要求符合WCAG的海外政府機構網站,似乎也很少實施此項對應。可能由於成本效益考量,以及智慧型手機上放大至200%的需求本身幾乎不存在,導致現場層級認為「即使不進行對應也不會造成重大問題」。
如何解決這個問題?
重要的是使用 vw 等視口基準的單位而非受文字放大影響的 rem,以及 確保即使放大縮放也不會讓間距過度增大。
但是如果只用 vw 指定,就無法發揮 clamp() 「能夠控制最小值和最大值」的優勢。
這時就輪到 min() 函數登場了!
min() 會採用傳入值中「最小的值」。利用這項特性,我們可以在正常顯示和放大時切換所適用的值。
寫法是這樣的。
--spacing-lg: min(
calc(var(--spacing-lg-min) / var(--clamp-viewport-min) * 100vw),
clamp(
calc(var(--spacing-lg-min) / var(--clamp-base) * 1rem),
calc(var(--spacing-lg-intersection) * 1rem + 100 * var(--spacing-lg-slope) * 1vw),
calc(var(--spacing-lg-max) / var(--clamp-base) * 1rem)
)
);
當在 375 CSS px 寬度顯示時,min 的第一個值會是 --spacing-lg-min 的值 24px 轉換為 vw 後的 6.4vw。
clamp() 的最小值是 1.5rem = 24px,但在 200% 放大時會變成 48px,因此左邊的 6.4vw 會更小,這個值就會被應用。
也就是說,
- 正常顯示時(100% 顯示):
clamp()的值會比vw基準的值還要小。- 由於
min()會採用較小的值,所以clamp()會生效,並根據螢幕寬度進行可變顯示。
- 放大時(200%顯示):
clamp()內的rem會因放大而變大,vw基準的值變得更小。vw基準的值會被套用,邊距相對於螢幕寬度的比率會被固定,因此可以防止過度放大。
這樣一來,就可以同時兼顧「回應式的易用性」和「無障礙設計的考量」了!
備註:在 PC 顯示上,邊距連同其他元素一起放大通常能更好地保持設計的平衡,因此--clamp-viewport-min是以此為基準,只在智慧型手機上套用。
實際行為比較
上方是僅使用 clamp,下方是 min + clamp。
在手機上放大到 200% 時,差異會很明顯。
注意:iOS Safari 可以從位址欄左側的圖標放大,Android Chrome 可以從右上角的圖標放大。
總結
- clamp() 在自適應間距調整時非常方便
- 但是放大顯示時,間距也會被放大,可能會導致佈局損毀
- 結合 min() 的使用,可以實現 正常時可變、放大時受控 的平衡方案
如果想要重視 WCAG 合規性,引入這樣的實現方式會很放心。「在行動裝置 200% 放大時也能保持良好表現」的實現方案仍屬罕見,但這樣既能保持日常的易讀性,又能降低無障礙設計方面的風險。
另外,如果想對間距以外的細微之處進行調整,也可以使用指定窄範圍斷點的媒體查詢方法。
@media (max-width: 239px) {
/* 拡大時に適用したいCSS */
}
舉例來說,當寬度為 375px 的螢幕放大至 200% 時,瀏覽器會將視窗寬度計算為「一半的大小(約 188px)」。因此,我們就能針對這個狹窄的條件進行匹配。
注意:239px 只是一個例子,應該在為未來的螢幕尺寸放大留出餘地的同時,確保不會對正常顯示造成影響,據此調整並確定該數值。
結合「clamp() + min()」與「窄範圍斷點的媒體查詢」,就能實現更靈活且可靠的無障礙設計對應!
從 DTP 跨足 Web 世界,轉眼間便掌握了標記語言、frontend 開發、專案指導,以及 accessibility 等各項技能——是名真正的「技術高人」。自 Liberogic 創立初期便展現多才多藝的能力,如今儼然成為公司內的活字典。最近正沉迷於利用 AI 提示詞探索「accessibility 對應能否更多依靠 AI?」的效率化研究。技術與思維都在不斷進化中。
Futa(二)
IAAP 認證網頁無障礙專家(WAS)/ 標記語言工程師 / Frontend 工程師 / 網頁總監