Long live the modern browser!
Browsers are getting better these days. We seem to be in a golden age where there’s a never-ending stream of new features added for the benefit of the users accessing the page, and really great tools for those creating the page. It hasn’t always been the case, though. Earlier versions of today’s browsers had limited features, and we had to consider how to work with — or around— those when designing and developing our sites. Static and adaptive layouts were commonplace, and our sites were designed to pixel perfection. Of course there was a distinct amount of pixel pushing gymnastics involved, though, when implementing our layouts within the constraints the browsers provided.
As browser features matured, and techniques like Fluid Grids became more commonplace, the way we coded our sites evolved into a whole new paradigm. We switched from defining and coding our units of measurement in pixels, and began using relative CSS units and unitless values more consistently in our CSS to meet the needs of ever-changing viewport sizes.
Fast forward to the present, and browser vendors have added in more features to allow us to create flexible and robust designs in a straightforward manner. Take for example, browser zooming. When the user zooms the page in a modern browser, everything scales up — or down — proportionally, depending on the user’s preference. Well, at least it should.
Why is browser zoom a big deal, anyway?
Allowing the user to control their web browsing experience isn’t a new concept, in fact it’s something that’s been written about in the web’s early days. Lately, that concept seems to have been forgotten as the browser features have improved.
The most important reason for using responsive and unitless values in our CSS is for supporting our users that rely on zooming. If you read the Web Content Accessibility Guidelines, our users need to be able to zoom the viewport without loss of content or functionality, or restrictions imposed by CSS values or viewport scaling settings. In particular, there are a some success criteria to be met:
- WCAG 1.4.4: Users must be able to resize text without assistive technology up to 200 percent, without loss of content or functionality. (Level AA)
- WCAG 1.4.8: Ideally, we should provide appropriate spacing between lines and paragraphs, and we shouldn’t be requiring the user to scroll horizontally to read a line of text on a full-screen window. (Level AAA)
- WCAG 1.4.10: Users must be able to resize text without being forced to scroll both horizontally and vertically to read that content. (Level AA)
Design systems and threads of consistency
As someone who works on the O’Reilly Media Design System, weaving threads of consistency across brand, style, and UI components is a top priority. Consistency across a system empowers designers and developers to craft great app experiences for the end user. That said, the most important thread that connects all elements of a design system tapestry is established accessibility best practices — for colors, typography, components, patterns.
In the case of defining a system’s typography styles, standards are established for things like visual hierarchy and rhythm of typography. Oftentimes a designer will begin layouts in Sketch or another design-based program, and specify font sizing and line-height values for typography in pixels. This approach can work well for static layout purposes, but there’s a catch. A pixel-based typography approach will not work as a CSS strategy, though, when browsers — and specifically browser zooming — enter the picture.
The browser zoom debate
At this point in the design system development process, a debate can ensue. In fact, our team had a very spirited debate about this when our design system was being rebooted — and I noticed that our typography CSS styles were using px-based line-height values as defined in Sketch by our designer.
Some of the arguments for using pixels in CSS were: “Browsers handle all the font zooming for us, so we don’t have to convert our typography to relative units in CSS. Users don’t bother to adjust the font display settings in the browser, our work is done here!” <dusts off hands> Some of the rebuttals for using relative CSS units were: “Yes, browsers handle page zoom for us, yet there’s a difference between how the UI appears when the page is zoomed, depending on whether the default browser size has been adjusted as well. Users do bother to adjust the font display settings in the browser so we need to account for that in our CSS declarations.”
And so the research began. When I first started looking up recommendations on whether or not using pixels in CSS in general is a good idea, I’d find conflicting opinions on the subject, such as articles like this one describing why you should just use pixels or should stop using pixels in CSS. Articles about responsive sizing in media queries. Even a good article about Accessibility in Resizing Text about the behavior of older browsers.
There wasn’t much mention — or consideration — that users really do dig into the advanced browser settings to change their default font size. Thankfully, I ran across a mention of it in the MDN docs, a really good article by Evan Minto that dives into the user data, and section in Every Layout’s page on rudimentary units.
Those last three articles were especially interesting, yet even with the amount of information provided, the one thing that had been missing in all of this was a side-by-side example. In particular, an example of what a block of text using pixel values versus a block of text using relative or unitless values looks like in a browser zoom scenario. Especially if the user changes the default font setting under the hood.
What do you mean by default font setting, though?
You may be familiar with a browser’s page zoom setting, which scales up all the contents on the page proportionally. A lesser known feature of most browsers, though, is the option to adjust your preferred font size. This feature operates independently from the page zoom feature. For example, these are the options used for the font size drop-down menu in Chrome’s appearance settings — ranging from the very small (9px) through very large (24px) — with the recommended default of medium set at 16px.
If you change one of those settings in your browser, ideally all your fonts will scale up (or down) proportionately in reference to the size of that font setting. Ideally, that is, if you’re using relative CSS units. This browser font size adjustment won’t have any effect on typography that uses pixels for font-size and/or the line-height. This brings us to the much-needed example.
The side-by-side comparison
Let’s take a look at how a block of text appears in the browser when zoomed in to 200% using different settings for page zoom, and default font size.
This Codepen displays three containers of text at a page zoom setting of 100% and a browser default font size at the recommended setting of medium (16px).
See the Pen by resource11 on CodePen.
The size of the fonts and line-height values are the same, yet use different units of measurement.
- The left container uses pixels for both font-size and line-height.
- The middle container uses rems for font-size and pixels for line-height.
- The right container uses rems for font-size and unitless values for line-height.
If you adjust the page zoom setting of 200% and keep the browser font size at the default medium (16), there won’t be perceivable differences between the containers.
Users may set the browser font size without touching page zoom, so let’s adjust the page zoom setting back to 100% and change your browser’s font size to very large to see if anything changes.
Notice how the text in the middle and right examples that use rems for font-size scale up to a multiple of the root level font size — which is 1.5 times the size of the default font size (16) — yet the example on the left remains the same, because the font’s value is still static (using pixels) rather than responsive (using rems).
Although both the middle and right examples are scaling up the font size properly, notice the line spacing in the block of text in the middle example looks very compressed.
This compressed line spacing is occurring because that center example uses a line-height value set in an absolute length value (pixels) rather than a relative value. That said, it’s noteworthy to mention that setting a length-based or even a percentage-based value for line-height have poor CSS inheritance behavior and can cause unexpected results, like this compressed line spacing in the middle example. Tight line spacing can be tough to parse if you have a cognitive disability, so it’s not recommended to use length-based or even a percentage-based value for line-height, especially if you’re using relative units for font-sizing.
Which brings us back to the left example for a moment. While the left example also uses a length-based value line-height values in combination with its length-based font-size, our goal is to support users that need to change the default font size of their browser. Choosing length-based values for the font-size and line-height in that left example may be solving the compressed line spacing issue, yet isn’t solving the user’s need to display text according to their personal browser font size setting, so using length-based values for line-height isn’t a recommended approach.
The example on the right, however, displays with a comfortable amount of line spacing because it’s using a relative value rather than an absolute value for line-height. Additionally, this value is unitless rather than length-based, which is the recommended best practice for line-height. The unitless line-height value is calculated by dividing the container’s line-height value in pixels by the font-size in pixels. In this case, our initial font-size is 16px and initial line-height value is 24px as represented in the example on the left. When you divide the line-height by font-size 24px/16px, the result is 1.5, a unitless value.
Using that unitless value on the right example rather than using a length-based value allows the line spacing of the container to scale up in proportion to the rem-based font size, while avoiding CSS inheritance issues. The end effect is a more comfortable reading experience for users that choose to zoom in on the page and adjust their default browser font size to their personal preference.
Remember, though, we’re still at a page zoom setting of 100% with the browser font size set to very large. Users may also need to set their page zoom higher while at a very large browser font size. For example, if the user selects a very large browser font size and sets the page zoom to 200%,
this added flexibility can create an even more comfortable reading experience when zoomed in.
If the user also happens to use one of the operating system accessibility settings like the macOS Picture-in-Picture Zoom feature,
using relative CSS units rather than relying solely on pixels really bumps up the reading experience in a low vision scenario.
This additional flexibility gives that control of experience back to the user where it belongs.
Pixel conversion tools
If you haven’t converted pixels to relative units in CSS before, here are some good tools out there to help you get started.
Remember, users really do change their settings under the hood, and we should be maintaining users’ control over their own browsing experience. If you use relative CSS units for your typography styles, you can maintain the fidelity of your layouts without negatively impacting the needs of your users.
Many thanks to the Twenty Four Accessibility team — Scott O’Hara, Liz Davis, and especially Sarah Higley and Carie Fisher — for their editorial expertise!