Автоматический размер шрифта — js

Как сделать так, чтобы размер шрифта автоматически настраивался, чтобы текст не выходил за пределы?

const h1 = document.getElementsByTagName('h1')[0];
const content = document.getElementById('content');
let size = parseInt(window.getComputedStyle(h1).getPropertyValue('font-size'));
while (checkIfOverflows(h1, content)){
    size--;
    h1.style.fontSize = size + 'px';
}

function checkIfOverflows(element, parent){
    const oldWidth = element.style.width;
    element.style.width = 'fit-content';
    const parentRect = parent.getBoundingClientRect();
    const elementRect = element.getBoundingClientRect();
    const overflows = (parentRect.right - elementRect.right < 0);
    element.style.width = oldWidth;
    console.info(overflows);
    return overflows;
}

У h1 есть стабильный левый край и nowrap, checkIfOverflows работает при однократной проверке, но не в этом цикле, где, если он сначала переполняется, он зацикливается навсегда, что означает, что, скорее всего, это проблема с синхронизацией или какие-то другие странные вещи в этом роде.

Имейте в виду, что пользовательский агент может установить минимальный размер шрифта, ниже которого вы не сможете опуститься. Масштабирование размера шрифта в соответствии с содержимым, как правило, является плохой идеей.

AnrDaemon 02.06.2024 00:17

Отвечает ли stackoverflow.com/questions/21055840/… на ваш вопрос?

rand'Chris 02.06.2024 00:19

Пожалуйста, включите работоспособный фрагмент, показывающий проблему. В частности соответствующий HTML. Вы уверены, что element.style.width установлен?

A Haworth 02.06.2024 06:52
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Похоже, проблема связана с динамической природой DOM и способом обновления свойств CSS. Возможное решение — использовать комбинацию requestAnimationFrame и более надежной проверки на переполнение. Вот как вы можете изменить свой код для достижения этой цели:

  • Используйте requestAnimationFrame, чтобы убедиться, что изменения стиля выполнены правильно. визуализируется перед повторной проверкой на переполнение.
  • Упростите функцию checkIfOverflows.

Вот обновленный код:

javascript

const h1 = document.getElementsByTagName('h1')[0];
const content = document.getElementById('content');
let size = parseInt(window.getComputedStyle(h1).getPropertyValue('font-size'));

// Use a function to resize the text
function adjustFontSize() {
    if (checkIfOverflows(h1, content)) {
        size--;
        h1.style.fontSize = size + 'px';
        // Use requestAnimationFrame to ensure the style changes are rendered before the next check
        requestAnimationFrame(adjustFontSize);
    }
}

function checkIfOverflows(element, parent) {
    const parentRect = parent.getBoundingClientRect();
    const elementRect = element.getBoundingClientRect();
    return elementRect.right > parentRect.right;
}

// Start the adjustment process
adjustFontSize();

Объяснение:

  • requestAnimationFrame: эта функция используется, чтобы убедиться, что регулировка размера шрифта происходит синхронно с перерисовкой браузера цикл. Он планирует запуск функции корректировкиFontSize до следующая перерисовка, гарантируя, что все изменения стиля будут отображены до следующая итерация цикла.

  • checkIfOverflows: эта функция вычисляет ограничивающие прямоугольники. элемента и его родителя, чтобы проверить, превышает ли правый край элемента правый край родительского элемента.

Шаги, обеспечивающие правильную работу кода:

  • Начальный размер шрифта. Убедитесь, что начальный размер шрифта h1 элемент установлен достаточно большим, чтобы он мог переполниться. Таким образом, Функция корректировкиFontSize имеет возможность уменьшить размер шрифта, если необходимый.

  • Свойства CSS: убедитесь, что свойство пробелов элемента h1 имеет значение установите значение nowrap, если вы хотите предотвратить перенос текста.

Вот простой пример CSS, позволяющий убедиться, что h1 не переносится:

CSS

h1 {
    white-space: nowrap;
}

Благодаря этим настройкам размер шрифта должен постепенно уменьшаться, пока не поместится в родительский контейнер без переполнения.

Если вы собираетесь воспользоваться услугами искусственного интеллекта, хорошей идеей будет запустить создаваемый им код, чтобы убедиться, что он отвечает на заданный вопрос. Затем вы можете включить его в качестве работоспособного фрагмента, который усилит ваш ответ.

A Haworth 02.06.2024 00:31
Ответ принят как подходящий

Вы можете создать виртуальную линейку, измеряющую ширину текста, вот так...

function GetTextWidth(Str,Font,Size){

let Ruler=document.createElement('div');

Ruler.style.cssText='visibility:hidden;position:absolute;top:0;left:0;wdth:auto;height:auto;padding:0;margin:0;font:normal 400 '+Size+'px "'+Font+'";';

Ruler.textContent=Str;

document.body.appendChild(Ruler);

let Width=Ruler.offsetWidth;

Ruler.remove();

return Width;

}

Примечание. Если вы собираетесь проводить много измерений, возможно, вам захочется не удалять линейку из документа, поэтому вам придется немного изменить эту функцию.

Кроме того, вероятно, заманчиво использовать display:none и, возможно, изменить некоторые другие свойства CSS линейки, но имейте в виду, что это может сделать ее бесполезной.

то есть: Firefox не считает контейнер существующим, когда display:none, поэтому будьте осторожны с любыми изменениями.

Другие вопросы по теме