Topics

clamp() 的留白指定中容易忽視的無障礙問題與解決方案

  • column

留白的調整使用 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%時,通常會發生以下現象。

  1. 由於文字放大(縮放)的進行,以rem單位為基準的間距也一起被放大
  2. 結果導致環繞原有內容的邊距變得過度寬闊
  3. 因此內容顯示區域變得極端狹窄,造成版面混亂或難以閱讀的狀況。

※ 不過從現實的角度來看,即使是被要求符合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 工程師 / 網頁總監

查看此員工的文章

信心十足的團隊體制與迅速的應對能力是我們的優勢

Liberogic 擁有經驗豐富的人員積極推進專案,因而獲得客戶的高度評價。
我們恰當地安排專案經理和總監,致力於順利推進整個專案。 我們避免不必要的全面投入而導致成本增加,而是採用適材適所配置資源的方式,因此在業務把握到估價制作與提交的速度上也備受好評。

請注意,我們不積極進行 SES 形式的駐場業務。

Slack、Teams、Redmine、Backlog、Asana、Jira、Notion、Google Workspace、Zoom、Webex 等幾乎所有主要的專案管理工具和聊天工具都可供您使用。

您是否在網頁無障礙服務方面遇到困難?

案例分析