5

我正在寻找一种方法来使等宽文本在其容器中尽可能宽,但不会溢出或破裂。我已经看过CSS3 Make Text As Big as possible To FIll Element without Overflowing并尝试实施建议的解决方案,但它似乎不适用于我的情况。如果我将字体大小设置为3vw而不是7vw链接问题的答案中建议的那样,它似乎很接近,但是当我更改线条的长度或页面的宽度时,它又会关闭。

这是我的代码:

https://jsfiddle.net/de7qbu19/(fiddle里的代码是一样的)

#song-container {
    text-align: center;
    margin: 20px;
}
#song {
    color: #000;
    font: normal 3vw Courier New,monospace,Courier;
    white-space: pre;
    word-break: break-all;
    text-align: left;
    display: inline-block;
}

#song > span { /* Chords*/
    color: #007fbf;
    cursor: pointer;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
            
<div class="container-fluid">
    <div id="song-container">
        <div class="panel panel-default">
            <div class="panel-body">
                <span id="song">
[Placeholder]

<span>Em</span>         <span>G</span>
Placeholder Placeholder Placeholder Placeholder
<span>D</span>          <span>C</span>
Placeholder Placeholder Placeholder Placeholder
                </span>
            </div>
        </div>
    </div>
</div>

当我运行该片段时,它似乎几乎占据了整个宽度: 小的 但是当我单击该Full page选项时,很明显它没有并且它不可靠,尤其是当我减小窗口大小时: 全面屏小赢

因此,使用单位设置字体大小vw似乎对我没有用。

有什么想法可以正确实现吗?

4

3 回答 3

3

如果您对 javascript 解决方案很满意,这里有一个简单的解决方案。

它包括检索div的宽度和字体大小,计算单个字符的宽度,最后根据这些信息计算出新的最大字体大小。

您还必须在脚本中指定最长文本行上可以包含的最大字符数:

Placeholder Placeholder Placeholder Placeholder

在上面的示例中,最长的文本行有 47 个字符;

var container = document.getElementById("container"),
  cs = getComputedStyle(container),
  containerPB = parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight) + parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth), //containerPadding + containerBorderWidth
  containerWidth = container.offsetWidth - containerPB,
  containerFontSize = parseFloat(cs.fontSize),
  containerFontFamily = cs.fontFamily,
  span = document.createElement("SPAN"),
  char = document.createTextNode("a"),
  charMax = 47, //max characters per line
  alpha = 1.00; //represent font scaling based on width
span.style.fontFamily = containerFontFamily;
span.appendChild(char);
span.style.visibility = "hidden";
document.body.appendChild(span);
//GETTING THE WIDTH OF A SINGLE CHAR
var charWidth = span.getBoundingClientRect().width;
document.body.removeChild(span);
container.style.fontSize =
  (containerWidth * containerFontSize * alpha) / (charWidth * charMax) + "px";
window.addEventListener("resize", function(e) {
  //update the width of container
  containerWidth = container.offsetWidth - containerPB;
  //update the font-size
  container.style.fontSize =
    (containerWidth * containerFontSize * alpha) / (charWidth * charMax) + "px";
});
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

#container {
  border: 1px solid #ddd;
  color: #000;
  font-family: Courier New, monospace, Courier;
  margin: 0 auto;
  padding: 0.375rem;
  width: 90%;
}

#container>span {
  /* Chords*/
  color: #007fbf;
  cursor: pointer;
}
<pre id="container">[Placeholder]

<span>Em</span>         <span>G</span>
Placeholder Placeholder Placeholder Placeholder
<span>D</span>          <span>C</span>
Placeholder Placeholder Placeholder Placeholder</pre>

于 2020-04-28T22:27:11.710 回答
3

我们先来看看为什么文本的大小是现在的样子。3vw表示3%视口宽度。需要注意的重要一点是,此值用于字符的高度。我们可以以视口宽度的百分比来计算全文的宽度。这仅适用于单声道字体。

首先,我们需要字体的宽度/高度比率。等宽字符的宽度取决于字体。我将使用Courier New这个例子。我不确定在哪里可以找到这个,所以我将使用99/188.

字符测量的图像

如果最大字符数是:

11 * 4 (Placeholder) + 3 (spaces) = 47

那么47个字符的宽度是:

47 * 3vw * (99/188) = 74.25vw

所以关于75%视口宽度。这意味着当填充、边距和边框占用25%的宽度超过宽度时(由于调整窗口大小),文本的内容将不再适合其容器。

那么我们如何使内容适合?我们可以使用 CSScalc()函数从动态值中减去一些静态值。为此,我们首先必须知道静态值的宽度。在您的示例中,这些是静态宽度:

  • 20px保证金为#song-container
  • 15px填充.container-fluid
  • 1px边框.panel
  • 15px填充.panel-body

不要忘记所有这些值都存在于两侧,因此它们占用:

(20px + 15px + 1px + 15px) * 2 = 102px

我们不能从 中减去这个3vw,因为3vw是一个字符的高度,而102px是静态元素的宽度。所以我们现在需要将 转换102px为一个字符的高度。这是通过将宽度分布在所有字符上,然后应用比率从字符宽度转换为高度来完成的。

102px / 47 / (99/188) ≈ 4.121212121

现在我们正在比较苹果和苹果,我们可以使用calc(3vw - 102px / 47 / (99/188))字体大小。您现在可以自由地使用该3vw值。在示例中,我将此值提高到3.5vw.

请注意,这不是 100% 准确的,我没有考虑字符间距,并且字体宽度/高度比基于测量值,而不是给定值。

#song-container {
    text-align: center;
    margin: 20px;
}
#song {
    color: #000;
    font-size: calc(3.5vw - 102px / 47 / (99/188));
    font-family: "Courier New",monospace,Courier;
    white-space: pre;
    word-break: break-all;
    text-align: left;
    display: inline-block;
}

#song > span { /* Chords*/
    color: #007fbf;
    cursor: pointer;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
            
<div class="container-fluid">
    <div id="song-container">
        <div class="panel panel-default">
            <div class="panel-body">
                <span id="song">
[Placeholder]

<span>Em</span>         <span>G</span>
Placeholder Placeholder Placeholder Placeholder
<span>D</span>          <span>C</span>
Placeholder Placeholder Placeholder Placeholder
                </span>
            </div>
        </div>
    </div>
</div>

这可行,但是当静态宽度、最大字符数或字体宽度/高度比发生变化时,您必须重新计算补偿值。出于这个原因,JavaScript 库可能更适合。您可以在 CSS-Tris 文章将文本装入容器中找到其中的一些描述。

我还建议查看基于容器宽度的字体缩放问题,该问题还有其他一些建议。

于 2020-05-04T18:00:11.827 回答
0

我很少有可以提高响应能力的事情是:

#song-container{
 text-align: center;
 margin:0;
overflow: hidden;
}

.panel-body{
 margin: 0;
}

如果您希望溢出是可滚动的,您可以添加overflow-x: scroll;此外,如果您使用媒体查询也会使其更具响应性,因为即使使用我的方法,如果屏幕只有 220 像素,它会减少一些由于字体缩放速度不够快,您可以更改媒体查询以在达到此点后更快地缩放字体以将其保留在您的容器中。希望这可以帮助!

编辑:

  #song-container {
    text-align: center;
    /*margin: 20px;*/
    padding: 1%;
}
#song {
    color: #000;
    font: normal 3vw Courier New,monospace,Courier;
    white-space: pre;
    word-break: break-all;
    text-align: left;
    display: inline-block;
}

#song > span { /* Chords*/
    color: #007fbf;
    cursor: pointer;
}
.panel-body{
  padding:0;
}

这应该这样做,我在小提琴中编辑它。

于 2020-05-04T21:27:09.577 回答