You could already be conversant in the CSS clamp() perform. You could even be utilizing it to fluidly scale a font measurement primarily based on the browser viewport. Adrian Bece demonstrated the idea in one other Smashing Journal article simply final 12 months. It’s a intelligent CSS “trick” that has been floating round for some time.
However in the event you’ve used the clamp()-based fluid kind method your self, then you will have additionally run into articles that supply a warning about it. For instance, Adrian mentions this in his article:
“It’s essential to reiterate that utilizing rem values doesn’t automagically make fluid typography accessible for all customers; it solely permits the font sizes to reply to person font preferences. Utilizing the CSS clamp perform together with the viewport models to attain fluid sizing introduces one other set of drawbacks that we have to contemplate.”
Right here’s Una Kravets with a number of phrases about it on internet.dev:
“Limiting how giant textual content can get with max() or clamp() may cause a WCAG failure below 1.4.4 Resize textual content (AA), as a result of a person could also be unable to scale the textual content to 200% of its unique measurement. Make certain to check the outcomes with zoom.”
Trys Mudford additionally has one thing to say about it within the Utopia weblog:
“Adrian Roselli fairly rightly warns that clamp can have a knock-on impact on the utmost font-size when the person explicitly units a browser textual content zoom choice. As with all function affecting typography, make sure you check completely earlier than utilizing it in manufacturing.”
Mudford cites Adrian Roselli, who seems to be the core supply of the opposite warnings:
“Once you use vw models or restrict how giant textual content can get with clamp(), there’s a probability a person could also be unable to scale the textual content to 200% of its unique measurement. If that occurs, it’s WCAG failure below 1.4.4 Resize textual content (AA) so make sure to check the outcomes with zoom.”
So, what’s occurring right here? And the way can we handle any accessibility points so we are able to preserve fluidly scaling our textual content? That’s precisely what I wish to focus on on this article. Collectively, we are going to assessment what the WCAG tips say to know the problem, then discover how we’d be capable to use clamp() in a manner that adheres to WCAG Success Criterion (SC) 1.4.4.
WCAG Success Criterion 1.4.4
Let’s first assessment what WCAG Success Criterion 1.4.4 says about resizing textual content:
“Aside from captions and photos of textual content, textual content may be resized with out assistive know-how as much as 200 p.c with out lack of content material or performance.”
Usually, if we’re setting CSS font-size to a non-fluid worth, e.g., font-size: 2rem, we by no means have to fret about resizing habits. All fashionable browsers can zoom as much as 500% with out further assistive know-how.
So, what’s the take care of sizing textual content with viewport models like this:
h1 {
font-size: 5vw;
}
Right here’s a easy instance demonstrating the issue. I counsel viewing it in both Chrome or Firefox as a result of zooming in Safari can behave in a different way.
The textual content solely scales as much as 55px, or 1.67 instances its unique measurement, though we zoomed your complete web page to 5 instances its unique measurement. And since WCAG SC 1.4.4 requires that textual content can scale to at the least two instances its unique measurement, this straightforward instance would fail an accessibility audit, at the least in most browsers at sure viewport widths.
Certainly this could’t be an issue for all clamped font sizes with vw models, proper? What about one which solely will increase from 16px to 18px:
h1 {
font-size: clamp(16px, 15.33px + 0.208vw, 18px);
}
The vw a part of that internal calc() perform (clamp() helps calc() with out explicitly declaring it) is so small that it couldn’t presumably trigger the identical accessibility failure, proper?
Certain sufficient, though it doesn’t get to fairly 500% of its unique measurement when the web page is zoomed to 500%, the scale of the textual content actually passes the 200% zoom laid out in WCAG SC 1.4.4.
So, clamped viewport-based font sizes fail WCAG SC 1.4.4 in some instances however not in others. The one recommendation I’ve seen for figuring out which conditions move or fail is to test every of them manually, as Adrian Roselli initially urged. However that’s time-consuming and imprecise as a result of the capabilities don’t scale intuitively.
There have to be some relationship between our inputs — i.e., the minimal font measurement, most font measurement, minimal breakpoint, and most breakpoint — that may assist us decide after they pose accessibility points.
Considering Mathematically
If we take into consideration this drawback mathematically, we actually wish to be sure that z₅(v) ≥ 2z₁(v). Let’s break that down.
z₁(v) and z₅(v) are capabilities that take the viewport width, v, as their enter and return a font measurement at a 100% zoom degree and a 500% zoom degree, respectively. In different phrases, what we wish to know is at what vary of viewport widths will z₅(v) be much less than 2×z₁(v), which represents the minimal measurement outlined in WCAG SC 1.4.4?
Utilizing the primary clamp() instance we checked out that failed WCAG SC 1.4.4, we all know that the z₁ perform is the clamp() expression:
z₁(v) = clamp(16, 5.33 + 0.0333v, 48)
Discover: The vw models are divided by 100 to translate from CSS the place 100vw equals the viewport width in pixels.
As for the z₅ perform, it’s tempting to suppose that z₅ = 5z₁. However bear in mind what we discovered from that first demo: viewport-based models don’t scale up with the browser’s zoom degree. This implies z₅ is extra appropriately expressed like this:
z₅(v) = clamp(16*5, 5.33*5 + 0.0333v, 48*5)
Discover: This scales all the pieces up by 5 (or 500%), apart from v. This simulates how the browser scales the web page when zooming.
Let’s characterize the clamp() perform mathematically. We will convert it to a piecewise perform, that means z₁(v) and z₅(v) would finally appear like the next determine:
We will graph these capabilities to assist visualize the issue. Right here’s the bottom perform, z₁(v), with the viewport width, v, on the x-axis:
This seems about proper. The font measurement stays at 16px till the viewport is 320px huge, and it will increase linearly from there earlier than it hits 48px at a viewport width of 1280px. To date, so good.
Right here’s a extra fascinating graph evaluating 2z₁(v) and z₅(v):
Can you see the accessibility failure on this graph? When z₅(v) (in inexperienced) is lower than 2z₁(v) (in teal), the viewport-based font measurement fails WCAG SC 1.4.4.
Let’s zoom into the bottom-left area for a more in-depth look:
This determine signifies that failure happens when the browser width is roughly between 1050px and 2100px. You may confirm this by opening the unique demo once more and zooming into it at completely different viewport widths. When the viewport is lower than 1050px or higher than 2100px, the textual content ought to scale as much as at the least two instances its unique measurement at a 500% zoom. However when it’s in between 1050px and 2100px, it doesn’t.
Trace: We have now to manually measure the textual content — e.g., take a screenshot — as a result of browsers don’t present zoomed values in DevTools.
Basic Options
For simplicity’s sake, we’ve solely targeted on one clamp() expression thus far. Can we generalize these findings by some means to make sure any clamped expression passes WCAG SC 1.4.4?
Let’s take a more in-depth take a look at what’s taking place within the failure above. Discover that the issue is induced as a result of 2z₁(v) — the SC 1.4.4 requirement — reaches its peak earlier than z₅(v) begins rising.
When would that be the case? Every little thing in 2z₁(v) is scaled by 200%, together with the slope of the road (v). The perform reaches its peak worth on the similar viewport width the place z₁(v) reaches its peak worth (the utmost 1280px breakpoint). That peak worth is 2 instances the utmost font measurement we would like which, on this case, is 2*48, or 96px.
Nevertheless, the slope of z₅(v) is similar as z₁(v). In different phrases, the perform doesn’t begin rising from its lowest clamped level — 5 instances the minimal font measurement we would like — till the viewport width is 5 instances the minimal breakpoint. On this case, that’s 5*320, or 1600px.
Serious about this usually, we are able to say that if 2z₁(v) peaks earlier than z₅(v) begins rising, or if the utmost breakpoint is lower than 5 instances the minimal breakpoint, then the height worth of 2z₁(v) have to be lower than or equal to the height worth of z₅(v), or two instances the utmost worth that’s lower than or equal to 5 instances the minimal worth.
Or easier nonetheless: The utmost worth have to be lower than or equal to 2.5 instances the minimal worth.
What about when the utmost breakpoint is greater than 5 instances the minimal breakpoint? Let’s see what our graph seems like once we change the utmost breakpoint from 1280px to 1664px and the utmost font measurement to 40px:
Technically, we might get away with a barely greater most font measurement. To determine simply how a lot greater, we’d have to unravel for z₅(v) ≥ 2z₁(v) on the level when 2z₁(v) reaches its peak, which is when v equals the utmost breakpoint. (Hat tip to my brother, Zach Barvian, whose wonderful math abilities helped me with this.)
To save lots of you the mathematics, you’ll be able to mess around with this calculator to see which mixtures move WCAG SC 1.4.4.
Conclusion
Summing up what we’ve lined:
If the utmost font measurement is much less than or equal to 2.5 instances the minimal font measurement, then the textual content will at all times move WCAG SC 1.4.4, at the least on all fashionable browsers.
If the utmost breakpoint is higher than 5 instances the minimal breakpoint, it’s attainable to get away with a barely greater most font measurement. That mentioned, the rise is negligible, and that may be a giant breakpoint vary to make use of in follow.
Importantly, that first rule is true for non-fluid responsive kind as properly. In case you open this pen, for instance, discover that it makes use of common media queries to extend the h1 component’s measurement from an preliminary worth of 1rem to 3rem (which violates our first rule), with an in-between cease for 2rem.
In case you zoom in at 500% with a browser width of roughly 1000px, you will note that the textual content doesn’t attain 200% of its preliminary measurement. This is sensible as a result of in the event you have been to explain 2z₁(v) and z₅(v) mathematically, they might be even easier piecewise capabilities with the identical most and minimal limitations. This guideline would maintain for any perform describing a font measurement with a recognized minimal and most.
Sooner or later, in fact, we might get extra instruments from browsers to deal with these points and accommodate even bigger most font sizes. Within the meantime, although, I hope you discover this text useful when constructing responsive frontends.
Subscribe to MarketingSolution.
Receive web development discounts & web design tutorials.
Now! Lets GROW Together!