我很难理解字体缩放。

我目前有一个字体大小为100%的网站。但这是100%的吗?这似乎是在16个像素处计算出来的。

我的印象是,100%会以某种方式指代浏览器窗口的大小,但显然不是因为无论窗口大小调整为移动宽度还是宽屏桌面,都是16像素。

如何使站点上的文本与其容器相关?我尝试过使用它们,但这也无法扩展。

我的理由是,当你调整大小时,像我的菜单这样的东西会变得压扁,所以我需要减少.menuItem等元素相对于容器宽度的px字体大小。(例如,在大型桌面上的菜单中,22px的效果非常好。向下移动到平板电脑宽度,16px更合适。)

我知道我可以添加断点,但我真的希望文本能够缩放并具有额外的断点,否则,我将以每100像素宽度减少数百个断点来控制文本。


当前回答

尝试使用fitText插件,因为Viewport大小并不能解决这个问题。

只需添加库:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

并通过设置文本系数来更改字体大小以正确:

$("#text_div").fitText(0.8);

您可以设置文本的最大值和最小值:

$("#text_div").fitText(0.8, { minFontSize: '12px', maxFontSize: '36px' });

其他回答

let textElement=document.getElementById('text1');let parentElement=textElement.parentElement;const parentClientHeight=parentElement.clientHeight;const parentClientWidth=parentElement.clientWidth;textElement.style.padding=“未设置”;textElement.style.margin=“自动”;let fontSize=parentClientHeight;设minFS=3,maxFS=fontSize;while(fontSize!=minFS){textElement.style.fontSize=`${fontSize}px`;如果(parentElement.scrollHeight<=parentClientHeight&&parentElement.scrollWidth<=parentClientWidth) {minFS=字体大小;}其他{maxFS=fontSize;}fontSize=数学楼层((minFS+maxFS)/2);}textElement.style.fontSize=`${minFS}像素';<div style=“高度:200px;宽度:300px;”><div id='text1'>测验</div></div>

容器查询是CSS功能集(2022年末)的最新添加,使这一点变得简单明了。

它们允许您基于包含元素的大小应用样式,但也提供了一组用于容器查询宽度/高度的新CSS单元cqw/cqh。要使用它们,需要在要使用其大小的父元素上设置容器类型属性。下面是一个最小的示例:

<div><p>Lorem ipsum dolor坐amet</p></div><style>第二部分{容器类型:内联大小;}p型{字体大小:5cqw;}</style>

随着父容器的增长,字体大小将平稳增加。在1000像素的容器宽度下,p字体大小将为1000像素/100*5=50像素。

容器类型可以是大小或内联大小。size跟踪容器的高度和宽度,允许您同时使用cqw和cqh。在网络上的大多数时间,高度是根据内容计算的,您只需指定宽度。为了节省浏览器的一些工作,您通常需要设置容器类型:inline-size;因此,浏览器只跟踪通常为宽度的内联维度(除非将写入模式设置为垂直)。

2022年下半年,浏览器对容器查询的支持快速增长,目前为75%(2023-01-01)。

但如果容器不是视口(主体)呢?

亚历克斯在2507rkt3的回答下的评论中提出了这个问题。

这一事实并不意味着大众汽车在一定程度上不能用于该集装箱的尺寸。现在要看到任何变化,我们必须假设容器在某种程度上是灵活的。无论是通过直接百分比宽度还是通过100%减去边距。如果容器始终设置为200px宽,那么这一点就变得“无意义”了——然后只需设置一个适用于该宽度的字体大小。

示例1

然而,对于灵活宽度的容器,必须认识到,在某种程度上,容器的大小仍在视口之外。因此,需要根据视口的百分比大小差异调整vw设置,这意味着要考虑父包装的大小。举个例子:

div {
    width: 50%;
    border: 1px solid black;
    margin: 20px;
    font-size: 16px;
    /* 100 = viewport width, as 1vw = 1/100th of that
       So if the container is 50% of viewport (as here)
       then factor that into how you want it to size.
       Let's say you like 5vw if it were the whole width,
       then for this container, size it at 2.5vw (5 * .5 [i.e. 50%])
    */
    font-size: 2.5vw;
}

假设这里的div是主体的子对象,它是100%宽度的50%,在这个基本情况下是视口大小。基本上,你想设定一个对你来说很好的大众汽车。正如我在上面的CSS内容中的评论中所看到的,你可以从数学上考虑整个视口的大小,但你不需要这样做。文本将随着容器“伸缩”,因为容器会随着视口大小的调整而伸缩。下面是两个不同大小的容器的示例。

示例2

通过强制基于此进行计算,可以帮助确保视口大小。考虑以下示例:

html {width: 100%;} /* Force 'html' to be viewport width */
body {width: 150%; } /* Overflow the body */

div {
    width: 50%;
    border: 1px solid black;
    margin: 20px;
    font-size: 16px;
    /* 100 = viewport width, as 1vw = 1/100th of that
       Here, the body is 150% of viewport, but the container is 50%
       of viewport, so both parents factor  into how you want it to size.
       Let's say you like 5vw if it were the whole width,
       then for this container, size it at 3.75vw
       (5 * 1.5 [i.e. 150%]) * .5 [i.e. 50%]
    */
    font-size: 3.75vw;
}

大小仍然基于视口外,但本质上是基于容器大小本身设置的。

如果容器的大小动态变化。。。

如果容器元素的大小最终通过@media断点或JavaScript动态改变了其百分比关系,那么无论基础“目标”是什么,都需要重新计算以保持文本大小的相同“关系”。

以上面的示例#1为例。如果div被@media或JavaScript切换为25%宽度,那么同时,字体大小需要在媒体查询或JavaScript中调整为5vw*.25=1.25的新计算值。这将使文本大小与原始50%容器的“宽度”从视口大小减小一半时的大小相同,但现在由于其自身百分比计算的变化而减小。

挑战

使用CSS calc()函数时,很难动态调整,因为该函数此时不适用于字体大小。因此,如果宽度在calc()上发生变化,则不能进行纯CSS调整。当然,对页边空白宽度的轻微调整可能不足以保证字体大小的任何改变,因此这可能无关紧要。

我刚刚创建了一个演示如何做到这一点。它使用transform:scale()来实现这一点,并使用一些监视元素大小调整的JS。非常适合我的需要。

我的问题类似,但与标题内的文本缩放有关。我尝试了Fit Font,但我需要切换压缩器以获得任何结果,因为它解决了一个稍微不同的问题,就像文本流一样。

所以我写了我自己的小插件,它减小了字体大小以适应容器,假设你有溢出:隐藏和空白:nowrap,这样即使将字体减小到最小也不允许显示完整的标题,它也会切断它可以显示的内容。

(function($) {

  // Reduces the size of text in the element to fit the parent.
  $.fn.reduceTextSize = function(options) {
    options = $.extend({
      minFontSize: 10
    }, options);

    function checkWidth(em) {
      var $em = $(em);
      var oldPosition = $em.css('position');
      $em.css('position', 'absolute');
      var width = $em.width();
      $em.css('position', oldPosition);
      return width;
    }

    return this.each(function(){
      var $this = $(this);
      var $parent = $this.parent();
      var prevFontSize;
      while (checkWidth($this) > $parent.width()) {
        var currentFontSize = parseInt($this.css('font-size').replace('px', ''));
        // Stop looping if min font size reached, or font size did not change last iteration.
        if (isNaN(currentFontSize) || currentFontSize <= options.minFontSize ||
            prevFontSize && prevFontSize == currentFontSize) {
          break;
        }
        prevFontSize = currentFontSize;
        $this.css('font-size', (currentFontSize - 1) + 'px');
      }
    });
  };
})(jQuery);