2

React/Javascript

I have a div* it contains a paragraph. This is a question box so it can be longer or shorter. I would like to resolve if this paragraph is longer (number of text)then scale down the font size in order to the text fits in div. If the paragraph is shorter scale up the font size.

-font size clamp is not the best way. I tried using the Scaletext, but i could not resolve. (i think it can not be used for my problem)

*the parent div has max width and height and responsive

  • https://stackoverflow.com/questions/16056591/font-scaling-based-on-width-of-container Does this answer your question? – Debashish Aug 24 '22 at 10:29
  • You might adapt this js example: ["Set font-size automatically according to the element height"](https://stackoverflow.com/questions/73064565/set-font-size-automatically-according-to-the-element-height/73071677#73071677) – herrstrietzel Aug 25 '22 at 01:26
  • 1
    Please read [ask], create a [mcve], and show how you used that Scaletext – Roko C. Buljan Aug 28 '22 at 17:00

4 Answers4

1

You could compare the divs boundaries (set by it's css width and height properties) with it's current scrollHeight:

So we're actually setting a fixed height and hide overflows via overflow:hidden.

  • Then we're looping through all question divs
  • check if they have an overflow
  • if so – decrease font-size (within another loop) until scrollHeight <=divHeight

let questions = document.querySelectorAll(".question");
let resize = document.querySelector(".resize");

//initial font size adjustment
fixOverflow();

//resize observer
const resizeObserver = new ResizeObserver(() => {
  resetFontSizes();
  fixOverflow();
});
resizeObserver.observe(resize);

function fixOverflow() {
  questions.forEach(function (question, i) {
    let divHeight = question.getBoundingClientRect().height;
    let scrollHeight = question.scrollHeight;
    let style = window.getComputedStyle(question);
    let fontSize = parseFloat(style.fontSize);
    //shrink font size if text has overflow
    if (scrollHeight > divHeight) {
      for (let i = 0; scrollHeight > divHeight; i++) {
        fontSize--;
        question.style.fontSize = fontSize + "px";
        scrollHeight = question.scrollHeight;
      }
    }
    //optional: increase font size if free space available
    if (scrollHeight < divHeight) {
      for (let i = 0; scrollHeight < divHeight; i++) {
        fontSize++;
        question.style.fontSize = fontSize + "px";
        scrollHeight = question.scrollHeight;
      }
    }
  });
}

//reset previously changed font sizes
function resetFontSizes() {
  let questions = document.querySelectorAll(".question");
  questions.forEach(function (question, i) {
    question.style.removeProperty("font-size");
  });
}
.resize{
  overflow:auto;
  padding:1rem;
  border:1px solid #ccc;
  resize:both;
}

.question p{
  margin-top:0;
}

.question{
  font-size:20px;
  line-height:1.2em;
  max-width:calc(100% - 2rem);
  width:500px;
  height:120px;
  border:1px solid #ccc;
  overflow:hidden;
  padding:1rem;
}
<div class="resize">
  <div class="question">
    <p>One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin. </p>
  </div>
  <div class="question">
    <p>One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin. He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections. The bedding was hardly able to cover it and seemed ready to slide off any moment. His many legs, pitifully thin compared with the size of the rest of him, waved about helplessly as he looked. </p>
  </div>
</div>
<h3 style="text-align:right">Resize parent div</h3>

You will also need either an ResizeObserver() or a simple resize eventListener to update/reset the font-size after resizing the window.

herrstrietzel
  • 11,541
  • 2
  • 12
  • 34
-1

If understand your question correctly you want to adjust the font size based on the screen width.

If that's the case - Have you tried to use the 'resize' javascript event and then scale up the font-size based on the innerWidth of that parent element?

Probably this would do the trick.

Reference to MDN Docs - resize event

e-goat
  • 1
  • 3
  • no i want to adjust font-size based on long of the text. The parent div is fix. (example 200 px X 150 px). The text can be either 10 character or 250 character, but i want text fits in the parent div. So if this text longer -> reduce the font size of the text if the text shoret-> increase the font size. – zoltankerekes Aug 24 '22 at 10:55
  • 1
    He wants to adjust the text regarding the amount of characters, not the parent’s size – Jonatan Kruszewski Aug 28 '22 at 17:01
-1

maybe you can use "vw" - A unit of measure equal to a percentage of the width of the document

div{ font-size: 10vw; white-space: nowrap; }

BlckRbbt
  • 1
  • 3
-1

First of all, it's good to know that there is a font-size CSS property and you could have something like

function setFontSize(element) {
    let map = [
        {start: 0, end: 10, fontSize: "60pt"},
        {start: 10, end: 20, fontSize: "40pt"},
        {start: 20, end: 30, fontSize: "20pt"},
        //...
    ]; //The actual values can be defined by you.

    let length = element.innerText.length;
    element.style.fontSize = map.filter(item => (item.start <= length && item.end > length))[0].fontSize;
}

function resizeAndSet(text) {
    let element = document.getElementById("youritem");
    element.innerText = text;
    setFontSize(element);
}
<div id="youritem"></div>
<input type="button" value="Big" onclick="resizeAndSet('abc')">
<input type="button" value="Average" onclick="resizeAndSet('abc0123456789')">
<input type="button" value="Small" onclick="resizeAndSet('abc01234567890123456789')">

Click through the buttons to see this in action. Alternatively you could use svg with its font-size, for example:

<svg viewBox="0 0 200 30" xmlns="http://www.w3.org/2000/svg">
  <text y="20" font-size="smaller">smaller</text>
  <text x="100" y="20" font-size="2em">2em</text>
</svg>
Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175