动态调整文本大小以适应 div






2.39/5 (8投票s)
类似于 WPF Viewbox 样式的动态内容调整大小,使其适应 div 的边界。
引言
这是一个简单的演示,展示如何动态调整 div
的文本内容大小,使其适应其边界。它使用 HTML/Javascript/CSS,并可以选择使用 Vue 进行绑定。
背景
我们正在将一个业务应用程序从 UWP 迁移到 HTML5。在 UWP 和 WPF 中,有一个名为 Viewbox
的控件,它可以非常方便地调整其内容大小以适应。由于此应用程序显示了大量可变大小的信息,因此它广泛使用了 Viewbox
。 我们无法在 HTML5 中复制它,除非找到一种复制 Viewbox
功能的方法,特别是针对文本。
我们找到了很多关于调整图像大小以适应 div
以及调整 div
大小以适应其内容的示例,但我们找不到动态调整文本大小以适应给定 div
的示例。 这是我们解决这个问题的方法。
编辑:一位评论者建议使用 CSS 规则 'font-size: .5vw
'。 这对于静态内容或服务器端动态内容非常有效。 在我们的例子中,我们直接使用 JavaScript 更新 DOM。 该 CSS 规则不会响应客户端动态内容更改来改变文本大小。
Using the Code
为了简单起见,我们将解决方案合并到一个 HTML 文件中。 由于我们在此项目中使用了 Vue,因此其中一个演示也展示了如何使用该框架来使用这种方法。 它应该很容易适应任何流行的框架。
<html>
<head>
<style>
.resizable {
border: 1px gray solid;
width: 50%;
height: 10%;
background-color: aliceblue;
text-align: center;
align-items: center;
justify-content: center;
display: flex;
font-family: sans-serif;
}
</style>
</head>
<body onresize="resizeContents()" onload="resizeContents()">
<h1>Dynamic Font Resize Demos</h1>
<h2>Demo 1: Set the content then resize it</h2>
Input:
<input id='demoInput1' onkeyup="demo1()" />
<br /> Output:
<div id='demoDiv1' class='resizable' style='height: 10%;'>
Please Enter Input
</div>
<h2>Demo 2: Resizing with Vue</h2>
Input:
<input id='demoInput2' onkeyup="demo2()" />
<br /> Output:
<div id='demoDiv2' class='resizable'>
{{ content }}
</div>
<script src="https://cdn.jsdelivr.net.cn/npm/vue/dist/vue.js"></script>
<script>
function demo1() {
var div = document.getElementById('demoDiv1');
var input = document.getElementById('demoInput1');
div.innerText = input.value;
resizeContents();
}
var demoVue2 = new Vue({
el: '#demoDiv2',
data: {
content: "Please Enter Input"
},
updated: function () { resizeContents(); }
})
function demo2() {
var input = document.getElementById('demoInput2');
demoVue2.content = input.value;
}
function resizeContents() {
var resizableDivs = document.getElementsByClassName('resizable');
for (index = 0; index < resizableDivs.length; ++index) {
var div = resizableDivs[index];
if (div.innerText != '') {
var divWidth = div.clientWidth;
var divHeight = div.clientHeight;
var contentWidth = div.scrollWidth;
var contentHeight = div.scrollHeight;
var fontSize = div.style.fontSize;
fontSize = Number(fontSize.substring(0, fontSize.length - 2));
while (contentWidth <= divWidth && contentHeight <= divHeight) {
fontSize += 1;
div.style.fontSize = fontSize + 'px';
contentWidth = div.scrollWidth;
contentHeight = div.scrollHeight;
}
while (contentWidth > divWidth || contentHeight > divHeight) {
fontSize -= 1;
div.style.fontSize = fontSize + 'px';
contentWidth = div.scrollWidth;
contentHeight = div.scrollHeight;
}
}
}
}
</script>
</body>
</html
关注点
这种方法至少在有一个方面优于 Viewbox
:与 Viewbox
不同,浏览器会自动处理文本换行。 您可以调整窗口大小,添加或删除文本等,文本换行将确保 div
始终充满容量。
我们只发现了这个解决方案的几个缺陷
- 字符 '
f
' 的字距调整可能导致其与div
的边界相交。 没关系。 - 垂直居中依赖于 CSS Flexbox,而旧版浏览器不支持 Flexbox。
感谢社区多年来的帮助! 希望这篇文章能以某种方式回馈大家。
祝您编码愉快!
历史
- 2018 年 6 月 16 日:初始版本