Scaling Text

One of the challenges posed in modern web development is dynamic text sizing. Images can be set to “auto” or “100%”, but text doesn’t work that way. It is scaled relative to its base size rather than its container.

When we’re just thinking about sizing responsively we can use the “vw” unit of measure to size text in relation to the viewport when the width gets into the hand-held device realm. That would usually be around 4-5vw. But what happens when we need it to fit into a container other than a viewport?

I’m currently working on a project that has a member points block, where the points are placed in a circle. The points aren’t very valuable. meaning that a user may have thousands. The artist specified a design showing only a 4-digit number where one of the digits was “1”, which is very narrow in a non-monospaced font.

Circle with number in it

artist’s vision

What would happen when the user had 333,333 points? Would the circle become an oval? Not very attractive!

I could have used CSS text ellipsizing to slice it off. That is done like this:

span { width: 100px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

But that would not have produced a meaningful result. Since the artist’s specs also included a diagonal “badge” to incentivize a user with zero points, I was going to have to write JavaScript anyway. I decided to try to find a way to programmatically shrink the text.

I didn’t want to rely on character count with the numbers, because they are not all of the same width in the specified font.* Instead I needed to rely on the length of the HTML element when the number was present in it. In order to do this, I had to trust that the code would work and let the span holding the number to grow as much as it wanted. If I clipped it with “overflow:hidden” it would never show the pressure its contents were exerting.

It turned out to be much easier than I thought. I reasoned that I would have to reduce the font size by a percentage that reflected the relative proportions of the expanded span and the fixed-width holder. For example, if the span holding the number grew to 200px, it would need to be reduced to 54% of its size to fit the 108px container again (108/200=.54). I knew my font size was 40px, and I hoped that multiplying 40 by the reduction percentage would work. Surprisingly, it did! I used 100 instead of 108 to give myself a little margin for error, then I reduced the result again by subtracting 10 from my calculation to provide a little padding. I was really happy with the result!


See the Pen Shrink Text by Connie Finkelman (@pixelslave) on CodePen.21122

*Numbers in Verdana are monospaced, giving you a character count option instead.

Leave a Reply