Resize text to fit the parent with variable font width axis

Adjust the width of your text to fit its parent container using a variable font width axis

Mandy Michael
Mar 6 · 3 min read

One of the most exciting things for me about variable fonts is that their flexibility opens up an opportunity to create more responsive designs and components.

There are a number of ways you can have text resize to fit its parent container, but it’s been largely limited to adjusting the font size. The problem with this approach is that making the font smaller is not always the best option for our designs.

With variable fonts that contain a width axis, we can adjust the font-stretch property with CSS to condense the font. When we combine this with font-size as well we can create more flexible response text on the web. For our example, we are using Barlow which has a width axis with a range of 300% to 500%.

The Code

You can either check out the Codepen, or you can read on to get a breakdown.

Note: This is an experiment, meaning I have in no way optimised this for performance. If you plan on using this for anything in prod, please make sure you think about the performance impacts.

To accomplish this we need a few things, firstly the width of the parent container and secondly, we will use scrollWidth to measure the width of our text.

const parentContainerWidth = text.parentNode.clientWidth;
const currentTextWidth = text.scrollWidth;

Once we have these we also need to determine what the current font-stretch value is so we can update it as the parent changes. One way to do this is to use getComputedStyle.

const currentFontStretch = parseInt(window.getComputedStyle(text).fontStretch);

Finally, we can use these values to determine the new font-stretch value. Basically what we are doing here is working out a percentage value to assign to our font-stretch property. Math.min and Math.max are really useful in this case because I don't want to extend past the available axis range for the font.

const newValue = Math.min(Math.max(300, (parentContainerWidth / currentTextWidth) * currentFontStretch), 500)

If we break this down, let's say our parent container is 300px wide, our text is 150px wide and out current font-stretch value is at the starting value of 300%. If we divide the parent by the child we’d have a value of 2, which we then multiply by the current font-stretch of 300, giving us a value of 600 e.g. Math.max(300, 600). Because Math.max will return the highest value we’ll take 600, leaving us with Math.min(600, 500) . In this case, we want the minimum value (our maximum font-stretch) so the final value will be 500.

This will ensure that our font-stretch value matches the width of our container, within the constraints of the available values.

Finally, we can use CSS custom properties to update our font-stretch value in our CSS leaving us with the final effect.

text.style.setProperty('--fontStretch', newValue + '%');

Bonus

While I was working on this I wanted a quick way to resize a div for the demo, I procrastinated a lot on it because I thought I’d have to write a bunch of code. Turns out, Chris Coyier had a great CSS only suggestion! resize. This property accepts a number of options and sets whether an element is resizable, and in which directions you can resize it! It only works on elements that don't have an overflow of hidden though. Check it out on MDN. (Or have a play with the bottom right corner on the header box).

You can see the full implementation in the Codepen example.

Have fun and make cool things.

Mandy

Mandy Michael

Written by

Lover of CSS, and Batman. Front End Developer, Writer, Speaker, Development Manager | Founder & Organiser @fendersperth | Organiser @mixinconf

More From Medium

More from Mandy Michael

More from Mandy Michael

Role Models and Mentors

Also tagged Variable Fonts

Also tagged Variable Fonts

Dyslexic-friendly Web typography

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade