我很难理解字体缩放。

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

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

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

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

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


当前回答

为了使字体大小适合其容器,而不是窗口,请参阅我在这个问题中分享的resizeFont()函数(其他答案的组合,其中大多数已经链接到这里)。它使用window.addEventListener('size',resizeFont);触发;。

Vanilla JavaScript:调整字体大小以适应容器

JavaScript:

function resizeFont() {
  var elements  = document.getElementsByClassName('resize');
  console.log(elements);
  if (elements.length < 0) {
    return;
  }
  _len = elements.length;
  for (_i = 0; _i < _len; _i++) {
    var el = elements[_i];
    el.style.fontSize = "100%";
    for (var size = 100; el.scrollHeight > el.clientHeight; size -= 10) {
      el.style.fontSize = size + '%';
    }
  }
}

您可能可以使用vw/vh作为备用,因此您可以使用JavaScript动态分配em或rem单位,确保在禁用JavaScript时字体可以缩放到窗口。

将.resize类应用于包含要缩放的文本的所有元素。

在添加窗口调整大小事件侦听器之前触发函数。然后,当加载页面以及调整页面大小时,任何不适合其容器的文本都将被缩小。

注意:默认字体大小必须设置为em、rem或%,以获得正确的结果。

其他回答

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

亚历克斯在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调整。当然,对页边空白宽度的轻微调整可能不足以保证字体大小的任何改变,因此这可能无关紧要。

容器查询是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)。

使用vw,em&co.确实有效,但IMO始终需要人为的微调。

这是我刚刚根据@tnt-rox的回答编写的一个脚本,它试图使人类的触摸自动化:

$('#controller').click(function(){$('h2').each(函数){变量$el=$(此),max=$el.get(0),el=空;最大值=最大值? 最大偏移宽度: 320;$el.css({“font size”:“1em”,“display”:“inline”,});el=$el.get(0);el.get_float=函数(){变量fs=0;if(this.style&&this.style.fontSize){fs=parseFloat(this.style.fontSize.replace(/([\d\.]+)em/g,'$1'));}返回fs;};el.bigger=函数(){this.style.fontSize=(this.get_float()+0.1)+'em';};而(el.offsetWidth<max){el.bigger();}//完成触摸。$el.css({“字体大小”:((el.get_float()-0.1)+'em'),'线条高度':'正常','显示':'',});}); // 结束(每个)}); // 结束(字体缩放测试)第二部分{宽度:50%;背景色:番茄;字体系列:'Arial';}氢气{空白:nowrap;}h2:第n个孩子(2){字体样式:斜体;}<script src=“https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js“></script><input type=“button”id=“controller”value=“Apply”/><div><h2>Lorem ipsum dolor公司</h2><h2>测试字符串</h2><h2>甜蜜串联</h2><h2>字体缩放比例</h2></div>

它基本上将字体大小减小到1em,然后开始递增0.1,直到达到最大宽度。

JSFiddle公司

始终使元素具有此属性:

JavaScript:element.style.fontSize=“100%”;

or

CSS:style=“font-size:100%;”

当您进入全屏时,您应该已经计算了一个比例变量(比例>1或比例=1)。然后,在全屏幕上:

document.body.style.fontSize = (scale * 100) + "%";

它只需要很少的代码就可以很好地工作。

纯CSS在某种程度上是可能的。

.自动调整文本大小{content:url(“data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'version='1.1'height='1.3em'width='10em'><text x='0'y='0.9em'fill='red'>这里是调整大小的文本</text></svg>“);背景色:rgba(0,0,0,0.06);动画:成长2s无限交替两者;}@关键帧增长{来自{width:100px;}到{width:300px;}}<div class=“自动调整文本大小”></div>

解释

内容规则设置元素的内容,它可以是图像的URL,包括SVG图像。SVG图像可以包含文本,因此基本上您有一个带有文本的背景图像,该图像根据其父图像的大小调整大小。您也可以使用background image属性,但与内容不同,它不会影响元素的布局,因此您需要定义父元素的大小。

这种方法的问题是,您需要定义SVG中文本的颜色、大小和位置。他们不会从父母那里继承。但你可以用Sass和Less变得聪明。此解决方案还可能存在可访问性问题。

我不建议在任何地方使用。但它在某些情况下应该相当有用。