How can I reduce font size based on length?
Asked Answered
P

3

7

Currently I have some large text on a page, and layout works fine for short text (~12-14 chars in length), but any more than that will overflow or wrap. This is undesirable, so I'd like the size to be reduced to fit the whole text.

I've looked into JS solutions like FitText and BigText, but they depend on a fixed width. Since I'm using Bootstrap, I don't have fixed widths.

Okay: http://tf2reputation.com/profile.php?id=76561197960947673
Not okay: http://tf2reputation.com/profile.php?id=76561198054504781

I'v also considered setting white-space: nowrap or truncating, but I'd prefer to show all the text, but smaller, if possible.

Pulpwood answered 4/6, 2014 at 4:32 Comment(3)
You could possibly use JS to express the font size as a ratio to the screen size, eg. the default font/screen ratio is 1:1, so as one changes so does otherAerobiosis
Have you tried FlowType.js?Aerobiosis
crazier thought: you can write the contents in SVGBooher
B
3

FitText does work with a fluid width.

From the github page :

Make sure your container has a width! display: inline elements don't have a width. Use display: block OR display: inline-block+ a > specified width (i.e. width: 100%).

Bold is mine for emphasis.

Looking on the homepage for FitText also reveals that there are no fixed width units in sight.

I should also mention that there is not a native CSS technique to achieve this. The closest thing would possibly be viewport relative lengths but that doesnt solve your problem.

My additional opinion (danger beware) : In my experience when you are confronted with a problem like this, its because you may be looking at things a little wrong from the design side, And if you require Javascript for your layout to stay intact, I do think that needs to be reconsidered. Nursing a design along is usually better than banging it into place with a crowbar. End Opinion

Bout answered 4/6, 2014 at 5:18 Comment(1)
Yup, I was doing it wrong. That's what I get for coding late at night. But I agree with you, I'd prefer a non-JS solution. Part of the reason for posting this question was to get some fresh eyes.Pulpwood
A
1

You could try an iterative approach using javascript.

Put the contents into a span with white-space: nowrap. If span is the span within, you can do something like this:

var maxWidth = span.parentNode.clientWidth;
var currentFont = parseInt(window.getComputedStyle(span).fontSize); // or max font size
while(span.offsetWidth > maxWidth) {
    currentFont--;
    span.style.fontSize = currentFont + "px";
}

This will continually decrement the font until the span fits within its parent.

If the allocated width changes as you resize the window, you may need to run this on window resize.

Amazon answered 4/6, 2014 at 5:50 Comment(2)
+1. A promising solution, but a little inefficient, and you must apply it on window.onresize.Exhibitive
Indeed, it isn't the most efficient algorithm, but certain optimizations are possible. You could, for instance, take a mid-point approach (instead of simply decrementing), to find the correct size in log(n) iterations. Also, as users resize, you can check the direction they resized to know if you need to decrement or increment (likely, the font will only need to change several sizes at most). If the text is static, you could cache the current width (or sizes already calculated) to save the need for future calculations as you resize. Though, I guess at that point you might as well use a libraryAmazon
S
0

This is my first answer so please go easy on me! I chose an example of a game considering the links in the original post do not work anymore.

        let score = document.getElementById("score");

    score.addEventListener("click", checkNumberLength);

    function checkNumberLength() {
        let currentScore = Number(score.innerText);
        currentScore = currentScore + 1;
        score.innerText = currentScore;
        currentScore >= 100 ? score.style.fontSize = "smaller" : score.style.color = "inital";
    }
<p id="score">98</p>
Stubby answered 16/6, 2024 at 9:0 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.