javascript – Dynamic font size based on the amount of text and block sizes


There is a code:

body {
  font-family: "Aquarelle";
  padding: 1cm;
  margin: 0px;

table {
  border-collapse: collapse;
  border: 1px solid black;
  width: 100%;
  height: 100%;

table td {
  font-size: 70pt;
  padding: 0 7%;
  min-width: 29cm;
  max-width: 21cm;
<body bgcolor="white" lang="RU">
  <div class="Section1">
        <td align="center" valign="middle">Самой красивой, умной, нежной, любимой маме! </td>

It is necessary to make sure that when the number of characters in the text increases, the table does not grow in height ( min-width: 29cm; max-width: 21cm; remains fixed), while the font should decrease. It is necessary that the font size was as large as possible, within the boundaries allocated to it (margins of 7% to the left and right).

Is it real in pure CSS? If not, then the JS option.

Everywhere I find examples where everything is sharpened to fit the screen.


Unfortunately, it is not yet possible to solve your problem using CSS only. But JavaScript comes to the rescue. The function itself is small and straightforward, but the performance still leaves a lot to be desired.

The text is always within the boundaries of the block and is always fully visible. Only the font size changes based on word length and line count.

 /* Функция пересчёта размера шрифта */ function fGummaFontSize() { /* Увеличиваем размер шрифта, до появления прокрутки */ while (this.scrollHeight <= this.clientHeight || this.scrollWidth <= this.clientWidth) { = parseFloat(getComputedStyle(this).fontSize) + 2 + "px"; } /* Уменьшаем размер шрифта, пока прокрутка не исчезнет */ while ( this.scrollHeight > this.clientHeight || this.scrollWidth > this.clientWidth ) { = parseFloat(getComputedStyle(this).fontSize) - 1 + "px"; } } /* Функция обхода всех элементов с нужным классом */ function fGummaResizeAll() { document.querySelectorAll(".gumma").forEach(el =>; } document.querySelectorAll(".gumma").forEach(el => el.addEventListener("input", fGummaFontSize)); window.onload = fGummaResizeAll; // Запуск после загрузки контента window.onresize = fGummaResizeAll; // Запуск при изменении размеров окна и контейнеров
 * { margin: 0; padding: 0; } body { background: url("") 0% 0% no-repeat rgb(255, 255, 255); height: 100vh; display: flex; flex-flow: row nowrap; justify-content: space-around; justify-content: space-evenly; align-items: center; } /* Большая часть свойств критически важна! */ .gumma { font-size: 0px; line-height: 1em; overflow: hidden; overflow-wrap: normal; word-wrap: normal; word-break: normal; line-break: auto; -webkit-hyphens: none; hyphens: none; height: 160px; width: 30%; background: rgba(240, 240, 240); }
 <div class="gumma" contenteditable>Ура!</div> <div class="gumma" contenteditable>Самой красивой, умной, нежной, любимой маме!</div> <div class="gumma" contenteditable>Текст с самымидлиннымисловамибезпробеловипереносов - лучший подарок!</div>

Note: The contenteditable attribute was added for interactivity and clarity only, and is optional. Also, its use, in some cases, breaks the operation of the function (for example, when pasting a block of text from the clipboard, but not character-by-character input). When changing the text through a script, the function works fine.

Scroll to Top