it-swarm.com.ru

Масштабирование шрифта в зависимости от ширины контейнера

Мне трудно разобраться с масштабированием шрифтов.

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

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

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

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

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

917
Francesca

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

Если контейнер является телом, то, что вы ищете, это Длина в процентах от Viewport :

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

Значения: 

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

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

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

p {
    font-size: 4vw;
}

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

Эти значения являются единицами размера, как и px или em, поэтому их можно использовать для измерения других элементов, таких как width, margin или padding.

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

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/

1278
jbenjohnson

Но что, если контейнер не является областью просмотра (телом)?

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

Этот факт не означает, что 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, вы можете «обдумать» это математически с точки зрения полного размера области просмотра, но вы не нуждаются, чтобы сделать это. Текст будет «сгибаться» с контейнером, потому что контейнер сгибается с изменением размера области просмотра. ОБНОВЛЕНИЕ: вот пример двух контейнеров разного размера .

Пример 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() стало бы трудно динамически настраиваться, поскольку в настоящее время эта функция не работает для целей font-size. Таким образом, вы не можете выполнить чистую настройку CSS3, если ваша ширина меняется на calc(). Конечно, небольшая корректировка ширины полей может быть недостаточной, чтобы гарантировать изменение font-size, поэтому это может не иметь значения.

277
ScottS

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

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

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

29
lsblsb

Решение с 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/

27
Danto

Существует большая философия для этого вопроса. Самое простое, что можно сделать, это задать определенный размер шрифта для тела (я рекомендую 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 */

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

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, скажем так. И по вашей идее, это будет в контейнере шириной 300px с размером шрифта 4px. Должен быть нижний предел Другое решение будет с медиа-запросами, чтобы вы могли установить шрифт для различной ширины.

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

21
Dan Ovidiu Boncut

Обновлено, потому что я получил отрицательный голос.

Вот функция:

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/

20
tnt-rox

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

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

Наконец-то я пришел, чтобы получить решение для чистого 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, не копая больше. В общем, хорошо, что это выяснили, и это один из шагов к реализации чистого CSS в дизайне сайта. 

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

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

18
hegez

Есть способ сделать это БЕЗ javascript!

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

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

HTML

<div>
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360.96 358.98" >
      <text>SAVE $500</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/

Хотите что-нибудь более роскошное?

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

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

14
Aaron Loften

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

Если не принимать во внимание ограничение на то, что единицы видового экрана не могут также встречаться с боковыми родительскими единицами для текста (например, если размер% ведет себя как все остальные), единицы видового экрана действительно предоставляют очень мощный инструмент: возможность получить измерение мин/макс. , Вы не можете сделать это где-нибудь еще - вы не можете сказать ... сделайте высоту этого 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 fiddle: https://jsfiddle.net/0jr7rrgm/3/ (Нажмите один раз, чтобы заблокировать красный квадрат для мыши, нажмите еще раз, чтобы отпустить)

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

13
Roman Rekhler

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

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

$('#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, '$1' ));
      }
      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

7
WoodrowShigeru

ты ищешь что-то подобное? =>
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
});
6
Sijav

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

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

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

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

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

6
scoota269

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

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

       body { font-size: 1em; }

    }

Затем укажите желаемый размер шрифта в «px» или «em».

6
Chunky

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

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

6
Pixel Reaper

Мое собственное решение, основанное на 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;
};
6
Vincent

Я подготовил простую функцию масштабирования, используя преобразование 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

5
Maciej Korsan

Моя проблема была похожа, но связана с масштабированием текста внутри заголовка. Я попробовал Fit Font, но мне нужно было включить компрессор, чтобы получить какие-либо результаты, так как он решал немного другую проблему, как Text Flow. Поэтому я написал свой собственный небольшой плагин, который уменьшает размер шрифта для соответствия размеру контейнера, предполагая, что у вас есть 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);
5
Aram Kocharyan

взгляните на мой код, он делает 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

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

3
Basheer AL-MOMANI

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

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

Ответ - система двойной пропорции:

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

Теперь X - это размер шрифта, который будет соответствовать ширине, 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, произойдет сбой

2
Maurizio Ricci

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

2
thdoan

Для динамического текста этот плагин весьма полезен 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();
2
pajouk

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

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

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

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

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

2
pk1557

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

<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' });
2
dsb

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

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

или же

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

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

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

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

2
marirena

Используйте CSS-переменные

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

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

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

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

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

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

1
user993683

Чтобы размер шрифта соответствовал его контейнеру, вместо окна посмотрите на функцию 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 или % для достижения правильных результатов.

1
Joshua Flood

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

1
Smart Coder

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

Ниже приведено изменение размера шрифта к размеру контейнера, независимо от того, масштабируется ли контейнер до размера области просмотра или достиг его максимального значения. Если у вас есть контейнеры шириной не 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;
    }
}
0
Justin Krause

Но что, если контейнер не является областью просмотра (телом)?

Реальный ответ находится в свойстве transform, позволяющем визуально манипулировать элементом, наклоняя, поворачивая, переводя или масштабируя:

https://css-tricks.com/almanac/properties/t/transform/

0
Crystal