Adjusting the font size based on the text length and the size of the parent div

React/Javascript

I am working on a challenge involving a div element that contains a paragraph. This paragraph may vary in length, so I need to find a way to dynamically adjust the font size based on its length. If the paragraph is longer, I want to scale down the font size to ensure it fits within the div. Conversely, if the paragraph is shorter, I need to scale up the font size.

I have attempted using Scaletext for this purpose, but unfortunately, I was not able to achieve the desired outcome. It seems that Scaletext may not be suitable for solving my specific issue.

The parent div has predefined max width and height, making it responsive to different screen sizes.

Answer №1

To determine if a div has overflow, compare its boundaries (defined by its CSS width and height properties) with its current scrollHeight:

This involves setting a fixed height and hiding overflows using overflow:hidden.

  • We then iterate over all question divs
  • Check if they have an overflow
  • If so – reduce font-size (in another loop) until scrollHeight is less than or equal to 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 overflows
    if (scrollHeight > divHeight) {
      for (let i = 0; scrollHeight > divHeight; i++) {
        fontSize--;
        question.style.fontSize = fontSize + "px";
        scrollHeight = question.scrollHeight;
      }
    }
    //Optional: Increase font size if there is 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>

To update/reset the font-size after resizing the window, you will need either a ResizeObserver() or a simple resize eventListener.

Answer №2

It appears as though you are looking to dynamically adjust the font size depending on the screen width, if I have understood your question correctly.

If this is indeed what you need, perhaps considering utilizing the 'resize' JavaScript event to scale up the font-size based on the innerWidth of the parent element could be a solution worth exploring.

This approach may prove to be effective in achieving your desired outcome.

For more information, please refer to the MDN Docs on the resize event

Answer №3

Consider utilizing the "vw" unit - A measurement equivalent to a percentage of the viewport width

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

Answer №4

It's important to note that the font-size CSS property exists. You can implement it in your code like this:

function adjustFontSize(element) {
    let map = [
        {start: 0, end: 10, fontSize: "60pt"},
        {start: 10, end: 20, fontSize: "40pt"},
        {start: 20, end: 30, fontSize: "20pt"},
        //...
    ]; //You can customize these values.

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

function changeTextAndSize(text) {
    let element = document.getElementById("youritem");
    element.innerText = text;
    adjustFontSize(element);
}
<div id="youritem"></div>
<input type="button" value="Large" onclick="changeTextAndSize('abc')">
<input type="button" value="Medium" onclick="changeTextAndSize('abc0123456789')">
<input type="button" value="Small" onclick="changeTextAndSize('abc01234567890123456789')">

Try clicking the buttons to see the font size adjustment in action. Another option is using SVG and its font-size attribute, 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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Can two Angular element components be utilized simultaneously on a single page in Angular 6?

Currently, I'm attempting to host independent Angular elements that can be seamlessly integrated into a non-Angular webpage. Everything works perfectly fine when there's only one element on the page, but as soon as I try to load two or more, I en ...

Ways to incorporate external JavaScript files into a React component

I have been attempting to incorporate external javascript files into my react component. When I included them in a basic html file using script tags, everything worked smoothly. However, I am unsure of how to achieve this within a react component. < ...

Removing the transparent section of an image: A step-by-step guide

I am struggling to figure out how to remove the background boxes in this image that I want to add to my website. click here for image Although it appears transparent, there are still gray and white boxes visible in the background. How can I get rid of th ...

Automatically load file and play audio when the page is loaded

I have created code that allows me to input an mp3 file, output the audio, and display a visual representation of the music. Currently, loading the file is done manually through an input type="file". Now, I want to change it so that the music automaticall ...

Troubleshooting: Unusual Page Loaded on Webpack Dev Server

While working with web pack, I encountered an issue when trying to run the npm run build:dev script. Instead of seeing the actual website, I was presented with a strange page displaying my workspace folders: https://i.sstatic.net/mBNKg.png In case it&apos ...

Is it possible to invoke an AngularJs service by clicking a button?

Recently, I've been working on some AngularJS code involving a service and controller. angular.module('myModule', []).service("AttendanceService", function ($http) { this.getdata = function () { return $http({ ...

Route is searching for static files in the incorrect directory

There seems to be a specific route, /admins/:id, that is looking for static files in /public/admins/ instead of /public/. This issue is causing 404 errors and preventing the js and css files from loading on this page. All other routes are correctly fetchin ...

Using Laravel Mix to implement a Datatable

I've encountered a problem and despite searching for a solution, I haven't been able to figure it out yet. I'm hoping someone can assist me in solving this issue. Below is the code I've been working with. Thank you in advance: webpack. ...

Express-minify is having trouble loading the CSS file. If we remove a portion of the file, it should be able

After implementing the express-minify middleware, I encountered an issue with loading the attached CSS file. Even after validating the CSS using an online service, no errors were detected. I attempted to debug by gradually removing elements, and the prob ...

appearing like a straightforward process of creating strings in JavaScript

Originally, I thought this task would be easy, but it ended up taking me the entire morning! var insert = '<div class="main_content_half_panel_circle" id="circle_' + c + '"></div><script type="text/javascript">$("#circle_& ...

Unique solution: "Using CSS to ensure the overflow document always scrolls to the bottom

Is there a way in CSS to make a div with overflow: scroll always automatically scroll to the bottom along the Y-axis, regardless of its content? For example, like a chat thread that consistently displays the latest message at the bottom. I've encount ...

Tips for retaining a number even when the page is refreshed

Is there a way to keep the number increasing even after refreshing the webpage? Currently, the number resets every time the page is refreshed. Any suggestions on how to fix this? Here is the number <form method="POST"> &l ...

What could be causing errors with my addrole command in discord.jsV12?

After updating to discord.jsv13, my addrole command is no longer working properly. I keep getting errors like role.id is not a function or role.id is not defined, even though I can't seem to find any errors in my code. I have experience with JavaScrip ...

What is the best way to implement CSS rules for a hidden submenu?

Can anyone help me figure out how to apply CSS rules for a hidden submenu? I've attempted to use some JavaScript, but it's not working as expected. Below is a sample of the code I'm working with. The idea is that when you click on the anchor ...

Linking a Checkbox to a Field's Value in AngularJS

I need assistance with checking/unchecking the checkbox depending on the value of the field services.Register.IsTest. If services.Register.IsTest=True, then the checkbox should be checked. Otherwise, it should remain unchecked. Here is the checkbox code: ...

Is it possible to export all types/interfaces from .d.ts files within multiple folders using index.ts in a React TypeScript project?

In my current React project, I am managing multiple configuration folders: -config -api/ |index.ts |types.d.ts -routes/ |index.ts |types.d.ts ... For example, in the api/index.ts file, I can import necessary types using import {SomeTyp ...

What is the best way to achieve a column layout using Bootstrap?

I'm having difficulty adjusting the column width in Bootstrap columns to my specific needs. Check out this link for more information: : https://i.sstatic.net/Tvdef.png What I'm trying to achieve is to keep the label column width fixed while all ...

Having difficulties adjusting the margin for a JSX element directly within the code

I'm struggling with giving a margin style inline to a JSX element. Here's the code snippet that I'm having trouble with: <Nunito20 style={{color: frenchGray, margin: 20 0 3 0;}}>Full Name</Nunito20> Unfortunately, this is throw ...

Looking to run JavaScript code during an Ajax request?

Chrome and Firefox are working fine with the following code, but I'm facing an issue with Safari. Main.php has: <script> function show<?php echo $s; ?>(str) { if (str.length == 0) { document.getElementById("textOrder").innerHTML = " ...

Using javascript to generate fresh dictionaries

Struggling to translate a C# "function" into JavaScript - any advice or tips? Here is the C# snippet: var parameters = new Dictionary<string,string> { { "link", "http://mysite.com" }, { "name", "This is an test" } }; I believe I need to ut ...