Siyah
Siyah

Reputation: 2897

Resizing a font with pure JavaScript based on string length

I know this question is asked multiple times, yet mine is different. I noticed that with the pure JavaScript solution, there is a need to resize the screen, while mine has absolutely nothing to do with resizing a screen.

What I have is a container div with some text in it. All texts have a certain font-size, but I want to change the font-size whenever the text gets a certain length.

I have seen this solution on SO: Resize font depending on string length

Yet, this absolutely looks horrible in pure JavaScript and it's a post of three years ago. There surely must be a better (shorter, better) solution for this. I have read about the CSS solutions, but as I said: I am not using a certain viewport and I don't want to. I just want to change the font-size when it's too long.

I have made a JSFiddle to illustrate the problem:

https://jsfiddle.net/tpx71aqL/

<div class="test">
Blablabla
</div>

<div class="test">
Blablabla12124e121211asdasasas
</div>

PS: I can't use jQuery and don't want to use ellipsis.

Upvotes: 1

Views: 3613

Answers (3)

Vassilis
Vassilis

Reputation: 2841

I needed something similar and I ended up doing something like this:

var elem = document.getElementById("test");
elem.style.fontSize = 30 - elem.innerHTML.length / 6 + 'px';

The idea is to set the max size and reduce it based on the length of the string.

Not fancy or sophisticated but worked for me.

Upvotes: 0

kontur
kontur

Reputation: 5219

This fiddle shows what I suggested in my comment. You extract the current width of the text wrapper and reduce font size until you have a wrapper the same size or slightly smaller than the parent.

var fit = document.getElementById("fit"),
    wrap = document.getElementById("wrap"),
    step = 0.5,
    currentSize;

while (fit.offsetWidth < wrap.offsetWidth) {
    currentSize = parseFloat(window.getComputedStyle(wrap, null).getPropertyValue('font-size'));
    wrap.style.fontSize = (currentSize - step) + "px";
}

Note the getComputedStyle to really get the calculated size.

You could improve this by making the reduction step smarter, instead of just going down a step again and again; for example calculate how far a 1px reduction approximated the wrapper width to the parent width and adjust step size accordingly.

Also this does assume that the text indeed needs scaling down, no scaling up - the same idea applies.

Upvotes: 3

Matthew Brent
Matthew Brent

Reputation: 1376

An idea for this solution is actually really simple. Check out my codepen here.

Using a simple while loop which checks clientWidth against scrollWidth which you can learn more about here, we use the javascript .style.fontSize = "smaller" which decreases the font size by 1 unit. This works well when we don't know what unit is assigned in the CSS. You can read more about it here.

Hope this helps.

document.onreadystatechange = () => {
  if (document.readyState === 'complete') {
    var container = document.getElementById("test");
    while (container.scrollWidth > container.clientWidth) {
      container.style.fontSize = "smaller";
    }
  }
};
.test {
  width: 200px;
  border: 1px solid black;
  font-size: 16px;
}
<div class="test">
Blablabla
</div>

<div class="test" id="test">
Blablabla12124e121211asdasasas
</div>

Upvotes: 3

Related Questions