Respect the Users Preferred Text Size

Currently mobile web browsers rely primarily on ‘pinch-to-zoom’ and ‘page zoom’ to adjust the font size of a web page. A better solution is to design web applications with the user’s system font size in mind. Providing a much better experience without the buggy caveats of ‘page zoom.’ Changing the font size of a web page should feel like this:

Page zoom was recently introduced in iOS 13 (double ‘A’ icon) and although it works better than it’s Android counterpart, results can vary substantially. Users will likely encounter overflow issues and broken web pages.

Chrome on Android doesn’t provide a way to get the system font size. Fortunately, WebKit provides this ability by using “Dynamic Type”:

@supports (font: -apple-system-body) {
:root {
font: -apple-system-body;
}
}

Although “Dynamic Type” was introduced in 2015, it has never been widely adopted in the web. With modern CSS layout tools such as Flexbox and Grid implementing designs that adapt to font size changes should be a breeze.

To specify a custom font family simply override the rules set by -apple-system-body. Make sure when specifying a custom font family to scale the font so it matches what the user expects. The x-height of the custom font should align or be of similar visual size to the system font.

Update Page On Font Size Change

Changing the font size in system settings doesn’t automatically update iOS web views, unless the web page has custom code. To reflect the user’s preference reapply -apple-system-body using the following code on events such as ‘focus’ or ‘visible’:

if (CSS.supports('font: -apple-system-body')) {
document.documentElement.style.font = '-apple-system-body'
}

Then to get the pixel value of the new font size, use the following:

rootComputedStyle = window.getComputedStyle(document.documentElement)
rootFontSize = rootComputedStyle.getPropertyValue('font-size')

To accurately get the root font size, make sure there are no custom defined font-size rules in html or :root selectors.

The following implementation includes a simple type scale based on Apple’s typography guidelines.

View Example

Wishlist

Browsers need to give us the tools so we as designers/developers can make our applications react properly to the user’s preferred font size. There are plenty of important design choices at different font sizes and simply scaling a design is not enough.

Unfortunately, CSS provides little support for creating rules based on a specific font size. While most of the following suggestions can be implemented using JavaScript, native CSS support would be preferable:

Font Size Media Query

Add a prefers-font-size media feature, which detects if the user prefers a specified font size:

@media (prefers-font-size: 32px) {}

Allowing rules that define a more appropriate type scale, tighter margins, spacing, etc. Providing developers the ability to make adjustments to the application’s layout will greatly increase usability at more accessible font sizes.

Rerender Page on Font Size Change

If a user changes their OS or browser font size setting, the browser should automatically rerender the page. A standard and consistent behavior should be adopted across browsers. In iOS, changing the system font setting doesn’t automatically rerender open pages. The user has to manually refresh the page for the new setting to take effect.

Font Size Change Event
document.addEventListener("fontsizechange", () => {})

Before the browser decides to rerender the page this event should be called. It’s specially helpful for JavaScript based web applications.

Font Size Min and Max Support
font-size: max(calc(1rem - 6px), 11px);
font-size: max(0.7rem, 11px);

In the example provided above, styles such as ‘Captions’ are lower than 11px when the root font size is 16px or smaller. Currently adding a min or max in font-size is not well supported, the good news is a similar feature font-min-size/font-max-size might arrive in ‘CSS Fonts 4’.

Environment Variable
env(prefers-font-size);

Makes the code more readable and most importantly it’s defined as a constant, changing font-size in :root or html selectors shouldn’t change its value.

Further Discussion

After the release of iOS 10, WebKit started to ignore the user-scalable=no viewport setting. Allowing ‘pinch-to-zoom’ everywhere was necessary because websites were picking a “text size that was unreadable while giving the user no way to zoom” (Jackson 2017). I would like to discuss why WebKit should now stop ignoring this viewport setting for certain cases.

References

Burzo, Dan. “Making Sense of Units in CSS Media Queries (in the Year 2019).” Journal, 29 Sept. 2019, [Link].

Jackson, Dean. “New Interaction Behaviors in iOS 10.” WebKit, 2 Feb. 2017, [Link].

Kalbag, Laura. “Adding IOS Dynamic Type Support to Better.” Indie, 17 Apr. 2017, [Link].

Kasemset, Clare, and Nandini Sundar. “Building Apps with Dynamic Type.” WWDC 2017, Apple Inc., 5 June 2017, [Link].

Kane, Lexie. “Usability for Seniors: Challenges and Changes.” Nielsen Norman Group, 8 Sept. 2019, [Link].

Kieleithner, Stefan. “Improving Dynamic Type Support: Inside PSPDFKit.” PSPDFKit, 17 Oct. 2018, [Link].

Komarov, Roman. “Conditions for CSS Variables.” Articles & Experiments, 21 Oct. 2016, [Link].

Maxfield, Myles. “Using the System Font in Web Content.” WebKit, 21 July 2015, [Link].

Nielsen, Jakob. “Let Users Control Font Size.” Nielsen Norman Group, 18 Aug. 2002, [Link].

Rutter, Richard. Web Typography: A Handbook for Designing Beautiful and Effective Responsive Typography. Ampersand Type, 2017.

“Typography.” Human Interface Guidelines, Apple Inc., 10 July 2018, [Link].

“Web Content Accessibility Guidelines (WCAG) 2.1.” W3C, 5 June 2018, [Link].

Published