18

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

10

Я испытываю трудности с масштабированием шрифтов на своем сайте.

На данный момент у меня есть сайт с font-size тела, установленным на 100%. Но 100% от чего? Похоже, что это вычисляется как 16 пикселей.

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

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

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

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

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

5 ответ(ов)

1

Решение с использованием SVG:

.resizeme {
  resize: both;
  margin: 0;
  padding: 0;
  height: 75px;
  width: 500px;
  background-color: lightblue;
  overflow: hidden;
}
<div class="resizeme">
  <svg
    width="100%"
    height="100%"
    viewBox="0 0 500 75"
    preserveAspectRatio="xMinYMid meet"
    style="background-color:green"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink"
  >
        <text
          x="0"
          y="75"
          font-size="75"
          fill="black"
        >█Resize This█</text>
      </svg>
</div>

Решение с использованием SVG и обёртки текста с помощью foreignObject:

.resizeme {
  resize: both;
  margin: 0;
  padding: 0;
  height: 200px;
  width: 500px;
  background-color: lightblue;
  overflow: hidden;
}
<div class="resizeme">
  <svg
    width="100%"
    height="100%"
    viewBox="0 0 500 200"
    preserveAspectRatio="xMinYMin meet"
  >
      <foreignObject width="100%" height="100%" xmlns="http://www.w3.org/1999/xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml" style="background-color:lightgreen;">
          <h1>заголовок</h1>
          <p>Измените размер синего блока.</p>
        </div>
      </foreignObject>
    </svg>
</div>

В приведённом коде показаны два способа создания изменяемого по размеру блока с использованием SVG. В первом примере используется простой текст, а во втором — foreignObject для обёртки текстового содержимого в HTML-элементы. Обратите внимание, что стили CSS отвечают за функциональность изменения размеров блока.

0

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

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

Знаю, что это не отвечает на вопрос автора, но, возможно, это поможет кому-то другому.

0

Чистое решение на CSS с использованием calc(), единиц измерения и математики

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

Наконец, я нашел решение с использованием чистого CSS, применяя calc() с различными единицами. Вам потребуется базовое математическое понимание формул, чтобы правильно составить выражение для calc().

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

К математике

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

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

X — это ширина контейнера, замените её на своё выражение или отрегулируйте значение для получения текста на всю страницу. R — это соотношение, которое вы получите, отрегулировав значения в некотором окне просмотра, просмотрев ширину и высоту элемента и подставив свои значения. Также помните, что это width / height 😉

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

Извиняюсь за возможные необычные конвенции в моем тексте, я не носитель английского языка и также довольно нов на Stack Overflow.

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

0

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

Вы можете использовать встроенное изображение SVG. Если SVG встроен, вы можете применять к нему CSS. Не забывайте, что при использовании этого метода ваше изображение 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%; /* Задайте ширину вашего контейнера */
  height: 50%; /* Задайте высоту вашего контейнера */
}

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/

0

Вот функция, которую вы можете использовать:

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/.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь