Flexbox.Вычислите размер шрифта, чтобы разместить текст как на однострочных, так и на многострочных элементах - PullRequest
3 голосов
/ 16 марта 2019

У меня есть гибкий контейнер 100vh, колонка направления. Под ним у меня есть динамическое количество элементов flex с одинаковой высотой. Все эти гибкие элементы занимают все вертикальное пространство:

<div>
  <ul class="container">
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
  </ul>
</div>

и css:

ul {
  display: flex;
  flex-direction: column;
  height: 100vh;
}
li {
  flex: 1 1 auto;
}

Элементы содержат текст. И я хочу подогнать текст под высоту элемента. Поэтому я использую js с единицами просмотра для вычисления правильного размера шрифта:

var lis = document.querySelectorAll('li');
var fontsize = (100 / lis.length) * 0.8;
document.querySelector('.container').style.fontSize = fontsize + "vh";

Вот полная рабочая скрипка, которую я только что описал.

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

<div>
  <ul class="container">
   <li>1</li>
   <li>2</li>
   <li>multiline becomes a problem with this approach</li>
  </ul>
</div>

Вот демонстрация проблемы.

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

Мой подход

Возможный подход, о котором я могу подумать, будет следующим:

1 Detect number of li's
2 Trigger font-size calculation as seen above and apply
3 Calculate if any lis text will wrap onto new lines and how many (how?)
  3.a. If no texts wrap into new lines stop here.
  3.b. If there is text that wraps into new lines 
    3.b.1. Sum number of li's + all new lines on all multiline li's
    3.b.2. Re-trigger font-size calculation with this number and apply
    3.b.3. Calculate again if any li's text will wrap onto how many new lines, and compare with before font-size change.
      3.b.4.a. If there are the same ammount of new lines, stop here.
      3.b.4.b. If there are more new lines, repeat from step 3.b.1

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

Итак, как подойти к этой проблеме?

Этот вопрос был помечен как возможный дубликат из этого другого вопроса . Но этот вопрос специально требует вписать текст в одну строку, а это совсем другое дело.

Тем не менее, я мог бы извлечь некоторые подсказки из некоторых ответов, поскольку они пытаются угадать, переполняет ли текст div. В частности, мне любопытно этот ответ , как @Hoffmann специально говорит, чтобы попытаться избежать проблемы петли, которую я упоминаю в своем подходе. Я попытаюсь понять код его плагина, который теперь поддерживается кем-то еще здесь: https://github.com/BrOrlandi/big-text.js/blob/master/big-text.js

Спасибо

1 Ответ

0 голосов
/ 17 марта 2019

Используя моноширинный шрифт, основные единицы измерения (vh только не vw), justify-content: spaced evenly, line-height являются основными факторами, используемыми в демо.


/* Reset */
* {
  margin: 0;
  padding: 0;
}
/* 
- Serif and Sans Serif fonts vary greatly, monospaced   
  fonts are a lot easier to use. 
- Assign the primary font on :root so if an explicit font-
  size is set elsewhere rem units reference font-size on 
  :root directly. 
- The font shorthand is as follows:
    font: font-weight, font-size/line-height, font-family
  line-height set at 10vh fits 100vh high <ul> well.
*/
:root {
  font: 400 6vh/10vh Consolas;
}
html, body {
  width: 100%;
  height: 100%;
}
body {
  overflow-x: hidden;
  overflow-y: scroll;
  margin: 5vh 15vh 0 10vh;
}
/*
Assign max-height: 100vh to the element containing the <ul>
*/
main {
  width: 96%;
  max-height: 100vh;
}
/* 
justify-content: space-evenly is exactly what it says 
*/
ul {
  display: flex;
  flex-direction: column;
  justify-content: space-evenly;
  height: 100vh;
}
li {
  flex: 1 1 auto;
}
<main>
  <ul>
    <li>One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin.</li>
    <li>He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections.</li>
    <li>The bedding was hardly able to cover it and seemed ready to slide off any moment.</li> 
    <li>His many legs, pitifully thin compared with the size of the rest of him, waved about helplessly as he looked.</li>
    <li>"What's happened to me?" he thought. It wasn't a dream.</li>
  </ul>
</main>
...