如何针对不同的文本长度自动收缩动态 h1 元素?
How do I autoshrink a dynamic h1 element for different text length?
我有一个动态更改其 HTML 的 h1 元素,我希望它自动缩小自身以显示较长的文本,但 return 到其固定字体大小以显示较短的文本。
这是标记:
<div class="frame" dir="ltr">
<div class="frame-view">
<h1> //dynamic text </h1>
</div>
</div>
和样式:
.frame {
z-index: 2;
position: relative;
top: 100px;
}
.frame-view {
text-align: center;
}
.frame-view h1 {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-style: normal;
font-variant: normal;
font-weight: 200;
font-size: 40px;
color: white;
padding: 0 20px;
}
这是 h1 在移动屏幕上显示长文本时的样子:
它没有停留在 20px
左、右填充内并且只是自动收缩文本,而是延伸到 HTML 之外。
在横向上它看起来不错,因为有足够的空间容纳它:
那么如何让这个 h1 自动收缩较长的文本并保持在边界内?
更新
为了进一步理解我想要实现的目标,可以这样想:
我希望 h1 的容器是静态的,并且文本在靠近容器边缘时调整其大小。想象一个标签是 50 像素,现在如果你把单词 "hello" 放在那个标签中,字体大小是 20 像素,那么它就是 20 像素字体大小没有问题..但是如果你把单词 "Hello how are you" 放在它不会适合 20 像素字体大小的边界,因此它必须自动收缩以保持在容器的边界内。
最简单的方法是使用 vw
。 vw
是 "viewport width" 的缩写。你会像这样去做:
h1 {
font-size: 4vw;
}
换句话说,<h1>
的一个字母占屏幕宽度的 4%,因为 1vw
= 屏幕宽度的 1%。
您需要尝试一下,弄清楚您需要使用什么数字才能使它为您所用。如果您发现使用 vw
根本无法实现您的目标,您也可以尝试 CSS3 calc()
(请参阅此处的示例:http://codepen.io/CrocoDillon/pen/fBJxu)。
警告#1:
但是,有一点要小心。根据元素的设置方式,这可能会导致一些不良副作用,因为 vw
的大小基于屏幕宽度,而不是包含 [=13= 的元素(如果有) ].
警告#2:
并非所有浏览器都支持 vw
。确保设置后备(font-size:24px
等),以防万一。
您应该从给定的文本宽度(以像素为单位)开始,然后使用 measuretext 函数测量给定文本的宽度。如果宽度接近容器的宽度,则缩小字体大小并重新测量。显然,在文本变得难以辨认之前,您应该限制文本的大小。一旦文本变得太小,您必须截断并在末尾添加点。
这里有一个示例,大致说明了如何操作。您需要 javascript,我已包含 jquery 以使其更容易。当您添加更多文本时,文本开始靠近框的边缘,字体大小将缩小,最小为 10 像素。之后太长的文本将被截断。
如果文本变短,您也可以使用类似的函数使文本再次变长,但反过来.. 增大字体大小直到溢出,然后后退一步。但是我没有包含代码。
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
</head>
<body>
<br>Enter your text:
<p></p>
<input type=text id=input_id style='width: 300px'></input>
<p></p>
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var txt = "Hello World more"
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var fontsize = 30
ctx.font = fontsize.toString() + "px Arial";
// ctx.fillText("width:" + ctx.measureText(txt).width, 10, 50);
// ctx.fillText(txt, 10, 100);
$('#input_id').val(txt)
ObserveInputValue('')
ObserveInputValue(txt)
// a bit crude but simple and it works: watch the input object every tenth sec
setInterval(function() {
ObserveInputValue($('#input_id').val());
}, 100);
function ObserveInputValue(iv) {
if (iv != txt) {
console.log('input value changed to: ' + iv)
txt = iv
ctx.clearRect(0, 0, 300, 150)
textwid = ctx.measureText(txt).width.toFixed(0)
// adjust font size so that text just fits
var maxfont = 50
var minfont = 10
while (textwid > 290 && fontsize > minfont) {
sizedecrease = Math.max(1, fontsize * 0.1).toFixed(0) // decrease by 10% or 1 pixel whichever is greater
fontsize -= sizedecrease
ctx.font = fontsize.toString() + "px Arial";
textwid = ctx.measureText(txt).width.toFixed(0)
}
// if text at min and still too long truncate text
while (textwid > 290 && fontsize <= minfont) {
// chop off last characters of text
txt = txt.substring(0, txt.length - 1)
textwid = ctx.measureText(txt).width.toFixed(0)
$('#input_id').val(txt)
}
// exercise to the reader.. increase font size again if user makes text shorter
ctx.fillText("width:" + textwid, 10, 50);
ctx.fillText("font:" + fontsize, 10, 100);
ctx.fillText(txt, 10, 150);
}
}
</script>
</body>
</html>
我有一个动态更改其 HTML 的 h1 元素,我希望它自动缩小自身以显示较长的文本,但 return 到其固定字体大小以显示较短的文本。
这是标记:
<div class="frame" dir="ltr">
<div class="frame-view">
<h1> //dynamic text </h1>
</div>
</div>
和样式:
.frame {
z-index: 2;
position: relative;
top: 100px;
}
.frame-view {
text-align: center;
}
.frame-view h1 {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-style: normal;
font-variant: normal;
font-weight: 200;
font-size: 40px;
color: white;
padding: 0 20px;
}
这是 h1 在移动屏幕上显示长文本时的样子:
它没有停留在 20px
左、右填充内并且只是自动收缩文本,而是延伸到 HTML 之外。
在横向上它看起来不错,因为有足够的空间容纳它:
那么如何让这个 h1 自动收缩较长的文本并保持在边界内?
更新
为了进一步理解我想要实现的目标,可以这样想:
我希望 h1 的容器是静态的,并且文本在靠近容器边缘时调整其大小。想象一个标签是 50 像素,现在如果你把单词 "hello" 放在那个标签中,字体大小是 20 像素,那么它就是 20 像素字体大小没有问题..但是如果你把单词 "Hello how are you" 放在它不会适合 20 像素字体大小的边界,因此它必须自动收缩以保持在容器的边界内。
最简单的方法是使用 vw
。 vw
是 "viewport width" 的缩写。你会像这样去做:
h1 {
font-size: 4vw;
}
换句话说,<h1>
的一个字母占屏幕宽度的 4%,因为 1vw
= 屏幕宽度的 1%。
您需要尝试一下,弄清楚您需要使用什么数字才能使它为您所用。如果您发现使用 vw
根本无法实现您的目标,您也可以尝试 CSS3 calc()
(请参阅此处的示例:http://codepen.io/CrocoDillon/pen/fBJxu)。
警告#1:
但是,有一点要小心。根据元素的设置方式,这可能会导致一些不良副作用,因为 vw
的大小基于屏幕宽度,而不是包含 [=13= 的元素(如果有) ].
警告#2:
并非所有浏览器都支持 vw
。确保设置后备(font-size:24px
等),以防万一。
您应该从给定的文本宽度(以像素为单位)开始,然后使用 measuretext 函数测量给定文本的宽度。如果宽度接近容器的宽度,则缩小字体大小并重新测量。显然,在文本变得难以辨认之前,您应该限制文本的大小。一旦文本变得太小,您必须截断并在末尾添加点。
这里有一个示例,大致说明了如何操作。您需要 javascript,我已包含 jquery 以使其更容易。当您添加更多文本时,文本开始靠近框的边缘,字体大小将缩小,最小为 10 像素。之后太长的文本将被截断。
如果文本变短,您也可以使用类似的函数使文本再次变长,但反过来.. 增大字体大小直到溢出,然后后退一步。但是我没有包含代码。
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
</head>
<body>
<br>Enter your text:
<p></p>
<input type=text id=input_id style='width: 300px'></input>
<p></p>
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var txt = "Hello World more"
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var fontsize = 30
ctx.font = fontsize.toString() + "px Arial";
// ctx.fillText("width:" + ctx.measureText(txt).width, 10, 50);
// ctx.fillText(txt, 10, 100);
$('#input_id').val(txt)
ObserveInputValue('')
ObserveInputValue(txt)
// a bit crude but simple and it works: watch the input object every tenth sec
setInterval(function() {
ObserveInputValue($('#input_id').val());
}, 100);
function ObserveInputValue(iv) {
if (iv != txt) {
console.log('input value changed to: ' + iv)
txt = iv
ctx.clearRect(0, 0, 300, 150)
textwid = ctx.measureText(txt).width.toFixed(0)
// adjust font size so that text just fits
var maxfont = 50
var minfont = 10
while (textwid > 290 && fontsize > minfont) {
sizedecrease = Math.max(1, fontsize * 0.1).toFixed(0) // decrease by 10% or 1 pixel whichever is greater
fontsize -= sizedecrease
ctx.font = fontsize.toString() + "px Arial";
textwid = ctx.measureText(txt).width.toFixed(0)
}
// if text at min and still too long truncate text
while (textwid > 290 && fontsize <= minfont) {
// chop off last characters of text
txt = txt.substring(0, txt.length - 1)
textwid = ctx.measureText(txt).width.toFixed(0)
$('#input_id').val(txt)
}
// exercise to the reader.. increase font size again if user makes text shorter
ctx.fillText("width:" + textwid, 10, 50);
ctx.fillText("font:" + fontsize, 10, 100);
ctx.fillText(txt, 10, 150);
}
}
</script>
</body>
</html>