如何计算字体大小以适应单文本行和多行弹性项目上的文本?

Posted

技术标签:

【中文标题】如何计算字体大小以适应单文本行和多行弹性项目上的文本?【英文标题】:How can I calculate a font-size to fit text on both single text line and multi-line flex items? 【发布时间】:2019-08-07 10:46:09 【问题描述】:

我有一个 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";

Here is the full working fiddle I just described.

我的问题是,如果弹性项目包含的文本足够多,以至于它可以换行到一个或多个新行,那么这种方法就不再适用了。

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

Here is the demonstration of the problem.

要计算多行项目的字体大小,我需要知道它占用了多少行,但这本身取决于字体大小。所以这是一个自食其果的问题。

我的方法

我能想到的一种可能的方法如下:

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 number of new lines, stop here.
      3.b.4.b. If there are more new lines, repeat from step 3.b.1

但是这种方法看起来很脏,并且会导致很多步骤的字体大小计算和调整。另外,我不确定如何执行第 3 步。

那么,如何解决这个问题呢?

此问题已被标记为可能与this other question 重复。但是这个问题特别要求将文本放入一行,这是一个非常不同的问题。

也就是说,我可能会从一些答案中得到一些提示,因为他们试图猜测文本是否溢出 div。特别是我对this answer 很好奇,因为@Hoffmann 明确表示要尝试避免我在方法中提到的循环问题。我将尝试理解他的插件的代码,现在由其他人在这里维护:https://github.com/BrOrlandi/big-text.js/blob/master/big-text.js

谢谢

【问题讨论】:

请提供minimal reproducible example 一个懒惰的选择是对字体大小执行二进制搜索。 @Nit 你能扩展你的建议吗? 您是否需要所有文本的大小相同,或者所有与文本相同的行都应根据行中的行数来适应? “行数”也可能是一个问题,因为更新文本大小会更新行数。 @Arthur 我需要所有弹性项目中的所有文本大小相同。在字体大小上统治它们。是的,更新字体大小可能会在多行弹性项目上创建更多新行。这是我在方法中描述的问题之一。谢谢 【参考方案1】:

使用等宽字体,内在单位(vh 仅不是 vw)、justify-content: spaced evenlyline-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>

【讨论】:

谢谢。如果我错了,请纠正我,但是如果 li 的数量发生变化,这将不适应,对吗?我特别要求为任何动态数量的 li 提供解决方案。

以上是关于如何计算字体大小以适应单文本行和多行弹性项目上的文本?的主要内容,如果未能解决你的问题,请参考以下文章

动态调整文本大小以使整个文本行适合文本字段

在 C++ 中计算文本文件中的文本行数时出错

QTextEdit如何将当前选定的文本行保持在屏幕上的同一位置

根据javascript中的文本行数更改textarea的高度[重复]

如何计算 DOM 元素内的文本行数?我可以吗?

如何调整字体大小以适应 UILabel 的高度和宽度