如何针对不同的文本长度自动收缩动态 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 像素字体大小的边界,因此它必须自动收缩以保持在容器的边界内。

最简单的方法是使用 vwvw 是 "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>