Rethinking Textual content Resizing on Internet. Airbnb has made important strides in… | by Steven Bassett | The Airbnb Tech Weblog | Might, 2024

To raised perceive the accessibility problem, allow us to discover how browser zoom performance works. It’s possible you’ll already be accustomed to this characteristic, utilizing keyboard shortcuts like Command / Ctrl + or Command / Ctrl — to scale all content material inside a window. While you improve the zoom degree past 100%, the viewport’s peak and width proportionally lower, whereas the content material is blown as much as match the bigger window.

As a part of our accessibility testing technique, we had been utilizing browser zoom to check the usability of our pages each on desktop and cellular sizes. Desktop testing confirmed that our pages did comparatively properly on the 200% zoom degree with our responsive internet method throughout the location. We noticed fewer points within the general person expertise when in comparison with cellular internet.

This works properly on desktop, the place we serve a smaller breakpoint (e.g., large to compact) and the viewport is comparatively spacious. Nonetheless, the restrictions of browser zoom turn out to be extra pronounced on cellular internet, the place the viewport is smaller. If we had been to scale the content material in a cellular viewport, it must match right into a viewport that’s half the width and half the peak of the unique. This may end up in important accessibility points, because the textual content and UI components turn out to be extraordinarily tough to learn and work together with. As proven within the picture on the fitting, the flexibility to view even a single itemizing inside a display’s value of house just isn’t doable with out scrolling, resulting in a irritating expertise.

A larger phone showing Airbnb homepage at 100% and a scaled version of the homepage at half the size. 200% Zoom is half the viewport size.
Airbnb’s homepage proven at browser zoom 100% on the left, and the identical display proven at 200% exhibiting the search and classes are reduce off solely and never capable of even see the primary itemizing.

Font scaling is the time period we’ll use to explain the flexibility to regulate textual content measurement independently of general web page zoom. Not like browser zoom, which scales all content material proportionally, Font Scaling applies solely to the textual content components on the web page. This permits customers to customise the font measurement to their most popular studying measurement with out affecting a lot of format or responsiveness of the remainder of the content material.

Font Scaling, can also be the time period we are going to use for scaling the font based mostly on a person’s most popular measurement. Not like zoom, this setting shall be utilized to all websites. Beneath is an instance of how the font scaling applies to simply the textual content on the display, exhibiting that the one scale of the textual content will increase, as a substitute of all of the content material.

Video Description: Airbnb textual content is scaled by setting the font measurement on arc browser, exhibiting the scaling from 16px to 32xp.

This idea of impartial font scaling is just like the Dynamic Kind characteristic on iOS, as we mentioned in our weblog publish “Supporting Dynamic Kind at Airbnb”. Dynamic Kind permits customers to set a most popular system-wide textual content measurement, which then mechanically adjusts the font measurement throughout all suitable apps.

Contemplating our current methods for accessibility on iOS, incorporating font scaling (vs zoom scaling) into our internet accessibility method was a pure subsequent step to assist add parity in approaches throughout our platforms.

Now that we perceive why font scaling is so highly effective for cellular internet, we should always deal with why we would select one CSS size unit over one other for supporting font scaling. On this weblog publish we’re solely going to deal with px, em and rem however there are different items as properly. CSS size items are linked to font scaling as a result of they decide how textual content and different components are sized on an online web page. Some size items are mounted, which means they don’t change based mostly on the person’s font measurement settings, whereas others are relative, which means they scale proportionally with the font measurement.

Let’s take a deep have a look at 3 CSS size items and the way they relate to font scaling:

  • px items are essentially the most generally used on the internet, theoretically they need to symbolize one pixel on the display. They’re a hard and fast unit which means the rendered worth doesn’t change.
  • em items nevertheless are a relative unit which can be based mostly on the guardian component’s font measurement. The title ‘em’ comes from the width of the capital letter ‘M’ in a given typeface, which was historically used because the reference level for font sizes. 1 em unit is the same as the peak of the present font measurement, roughly 16px on the default worth. em items scale proportionally, to allow them to be affected by their guardian’s font sizes
  • rem items, quick for “root em”, are just like em items in that they’re proportional to font measurement, however they solely use the basis component (the html component) to calculate their font measurement. Which means rem items supply font scaling, however will not be affected by their guardian’s font measurement.

The selection between em and rem items typically comes all the way down to the extent of management and predictability required for font scaling. Whereas em items can be utilized, they will result in cascading font measurement adjustments that could be tough to handle, particularly in complicated layouts. In distinction, rem items present a extra constant and predictable method to font scaling, as they’re all the time relative to the basis component’s font measurement.

That is illustrated within the CodePen instance, the place the totally different font scaling behaviors of px, em, and rem items are demonstrated. In conditions the place font scaling is a vital requirement, such because the Airbnb instance talked about, the usage of rem items generally is a extra dependable selection to make sure a constant and maintainable font scaling answer.

Relative items like rem can be utilized wherever a hard and fast unit like px can be utilized. Nonetheless, indiscriminate use of rem items throughout all properties can result in undesirable scaling conduct and elevated complexity.

Within the case of Airbnb, the crew determined to prioritize the usage of rem items particularly for font scaling, fairly than scaling all components proportionally. This focused method supplied the important thing good thing about constant textual content scaling, with out the potential downsides of scaling each side of the format.

The rationale behind this resolution was twofold:

  1. Scaling all the things utilizing rem items would have been just like Browser Zoom and doubtlessly launched unintended format points,
  2. The first focus was on offering a mobile-friendly font scaling answer. By focusing on font sizes with rem items, the crew might be sure that crucial content material — the textual content — scaled appropriately.

Shifting from pixel-based values to rem items as a company-wide change in CSS follow generally is a important problem, particularly when working throughout a number of groups. The effort and time required to coach designers and frontend builders on the brand new method, and to have them convert their current pixel-based values to rem items, generally is a important barrier to adoption. To handle this, the Airbnb crew determined to deal with automating the unit conversion course of as a lot as doable, enabling a extra seamless transition to the brand new rem-based system.

As a substitute of requiring designers to have to think about new items or introduce some conversion for internet solely, we determined to proceed to creator our CSS in px items. This diminished the quantity of coaching required for groups to start out utilizing rem items out the gate.

One space we did deal with with our design groups was beginning to check their designs utilizing font scaling by leveraging the Text Resizer — Accessibility Checker to assist simulate what a design may seem like at 2X the font measurement. This device helped us spot issues earlier into the design course of.

Airbnb is within the technique of transitioning from React-with-Styles to a more moderen method utilizing Linaria. Whereas the adoption of Linaria was progressing shortly, we acknowledged the necessity to help each styling programs for a constant expertise. Managing the conversion throughout these two totally different CSS-in-JS programs posed an extra problem.

Table of Contents

Linaria

By leveraging Linaria’s help for CSS customized properties, the crew was capable of create new typography theme values that mechanically transformed the prevailing pixel-based values to their rem equivalents. This method allowed the crew to introduce the brand new rem-based theme values in a centralized method, making them out there to little one components. This gave the crew the flexibility to override the rem values on a per-page foundation, offering the mandatory flexibility in the course of the transition course of.

import  typography  from './site-theme';

// Loops by the CSS Vars we use for typography and converts them
// from px to rem items.
const theme: css`
$getCssVariables( typography: replacePxWithREMs(typography) )
// Modifications from:
// - body-font-size: 16px;
// To
// - body-font-size: 1rem;
`;
// Use the category title generated from linaria to override the theme
// variables for the youngsters of this element.
const RemThemeLocalProvider: React.FC = ( kids ) =>
const cx = useCx();
return <div className=linariaClassNames.theme)>kids</div>;
;ty

Though this method helped us convert a lot of the font scaling properties, there have been many locations in our code that we used pxbased values outdoors the theme. Linaria’s help for post-CSS plugins made fixing these areas comparatively straightforward. We leveraged postcss-pxtorem to assist goal these values extra simply. We began through the use of an permit listing, in order that we might rigorously apply this alteration to a smaller set of early adopting pages.

It was necessary that we supplied an escape hatch when there was some purpose for front-end engineers needing to make use of px items. Fortunately we had been capable of present this through the use of a distinct casing for the px worth like proven under.

/* `px` is transformed to `rem` */
.convert
font-size: 16px; /* transformed to 1rem */

/* `Px` or `PX` is ignored by `postcss-pxtorem`
however nonetheless accepted by browsers */
.ignore
font-size: 200Px;
font-size: clamp(16Px, 2rem, 32Px);

React with Kinds

quantity of our frontend code nonetheless makes use of react-with-styles, so we needed to discover one other approach to help these circumstances with a simple conversion. By this we created a easy Larger-Order element that made the conversion fairly easy. First we created a wrapper for the withStyles perform like under, and gave the flexibility to keep away from conversion as properly.

export const withRemStyles = (
styleFn?: Nullable<(theme: Theme) => Kinds>,
choices?: WithStylesOptions & disableConvertToRemUnits?: boolean ,
) =>
const disableConvertToRemUnits = getDisableConvertToRemUnits(choices);
// If conversion is disabled, simply return the unique withStyles perform
if (disableConvertToRemUnits)
return _withStyles(styleFn, choices);

// In any other case, wrap the unique fashion perform with a brand new perform
// that converts px to rem
return _withStyles((theme: Theme) =>
if (styleFn)
const kinds = styleFn(theme);
const remStyles = convertToRem(kinds);
return remStyles;

return ;
, choices);
;

Then the convertToRem will look by the keys and values and map a transformed worth for any of the font sizing attributes. This allowed us to automate the conversion course of in a extra easy means.

With these two challenges out of the best way, we are able to begin testing our elements to confirm if there are any main points we would must resolve earlier than rolling out. In our element documentation and tooling, we constructed an inner plugin to permit for simpler testing by setting the font-size on the html component straight to check with font scaling.

Screenshot testing has helped our groups catch visible regressions. Including help to permit for setting further screenshots at totally different root font sizes has helped our product groups overview what the element appears like at totally different font scales. To do that, we permit for including further font sizes to be set when capturing the screenshots so that you don’t should create new element variations only for font scaling.

Supporting font scaling for Cell Safari was harder. Not like different browsers, there may be not a font measurement desire out there in Cell Safari. Nonetheless, they’ve launched help for their very own font: -apple-system-body however there are some necessary concerns.

Since macOS Excessive Sierra (10.13), desktop Safari additionally helps the font desire, however there may be not a simple “font measurement” configuration out there in MacOS. As a result of there might be sudden conduct on desktop Safari, so we used a @helps assertion to forestall this. The code under will solely goal Cell Safari.

// Apple's Dynamic Kind requires this font household for use
// Solely goal iOS/iPadOS
@helps (font: -apple-system-body) and (-webkit-touch-callout: default)
:root
font: -apple-system-body;

One other consideration is that the “100%” default font measurement chosen doesn’t equal the usual font measurement of 16px, however fairly 17px. This can be a very refined distinction, however it’s vital for the design high quality bar we intention to attain at Airbnb. So to resolve this subject, we ended up utilizing an inline head script to normalize the worth, by putting it early into the web page execution we averted seeing a change in font measurement.

(() => 
// do not do something if the browser does not match the helps assertion
if (!CSS.helps('(font: -apple-system-body) and (-webkit-touch-callout: default)')) return;
// Should create a component for the reason that root component kinds will not be but parsed.
const div = doc.createElement('div');
div.setAttribute('fashion', 'font: -apple-system-body');
// Physique just isn't out there but so this must be added to the basis component
documentElement.appendChild(div);
const fashion = getComputedStyle(div);
if (fashion.fontSize === '17px')
documentElement.fashion.setProperty('font-size', '16px');

documentElement.removeChild(div);
)();

Then when the web page hundreds we use a resize observer to detect if the worth adjustments once more to unset or set the font-size property on the html component. This helps us nonetheless help scalable fonts, however not have a big influence on the default font measurement (100%).

Supporting scalable fonts is an funding that ought to make a dramatic distinction for our Hosts and company with low imaginative and prescient and anybody who advantages from bigger font sizes and management over their looking expertise. Beneath are two examples of the house web page exhibiting how the default font measurement (16px) seems to somebody who has blurry imaginative and prescient and what it appears like by doubling the font measurement (32px). The second picture is much extra legible and usable.