Масштабирование шрифта по ширине контейнера

мне трудно получить мою голову вокруг масштабирования шрифта.

и этот сайт с кузовом font-size на 100%. 100% того, что хотя? Это, кажется, вычисляется в 16px.

у меня создалось впечатление, что 100% каким-то образом будет ссылаться на размер окна браузера, но, по-видимому, не потому, что это всегда 16px, независимо от того, изменяется ли окно до мобильной ширины или полноэкранного рабочего стола.

как я могу сделать текст на моем сайте масштабируется по отношению к его контейнеру? Я пробовал использовать em но это тоже не масштабируется.

мое рассуждение заключается в том, что такие вещи, как мое меню, становятся хлюпающими при изменении размера, поэтому мне нужно уменьшить px font-size of .menuItem среди других элементов по отношению к ширине контейнера. (Например, в меню на большом рабочем столе 22px работает отлично. Переместитесь вниз к ширине планшета, и 16px более подходит.)

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

30 ответов


EDIT: если контейнер не является телом CSS трюки охватывает все ваши варианты здесь:https://css-tricks.com/fitting-text-to-a-container/

если контейнер-это тело, то, что вы ищете Viewport-процент длины:

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

значения:

  • vw (% от ширины области просмотра)
  • vh (% от высоты области просмотра)
  • vi (1% от размера окна просмотра в направлении встроенной оси корневого элемента)
  • vb (1% от размера вьюпорта в направлении оси блока корневого элемента)
  • vmin (меньше vw или vh)
  • vmax (больше или vw или vh)

1 v * равно 1% от исходного содержащего блока.

использование выглядит так:

p {
    font-size: 4vw;
}

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

эти значения размера подразделение, как px или em, поэтому их можно использовать для определения размера других элементов, таких как ширина, поле или обивка.

поддержка браузера довольно хороша, но вам, вероятно, понадобится запасной вариант, такой как:

p {
    font-size: 16px; 
    font-size: 4vw;
}

проверьте статистику поддержки:http://caniuse.com/#feat=viewport-units.

кроме того, проверьте CSS-трюки для более широкого взгляда: http://css-tricks.com/viewport-sized-typography/

вот хорошая статья о настройке минимальных / максимальных размеров и осуществлении немного большего контроля над размерами:http://madebymike.com.au/writing/precise-control-responsive-typography/

и вот статья о настройке вашего размера с помощью calc (), чтобы текст заполнял окно просмотра:http://codepen.io/CrocoDillon/pen/fBJxu

кроме того, пожалуйста, просмотрите это статья, которая использует метод, названный "расплавленный ведущий", чтобы отрегулировать высоту линии. https://css-tricks.com/molten-leading-css/


но что, если контейнер не просмотра (тела)?

этот вопрос задан в комментарии Алексом под принятым ответом.

этот факт не означает vw нельзя использовать в некоторой степени для размера этого контейнера. Теперь, чтобы увидеть какие-либо изменения, нужно предположить, что контейнер каким-то образом является гибким по размеру. Будь то через прямой процент width или через 100% минус маржа. Точка становится "спорной", если контейнер всегда установите, скажем,200px широкий, тогда просто установить font-size это работает для этой ширины.

Пример 1

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

div {
    width: 50%;
    border: 1px solid black;
    margin: 20px;
    font-size: 16px;
    /* 100 = viewport width, as 1vw = 1/100th of that
       So if the container is 50% of viewport (as here)
       then factor that into how you want it to size.
       Let's say you like 5vw if it were the whole width,
       then for this container, size it at 2.5vw (5 * .5 [i.e. 50%])
    */
    font-size: 2.5vw; 
}

полагая здесь div является ребенком body, это 50% этой 100% ширины, что размер окна в данном случае. В принципе, вы хотите установить vw это будет выглядеть хорошо для вас. Как вы можете видеть в моем комментарии в приведенном выше css, вы можете "думать" через это математически относительно полного размера окна просмотра, но вы не нужно для этого. Текст будет "сгибаться" с контейнером, потому что контейнер сгибается с изменением размера окна просмотра. UPDATE:вот пример двух контейнеров разного размера.

Пример 2

вы можете помочь обеспечить размер окна просмотра, заставив расчет на основе этого. рассмотрим такой пример:

html {width: 100%;} /* force html to be viewport width */
body {width: 150%; } /* overflow the body */

div {
    width: 50%;
    border: 1px solid black;
    margin: 20px;
    font-size: 16px;
    /* 100 = viewport width, as 1vw = 1/100th of that
       Here, the body is 150% of viewport, but the container is 50% 
       of viewport, so both parents factor  into how you want it to size.
       Let's say you like 5vw if it were the whole width,
       then for this container, size it at 3.75vw 
       (5 * 1.5 [i.e. 150%]) * .5 [i.e. 50%]
    */
    font-size: 3.75vw; 
}

размер все еще основан на видовом экране, но по существу настроен на основе сам размер контейнера.

следует динамически изменять размер контейнера...

если размер элемента контейнера в конечном итоге динамически изменяет его процентное отношение либо через @media точки останова или через javascript, тогда независимо от базовой " цели "потребуется пересчет для поддержания той же" связи " для размера текста.

возьмите пример #1 выше. Если div был переведен в 25% ширина либо @media или javascript, затем в то же время font-size необходимо будет настроить либо в медиа-запросе, либо на javascript для нового вычисления 5vw * .25 = 1.25. Это поставило бы размер текста на тот же размер, что и у" ширины " оригинала 50% контейнер был уменьшен наполовину от размера окна просмотра, но теперь был уменьшен из-за изменения в его собственном расчете процента.

Вызов

С технология CSS3 calc() функции in используйте, стало бы трудно настроить динамически, так как эта функция не работает для font-size цели в это время. Таким образом, вы не можете выполнить чистую настройку CSS3, если ваша ширина меняется на calc(). Конечно, незначительной регулировки ширины полей может быть недостаточно, чтобы гарантировать любое изменение font-size, так что это может не иметь значения.


то, что я делаю в одном из моих проектов, - это "смесь" между vw и vh, чтобы настроить размер шрифта для моих нужд, например.:

font-size: calc(3vw + 3vh);

Я знаю, что это не отвечает на вопрос op, но, возможно, это может быть решением для кого-то еще.


решение с SVG:

<div style="width: 60px;">  
  <svg width="100%" height="100%" viewBox="0 -200 1000 300"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <text font-size="300" fill="black">Text</text>
  </svg>
</div>

https://jsfiddle.net/qc8ht5eb/


существует большая философия для этого вопроса. Проще всего было бы дать определенный размер шрифта телу (я рекомендую 10), а затем все остальные элементы будут иметь свой шрифт в em или rem. Я приведу вам и пример, чтобы понять эти единицы. ЭМ всегда относительно своего родителя

body{font-size:10px;}
.menu{font-size:2em;} /* that means 2*10px = 20px */
.menu li{font-size:1.5em;} /* that means 1.5*20px = 30px */

Rem всегда относительно тела

body{font-size:10px;}
.menu{font-size:2rem;} /* that means 2*10px = 20px */
.menu li{font-size:1.5rem;} /* that means 1.5*10px = 15px */

и чем вы можете создать скрипт, который будет изменять размер шрифта относительно ширины контейнера. Но дело не в этом. Я бы рекомендовал. Потому что в контейнере ширины 900px, например, у вас будет p элемент с размером шрифта 12px, скажем. И на вашей ideea, которая станет контейнером ширины 300px при размере шрифта 4px. Должен быть нижний предел. Другие решения будут с медиа-запросами, чтобы вы могли установить шрифт для разных Ширин.

но решения, которые я бы рекомендовал, - это использовать библиотеку javascript, которая поможет вам в этом. И fittext.js что я нашел пока что.


Обновлено, потому что я получил голос вниз.

вот функция:

document.body.setScaledFont = function(f) {
  var s = this.offsetWidth, fs = s * f;
  this.style.fontSize = fs + '%';
  return this
};

затем преобразуйте все размеры шрифта дочерних элементов документов в em или %.

затем добавьте что-то вроде этого в свой код, чтобы установить базовый размер шрифта.

document.body.setScaledFont(0.35);
window.onresize = function() {
    document.body.setScaledFont(0.35);
}

http://jsfiddle.net/0tpvccjt/


Pure-CSS решение с calc(), CSS единиц и математика

это точно не то, что ОП просит, но может сделать чей-то день. Этот ответ не ложка-feedingly легкая и требует некоторого исследования в разработчика конца.

я пришел, наконец, чтобы получить решение pure-CSS для этого с помощью calc() С разных подразделений. Вам понадобится некоторое базовое математическое понимание формул, чтобы разработать свое выражение для calc().

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

математика

вам понадобится:

  • красиво отрегулированный коэффициент в некотором видовом окне, я использовал 320px, таким образом, я получил 24px высокий и 224px широкий, поэтому коэффициент 9.333... или 28 / 3
  • ширина контейнера, у меня padding: 3em и полная ширина, так что это дошло до 100wv - 2 * 3em

X-Ширина контейнер поэтому замените его своим собственным выражением или настройте значение, чтобы получить полностраничный текст. R-это соотношение, которое у вас будет. Вы можете получить его, регулируя значения в некотором окне просмотра, проверяя ширину и высоту элемента и заменяя их своими собственными значениями. Кроме того, это width / heigth ;)

x = 100vw - 2 * 3em = 100vw - 6em
r = 224px/24px = 9.333... = 28 / 3

y = x / r
  = (100vw - 6em) / (28 / 3)
  = (100vw - 6em) * 3 / 28
  = (300vw - 18em) / 28
  = (75vw - 4.5rem) / 7

и бац! Он работал! Я написал

font-size: calc((75vw - 4.5rem) / 7)

к моему заголовку, и он хорошо отрегулирован в каждом окне просмотра.

но как это работает?

нам нужна константы здесь. 100vw означает полную ширину окна просмотра, и моей целью было установить заголовок полной ширины с некоторым заполнением.

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

вывод

интересно, почему никто не понял это, и некоторые люди даже говорят, что это было бы невозможно возиться с CSS. Мне не нравится использовать Javascript для настройки элементов, поэтому я не принимаю ответы JS или даже jQuery, не копая больше. В целом, это хорошо, что это было выяснено, и это один шаг к реализации pure-CSS в дизайне веб-сайта.

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

редактировать: следует также отметить, что в некоторых браузерах есть злые полосы прокрутки. Например, при использовании Firefox я заметил, что 100vw означает полную ширину окна просмотра, простирающуюся под полосой прокрутки (где содержимое не может расширяться!), поэтому текст fullwidth должен быть тщательно обработан и желательно протестирован со многими браузерами и устройствами.


Это может быть не очень практично, но если вы хотите, чтобы шрифт был прямой функцией родителя, без наличия JS, который слушает/циклы(интервал), чтобы прочитать размер div/page, есть способ сделать это. Фреймы. Все, что находится в iframe, будет рассматривать размер iframe как размер окна просмотра. Таким образом, трюк состоит в том, чтобы просто сделать iframe, ширина которого является максимальной шириной, которую вы хотите, чтобы ваш текст был, и высота которого равна максимальной высоте * соотношение сторон конкретного текста.

отставив в сторону ограничение, что единицы видового экрана не могут также иметь боковые родительские единицы для текста (как в случае с размером%, как и все остальные), единицы видового экрана предоставляют очень мощный инструмент:возможность получить измерение min/max. Вы не можете сделать это где - то еще-вы не можете сказать..сделайте высоту этого div шириной родительского * что-то.

при этом трюк состоит в том, чтобы использовать vmin и установить размер iframe так, чтобы [доля] * общая высота хороший размер шрифта, когда высота является предельным размером, и [доля] * общая ширина, когда ширина является предельным размером. Вот почему высота должна быть произведением ширины и соотношения сторон.

для моего конкретного примера у вас есть

.main iframe{
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: calc(3.5 * 100%);
  background: rgba(0,0,0,0);
  border-style: none;
  transform: translate3d(-50%,-50%,0);
}

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

var rule = document.styleSheets[1].rules[4];
var iDoc = document.querySelector('iframe').contentDocument;
iDoc.styleSheets[0].insertRule(rule.cssText); 

вы можете написать небольшую функцию, которая получает правило CSS / все правила CSS, которые повлияют на текстовую область.

Я не могу придумать другой способ сделать это, не имея некоторых велосипедных / прослушивания JS. Реальным решением было бы для браузеров предоставить способ масштабирования текста как функции родительского контейнера, а также предоставить ту же функциональность типа vmin/vmax.

JS играть на скрипке: https://jsfiddle.net/0jr7rrgm/3/ (нажмите один раз, чтобы заблокировать Красный квадрат мыши, нажмите еще раз, чтобы освободить)

большинство JS в скрипке-это просто моя пользовательская функция перетаскивания


есть способ сделать это без javascript!

Вы можете использовать встроенный SVG. Вы можете использовать css на svg, если он встроен. Вы должны помнить, что использование этого метода означает, что ваш svg будет реагировать на его размер контейнера.

попробуйте использовать следующее решение...

HTML-код

<div>
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360.96 358.98" >
      <text>SAVE 0</text>

  </svg>

</div>

в CSS

div {
  width: 50%; /* set your container width */
  height: 50%; /* Set your container height */

}

svg {
  width: 100%;
  height: auto;

}

text {
  transform: translate(40px, 202px);
  font-size: 62px;
  fill: #000;

}

пример: https://jsfiddle.net/k8L4xLLa/32/

хочется чего-то большего кричащий?

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

https://jsfiddle.net/k8L4xLLa/14/


используя vw, em & co. работает наверняка, но ИМО всегда нужно прикосновение человека для тонкой настройки.

вот сценарий, который я только что написал на основе @tnt-rox'ответ который пытается автоматизировать прикосновение этого человека:

$('#controller').click(function(){
	$('h2').each(function(){
    var
      $el = $(this),
      max = $el.get(0),
      el = null
    ;
    max =
      max
    ? max.offsetWidth
    : 320
    ;
    $el.css({
      'font-size': '1em',
      'display': 'inline',
    });
    el = $el.get(0);

    el.get_float = function(){
      var
        fs = 0
      ;
      if (this.style && this.style.fontSize) {
        fs = parseFloat(this.style.fontSize.replace( /([\d\.]+)em/g, '' ));
      }
      return fs;
    };

    el.bigger = function(){
      this.style.fontSize = (this.get_float() +0.1) +'em';
    };


    while ( el.offsetWidth < max ) {
      el.bigger();
    }
    // finishing touch.
    $el.css({
      'font-size': ((el.get_float() -0.1) +'em'),
      'line-height': 'normal',
      'display': '',
    });
	});  // end of ( each )
});	// end of ( font scaling test )
div {
  width: 50%;
  background-color: tomato;
  font-family: 'Arial';
}

h2 {
  white-space: nowrap;
}

h2:nth-child(2) {
  font-style: italic;  
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="button" id="controller" value="Apply" />
<div>
  <h2>Lorem ipsum dolor</h2>
  <h2>Test String</h2>
  <h2>Sweet Concatenation</h2>
  <h2>Font Scaling</h2>
</div>

это в основном уменьшает размер шрифта на 1em, а затем начинает увеличиваться на 0.1, пока не достигнет максимальной ширины.

jsFiddle


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

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


внутри вашего CSS попробуйте добавить это внизу, изменив ширину 320px для того, где ваш дизайн начинает ломаться:

    @media only screen and (max-width: 320px) {

       body { font-size: 1em; }

    }

затем дайте размер шрифта в "px" или "em", как вы хотите.


вы пробовали http://simplefocus.com/flowtype/ ?

Это то, что я использую для своих сайтов и отлично работает. Надеюсь, это поможет.


вы ищете что-то вроде этого? =>
http://jsfiddle.net/sijav/dGsC9/4/
http://fiddle.jshell.net/sijav/dGsC9/4/show/
Я использовал flowtype и он отлично работает (однако это js, а не чистое решение css)

$('body').flowtype({
 minFont : 10,
 maxFont : 40,
 minimum : 500,
 maximum : 1200,
 fontRatio : 70
});

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

вы можете играть с ним на http://jsfiddle.net/tubededentifrice/u5y15d0L/2/

волшебство происходит здесь:

var setMaxTextSize=function(jElement) {
    //Get and set the font size into data for reuse upon resize
    var fontSize=parseInt(jElement.data(quickFitFontSizeData)) || parseInt(jElement.css("font-size"));
    jElement.data(quickFitFontSizeData,fontSize);

    //Gradually increase font size until the element gets a big increase in height (ie line break)
    var i=0;
    var previousHeight;
    do
    {
        previousHeight=jElement.height();
        jElement.css("font-size",""+(++fontSize)+"px");
    }
    while(i++<300 && jElement.height()-previousHeight<fontSize/2)

    //Finally, go back before the increase in height and set the element as resized by adding quickFitSetClass
    fontSize-=1;
    jElement.addClass(quickFitSetClass).css("font-size",""+fontSize+"px");

    return fontSize;
};

этот веб-компонент изменяет размер шрифта, чтобы внутренняя ширина текста соответствовала ширине контейнера. Проверьте демо.

вы можете использовать его как это:

<full-width-text>Lorem Ipsum</full-width-text>

моя проблема была похожа, но связана с масштабированием текста в заголовке. Я попробовал Fit Font, но мне нужно было переключить компрессор, чтобы получить какие-либо результаты, так как он решал немного другую проблему, как и поток текста. Поэтому я написал свой собственный маленький плагин, который уменьшает размер шрифта, чтобы соответствовать контейнер, если у вас есть overflow: hidden и white-space: nowrap Так что даже если уменьшение шрифта до минимума не позволяет показать полный заголовок, он просто отрезает то, что он может показать.

(function($) {

  // Reduces the size of text in the element to fit the parent.
  $.fn.reduceTextSize = function(options) {
    options = $.extend({
      minFontSize: 10
    }, options);

    function checkWidth(em) {
      var $em = $(em);
      var oldPosition = $em.css('position');
      $em.css('position', 'absolute');
      var width = $em.width();
      $em.css('position', oldPosition);
      return width;
    }

    return this.each(function(){
      var $this = $(this);
      var $parent = $this.parent();
      var prevFontSize;
      while (checkWidth($this) > $parent.width()) {
        var currentFontSize = parseInt($this.css('font-size').replace('px', ''));
        // Stop looping if min font size reached, or font size did not change last iteration.
        if (isNaN(currentFontSize) || currentFontSize <= options.minFontSize ||
            prevFontSize && prevFontSize == currentFontSize) {
          break;
        }
        prevFontSize = currentFontSize;
        $this.css('font-size', (currentFontSize - 1) + 'px');
      }
    });

  };

})(jQuery);

Я подготовил простую функцию масштабирования, используя преобразование css вместо размера шрифта. Вы можете использовать его внутри любого контейнера, вам не нужно устанавливать медиа-запросы и т. д.:)

запись в блоге: https://blog.polarbits.co/2017/03/07/full-width-css-js-scalable-header/

код:

function scaleHeader() {
  var scalable = document.querySelectorAll('.scale--js');
  var margin = 10;
  for (var i = 0; i < scalable.length; i++) {
    var scalableContainer = scalable[i].parentNode;
    scalable[i].style.transform = 'scale(1)';
    var scalableContainerWidth = scalableContainer.offsetWidth - margin;
    var scalableWidth = scalable[i].offsetWidth;
    scalable[i].style.transform = 'scale(' + scalableContainerWidth / scalableWidth + ')';
    scalableContainer.style.height = scalable[i].getBoundingClientRect().height + 'px';
  }
}

рабочую демку: https://codepen.io/maciejkorsan/pen/BWLryj


посмотрите на мой код, он делает font size smaller to fit что есть

но я думаю, что это не привело к положительному опыту пользователей

var containerWidth = $("#ui-id-2").width();
var items = $(".quickSearchAutocomplete .ui-menu-item");
var fontSize = 16;

items.each(function(){
    //display value depend sometimes on your case you may make it block or inline-table instead of inline-block or whatever value that make the div take overflow width
    $(this).css({"whiteSpace":"nowrap","display":"inline-block"});
    while ($(this).width() > containerWidth){
         console.log("$(this).width()"+ $(this).width() + "containerWidth" + containerWidth)
         $(this).css("font-size", fontSize -= 0.5);
    }
});

result

надеюсь, что это поможет вам


всегда ваш элемент С этим атрибутом:

Javascript:element.style.fontSize = "100%";

или

CSS:style = "font-size: 100%;"

когда вы идете в полноэкранном режиме, у вас уже должен быть масштаб вычисленная переменная (масштаб > 1 или масштаб = 1). Затем в полноэкранном режиме:

document.body.style.fontSize = (scale * 100) + "%";

он отлично работает с небольшим кодом.


в качестве резервного JavaScript (или вашего единственного решения) вы можете использовать my плагин jQuery Scalem, который позволяет масштабировать относительно родительского элемента (контейнера), передав .


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

но потом я нашел это, и это сработало:

https://github.com/chunksnbits/jquery-quickfit

пример использования:

$('.someText').quickfit({max:50,tolerance:.4})


попробуйте использовать fitText плагин, размер окна просмотра причины не является решением этой проблемы. Просто добавьте библиотеку

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <script src="jquery.fittext.js"></script>

и изменить размер шрифта для правильной настройки коэффициента текста:

$("#text_div").fitText(0.8);

вы можете установить максимальные и минимальные значения текста:

$("#text_div").fitText(0.8, { minFontSize: '12px', maxFontSize: '36px' });

для динамического текста этот плагин весьма полезен http://freqdec.github.io/slabText/. Просто добавьте css

.slabtexted .slabtext
    {
    display: -moz-inline-box;
    display: inline-block;
    white-space: nowrap;
    }
.slabtextinactive .slabtext
    {
    display: inline;
    white-space: normal;
    font-size: 1em !important;
    letter-spacing: inherit !important;
    word-spacing: inherit !important;
    *letter-spacing: normal !important;
    *word-spacing: normal !important;
    }
.slabtextdone .slabtext
    {
    display: block;
    }

и скрипт

$('#mydiv').slabText();

чтобы размер шрифта соответствовал его контейнеру, а не окну, см. resizeFont() функция, которую я разделил в этом вопросе (комбинация других ответов, большинство из которых уже связаны здесь). Он запускается с помощью window.addEventListener('resize', resizeFont);.

Vanilla JS: изменить размер шрифта-удивительный, чтобы соответствовать контейнеру

JS:

function resizeFont() {
  var elements  = document.getElementsByClassName('resize');
  console.log(elements);
  if (elements.length < 0) {
    return;
  }
  _len = elements.length;
  for (_i = 0; _i < _len; _i++) {
    var el = elements[_i];
    el.style.fontSize = "100%";
    for (var size = 100; el.scrollHeight > el.clientHeight; size -= 10) {
      el.style.fontSize = size + '%';
    }
  }
}

вы могли бы использовать vw / vh в качестве запасного варианта, поэтому вы динамически назначаете em или rem единицы измерения с помощью javascript, убедитесь, что шрифты масштабируются до окна, если javascript отключен.

применить .resize класс для всех элементов, содержащих текст, который вы хотите масштабировать.

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

примечание: по умолчанию font-size должно быть установлено значение либо em,rem или % для достижения правильной результаты... и если стиль ваших элементов слишком сложен, браузер может произойти сбой, если вы начнете лихорадочно изменять размер окна.


это сработало для меня:

Я пытаюсь приблизить размер шрифта на основе ширины / высоты, полученной от установки размера шрифта: 10px. В основном идея заключается в том, " если у меня есть ширина 20px и высота 11px с размером шрифта:10px, так что это будет максимальный размер шрифта для математики контейнера шириной 50px и высотой 30px?"

ответ представляет собой систему двойной пропорции:

{ 20:10=50:X, 11: 10=30: Y } = { X= (10 * 50) / 20, Y= (10*30)/11 }

теперь X-это размер шрифта, который будет соответствовать width, Y-размер шрифта, который будет соответствовать высоте; возьмите наименьшее значение

function getMaxFontSizeApprox(el){
    var fontSize = 10;
    var p = el.parentNode;

    var parent_h = p.offsetHeight ? p.offsetHeight : p.style.pixelHeight;
    if(!parent_h)parent_h = 0;

    var parent_w = p.offsetHeight ? p.offsetWidth : p.style.pixelWidth;
    if(!parent_w)parent_w = 0;

    el.style.fontSize = fontSize + "px";

    var el_h = el.offsetHeight ? el.offsetHeight : el.style.pixelHeight;
    if(!el_h)el_h = 0;

    var el_w = el.offsetHeight ? el.offsetWidth : el.style.pixelWidth;
    if(!el_w)el_w = 0;

    //0.5 is the error on the measure that js does
    //if real measure had been 12.49 px => js would have said 12px
    //so we think about the worst case when could have, we add 0.5 to 
    //compensate the round error
    var fs1 = (fontSize*(parent_w + 0.5))/(el_w + 0.5);
    var fs2 = (fontSize*(parent_h) + 0.5)/(el_h + 0.5);

    fontSize = Math.floor(Math.min(fs1,fs2));
    el.style.fontSize = fontSize + "px";
    return fontSize;
}

NB: аргумент функции должен быть элементом span или элементом, который меньше, чем его родитель, иначе, если дети и родитель имеют одинаковую функцию width/height, произойдет сбой


Я не вижу ответа со ссылкой на свойство CSS flex, но это тоже может быть очень полезно.


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

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

.container {
    width: 100%;
    max-width: 600px;
}
.headline {
    font-size: 20vw;
}
.subhead {
    font-size: 5vw;
}
@media (min-width:600px) {
    .headline {
        font-size: 120px;
    }
    .subhead {
        font-size: 32px;
    }
}

использовать переменные CSS

никто еще не упоминал переменные CSS, и этот подход работал лучше всего для меня, поэтому:

предположим, у вас есть столбец на Вашей странице, который составляет 100% ширины экрана мобильного пользователя, но имеет max-width 800px, поэтому на рабочем столе есть некоторое пространство по обе стороны столбца. Поместите это в верхней части страницы:

<script> document.documentElement.style.setProperty('--column-width', Math.min(window.innerWidth, 800)+'px'); </script>

и теперь вы можете использовать эту переменную (вместо встроенного vw unit), чтобы установить размер шрифта. Е. Г.

p {
  font-size: calc( var(--column-width) / 100 );
}

это не чисто CSS подход, но это довольно близко.


Если проблема в том, что шрифт становится слишком большим на широкоэкранном рабочем столе, я думаю, что самый простой метод css будет примерно таким (при условии, что обертка max 1000px wide)

.specialText{
    font-size:2.4vw;
}

@media only screen and (min-width: 1000px) {
    .specialText {
        width:24px;
    }
}

таким образом, это автоматический размер для любого экрана меньше, чем максимальная ширина вашего контейнера, и фиксированный размер, когда экран шире (как практически все настольные/ноутбуки)