如何缩放任意文本以始终适合视口宽度? [英] How can I scale arbitrary text to always fit the viewport width?

查看:43
本文介绍了如何缩放任意文本以始终适合视口宽度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在忙于工作的网站有一个部分,其中包含一些非常大的标题.有些事情我不确定如何处理:

A site I'm busy working on has a section with some very large headings. There's something I'm not sure how to handle:

标题可以是一两个短或长的词,例如:Cyprus"到Nouvelle Zelande",并且它必须缩放到与视口的宽度大致相同.这意味着Cyprus"与Nouvelle Zelande"相比,较短的文本将具有更大的单个字符.

The heading may be one two short or long words, e.g: "Cyprus" to "Nouvelle Zelande", and it must scale to be roughly the width of the viewport. That means "Cyprus", being shorter, will have larger individual characters than longer text than "Nouvelle Zelande".

我认为使用 JavaScript 相对容易做到这一点,但我想采用纯 HTML/CSS 解决方案.所以:如何缩放文本以适应视口的宽度?到目前为止,我自己很困惑,不知道该怎么做.

This would be relatively easy to do with JavaScript, I think, but I'd like to go for a pure HTML/CSS solution. So: how can I scale text to fit the width of the viewport? So far, I'm stumped and not sure how to do it, myself.

一些细节:

  • 您只需定位到每个浏览器的最新版本,其中包括 IE11.
  • 您可以使用在这些浏览器中运行的任何和所有 HTML5 和 CSS3.
  • 您可以将文本Nouvelle Zelande"自动换行,只要两个单词中较长的单词仍然大致适合可用宽度即可.
  • 您可以在标题内部/周围添加额外的元素.

请注意,视口单位不是解决方案. 之前提出的问题 (纯 CSS 制作字体-基于动态字符数量的大小响应基于容器宽度的字体缩放) 有使用视口单位,如 vw!",但这根本无法处理这种情况,精明的读者甚至 指出这个.我什至在下面的代码示例中使用了 vw 来演示它的非解决方案.它会根据视口调整大小,但不会根据文本量调整大小.

Note that viewport units are not a solution. Previous questions asking about this (Pure CSS to make font-size responsive based on dynamic amount of characters, Font scaling based on width of container) have answers of "use viewport units, like vw!", but that doesn't handle this scenario at all, and astute readers even pointed this out. I've even used vw in the code sample below to demonstrate its non-solution-ness. It'll size based on the viewport just fine, but won't do any sizing based on the amount of text.

h2 {
  font-family: sans-serif;
  text-transform: uppercase;
  font-size: 14vw;
  white-space: nowrap;
  overflow-x: hidden;
  margin: 0;
}

<h2>Nouvelle Zelande</h2>
<h2>Australia</h2>
<h2>Cyprus</h2>

推荐答案

唯一的单位,如果用于设置字体大小,即相对于其容器的大小,是视口单位vw/vh,它不会单独解决您的情况,即使容器与视口的宽度相同,因为它不会计算字母大小以适合到容器中.

The only unit, if being used to set font size, that is relative to the size of its container, is viewport units vw/vh, which will not solve your case alone, even if the container is the same width as the viewport, since it does not calc the letter size to fit into the container.

我能想到的最接近的非脚本解决方案是使用 CSS 元素计数器技巧,并将每个字母包裹在 span

The closest non-script solution I can come up with is to use the CSS element counter trick, and wrap each letter in a span

我在这里设置的 130vw 对给定的字体效果最好,尽管这可能需要根据使用的字体系列进行调整.

The 130vw I set here, worked best for the given font, though this might need to be adjusted based on which font family is being used.

h2 {
  display: inline-block;
  font-family: sans-serif;
  text-transform: uppercase;
  white-space: nowrap;
  overflow-x: hidden;
  margin: 0;
}

/* 1 letter */
h2 span:first-child:nth-last-child(1) {
    font-size: 130vw;
}
/* skipped 2-5 in this demo */

/* 6 letters */
h2 span:first-child:nth-last-child(6),
h2 span:first-child:nth-last-child(6) ~ span {
    font-size: calc(130vw / 6);
}

/* skipped 7-14 in this demo */

/* 15 letters */
h2 span:first-child:nth-last-child(15),
h2 span:first-child:nth-last-child(15) ~ span {
    font-size: calc(130vw / 15);
}

<h2><span>N</span><span>o</span><span>u</span><span>v</span><span>e</span><span>l</span><span>l</span><span>e</span> &nbsp;<span>Z</span><span>e</span><span>l</span><span>a</span><span>n</span><span>d</span><span>e</span></h2><br>
<h2><span>C</span><span>y</span><span>p</span><span>r</span><span>u</span><span>s</span></h2>

这里是使用脚本的相同概念,没有span

Here is the same concept using a script, and without the span's

(function (d,t) {
  window.addEventListener("resize", throttler, false);
  window.addEventListener("load", throttler(), false);  /*  run once on load to init  */
  
  function throttler() {
    if ( !t ) {
      t = setTimeout(function() {
        t = null;
        keepTextFit(d.querySelectorAll('h2'));
       }, 66);
    }
  }
  function keepTextFit(el) {
    var f = el[0].getAttribute("data-font");
    for (var i = 0; i < el.length; i++) {
      var c = el[i].textContent.split('').length;      
      el[i].style.cssText = 
        'font-size: calc(' + f + ' / ' + c + ')';
    }
  }
})(document,null);

h2 {
  display: inline-block;
  font-family: sans-serif;
  text-transform: uppercase;
  white-space: nowrap;
  overflow-x: hidden;
  margin: 0;
}

<h2 data-font="130vw">Nouvelle Zelande</h2>
<h2>Australia</h2>
<h2>Cyprus</h2>

注意,因为 resize 事件 可以高速触发,节流器用于降低速率,因此处理程序不会过于频繁地执行昂贵的操作,例如 DOM 修改.

如果您想完美合身,请查看此帖子:fit-text-perfectly-inside-a-div

If you want to make a perfect fit, check this post: fit-text-perfectly-inside-a-div

这篇关于如何缩放任意文本以始终适合视口宽度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆