Topics

Overlooked accessibility issues with clamp() spacing—and how to fix them

  • column

Using clamp() to scale spacing between minimum and maximum values has become quite common lately.

While extremely convenient for responsive design, accessibility zoom features reveal a subtle pitfall.

Common clamp() usage examples

For instance, when adjusting spacing with clamp(), you might typically write something like this:

: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)
  );
}

Without going into detail, essentially:

  • On mobile, the size of --spacing-lg-min
  • On desktop, the size of --spacing-lg-max
  • In between, it expands and contracts smoothly.

and is a very user-friendly pattern.

What are the accessibility pitfalls?

The problem arises when trying to comply with WCAG 2.0 Success Criterion 1.4.4 "Resize text".

This criterion was originally established before smartphones became widespread, with the intent that content should remain viewable when enlarged up to 200% on a PC. However, the same condition applies to smartphone browsers.

When you actually enlarge to 200% on a smartphone, you tend to see phenomena like this.

  1. Text enlargement (zoom) causes rem-based spacing to scale up along with it.
  2. As a result, the spacing around the original content becomes excessively wide.
  3. This leads to the content display area becoming extremely narrow, resulting in layout breakage and poor readability.

* In reality, even looking at government sites overseas where WCAG compliance is mandatory, it seems implementation is not widely done. It is likely that practical projects consider this "not a major issue even if not implemented" due to cost-effectiveness and the fact that there is almost no actual demand for zooming to 200% on a smartphone.

How do you solve this issue?

Instead of rem, which is affected by text enlargement, use viewport-based units like vw, and it's important to avoid making spacing unnecessarily large when zooming.

However, if you specify only vw, you won't be able to take advantage of clamp()'s benefit of controlling minimum and maximum values.

This is where the min() function comes in!

min() adopts the smallest value among the values passed to it. By using this characteristic, you can switch which value is applied between normal and enlarged displays.

Here's how to write it.

--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)
  )
);

When displayed at 375 CSS px, the first value of min becomes 6.4vw, which is --spacing-lg-min (24px) converted to vw.

The minimum value of clamp() is 1.5rem = 24px, but at 200% enlargement it becomes 48px, so 6.4vw on the left becomes smaller and will be applied.

In other words,

  • Normal display (100%):
    • The clamp() value becomes smaller than the vw-based value.
    • Since min() selects the smaller value, clamp() takes effect and the display scales responsively with the viewport width.
  • When zoomed (200% display):
    • The rem values inside clamp() increase with zoom, making the vw-based value smaller.
    • The vw-based value is applied, and spacing is locked to a ratio of viewport width, preventing excessive enlargement.

This way, you can achieve both responsive usability and accessibility considerations!

* Note: On desktop displays, enlarging padding along with the design often maintains visual balance, so --clamp-viewport-min is applied only to smartphones.

Comparing the actual behavior

Top is clamp only, bottom is min + clamp.

When you zoom to 200% on a smartphone, the difference becomes clear.

Note: On iOS Safari, you can zoom from the icon on the left of the address bar. On Android Chrome, use the icon in the top right.

Summary

  • clamp() is convenient for responsive spacing adjustments
  • However, zooming in can enlarge the spacing as well, which may cause layout shifts
  • By combining with min(), you can achieve flexible spacing at normal zoom and controlled spacing when zoomed

If you're concerned about WCAG compliance, incorporating these implementations provides peace of mind. While implementations that "account for up to 200% zoom on mobile" are still uncommon, they preserve readability in normal viewing while reducing accessibility risks.

By the way, if you want to make fine adjustments beyond spacing, you can also use media queries with narrow breakpoints.

@media (max-width: 239px) {
  /* 拡大時に適用したいCSS */
}

For example, when a 375px-wide screen is zoomed to 200%, the browser calculates the viewport width as "half the size (approximately 188px)". This allows you to target this narrow condition.

Note: The value of 239px is just an example. It's best to adjust it to leave room for larger screens in the future while ensuring normal display isn't affected.

By combining "clamp() + min()" with "narrow breakpoint media queries", you can achieve more flexible and robust accessibility compliance!

About the author of this article

A "master of technique" who jumped from DTP into the web world and, before he knew it, mastered markup, frontend, direction, and accessibility. Active across multiple domains since Liberogic's early days, he's now a walking encyclopedia within the company. Recently, he's been diving deep into prompt-driven efficiency optimization, wondering "Can we rely more on AI for accessibility compliance?" Both his technology and thinking continue to evolve.

Futa

IAAP Certified Web Accessibility Specialist (WAS) / Markup Engineer / Frontend Engineer / Web Director

Read this staff member's article

Reliable team structure and responsive project management are our strengths

At Liberogic, our experienced staff actively drive projects forward, earning high praise from clients.
We carefully assign project managers and directors to ensure smooth project execution across all phases. We prevent unnecessary cost increases from over-commitment by deploying resources strategically, and we're known for speed in project understanding, estimation, and delivery.

* Please note that we do not actively pursue on-site SES-style staffing arrangements.

You can use virtually all major project management and chat tools, including Slack, Teams, Redmine, Backlog, Asana, Jira, Notion, Google Workspace, Zoom, Webex, and more.

Are you struggling with web accessibility compliance?

Case Studies