关于css:基于容器宽度的字体缩放

Font scaling based on width of container

我很难理解字体缩放。

我目前这个网站的主体font-size为100%。但是100%的是什么?这似乎计算出16像素。

我的印象是,100%会以某种方式引用浏览器窗口的大小,但显然不是因为它总是16像素,无论窗口是否调整为移动宽度或完整的宽屏桌面。

如何使我的网站上的文本与其容器相关?我尝试使用em,但这也没有扩展。

我的理由是,当你调整大小时,我的菜单之类的东西会变得模糊,所以我需要减少与容器宽度相关的其他元素中的px .menuItem。 (例如,在大型桌面上的菜单中,22px完美运行。向下移动到平板电脑宽度,16px更合适。)

我知道我可以添加断点,但我真的希望文本可以扩展以及有额外的断点,否则我最终会为每100个像素的宽度减少数百个断点来控制文本。


编辑:如果容器不是主体CSS Tricks涵盖了将文本拟合到容器中的所有选项。

如果容器是正文,那么您要查找的是视口百分比长度:

The viewport-percentage lengths are relative to the size of the initial containing block. When the height or width of the initial containing block is changed, they are scaled accordingly. However, when the value of overflow on the root element is auto, any scroll bars are assumed not to exist.

价值观是:

  • vw(视口宽度的百分比)
  • vh(视口高度的百分比)
  • vi(在根元素的内联轴方向上视口大小的1%)
  • vb(根元素块轴方向视口大小的1%)
  • vmin(vwvh中的较小者)
  • vmax(较大或vwvh)

1 v *等于初始包含块的1%。

使用它看起来像这样:

1
2
3
p {
    font-size: 4vw;
}

如您所见,当视口宽度增加时,font-size也会增加,而无需使用媒体查询。

这些值是一个大小单位,就像pxem一样,因此它们也可用于调整其他元素的大小,例如宽度,边距或填充。

浏览器支持非常好,但您可能需要回退,例如:

1
2
3
4
p {
    font-size: 16px;
    font-size: 4vw;
}

查看支持统计信息:http://caniuse.com/#feat=viewport-units。

另外,请查看CSS-Tricks以获得更广泛的外观:Viewport Sized Typography

这是一篇很好的文章,关于设置最小/最大尺寸并对尺寸进行更多控制:精确控制响应式排版

这里有一篇关于使用calc()设置大小的文章,以便文本填充视口:http://codepen.io/CrocoDillon/pen/fBJxu

另外,请查看这篇文章,该文章使用了一种名为"熔化前导"的技术来调整线高。在CSS中熔化领先


但是如果容器不是视口(正文)怎么办?

Alex根据接受的答案在评论中提出了这个问题。

这个事实并不意味着vw在某种程度上不能用于该容器的大小。现在要看到任何变化都必须假设容器在某种程度上是灵活的。是通过直接百分比width还是通过100%减去边距。如果容器总是设置为200px宽,则该点变得"没有实际意义" - 然后只需设置一个适用于该宽度的font-size

例1

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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;
}

假设divbody的子元素,它是100%宽度的50%,这是此基本情况下的视口大小。基本上,你想设置一个对你来说很好看的vw。正如您在上面的CSS内容中的评论中所看到的,您可以通过数学方式"思考"整个视口大小,但您不需要这样做。文本将与容器"flex",因为容器在视口大小调整时弯曲。更新:这是两个不同大小的容器的示例。

例2

您可以通过强制执行基于此计算的计算来帮助确保视口大小调整。考虑这个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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%宽度,那么font-size同时需要在媒体查询或JavaScript中调整5vw * .25 = 1.25的新计算。这将使文本大小与原始50%容器的"宽度"从视口大小减少一半时的大小相同,但现在由于其自身百分比计算的变化而减小。

一个挑战

使用CSS3 calc()函数时,将很难动态调整,因为此函数此时不能用于font-size目的。因此,如果宽度在calc()上发生变化,则无法进行纯CSS3调整。当然,对边距宽度的微小调整可能不足以保证font-size的任何变化,因此可能无关紧要。


SVG解决方案:

1
2
3
4
  <svg width="100%" height="100%" viewBox="0 -200 1000 300"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <text font-size="300" fill="black">Text</text>
  </svg>

https://jsfiddle.net/qc8ht5eb/

使用foreignObject进行SVG和文本换行的解决方案:

1
2
3
4
5
6
7
<svg viewBox="0 0 100 100">
  <foreignObject width="100%" height="100%">
    heading

    lorem ipsum dolor sit amet
  </foreignObject>
</svg>

https://jsfiddle.net/2rp1q0sy/


在我的一个项目中,我使用vw和vh之间的"混合"来根据我的需要调整字体大小,例如:

1
font-size: calc(3vw + 3vh);

我知道这不能回答OP的问题,但也许它可以成为其他任何人的解决方案。


这个问题有一个很大的哲学。

最简单的做法是给身体一个字体大小(我推荐10),然后所有其他元素的字体都在emrem中。
我会举个例子来了解这些单位。
em始终相对于其父级:

1
2
3
body{font-size: 10px;}
.menu{font-size: 2em;} /* That means 2*10 pixels  = 20 pixels */
.menu li{font-size: 1.5em;} /* That means 1.5*20 pixels = 30 pixels */

rem总是相对于身体:

1
2
3
body{font-size: 10px;}
.menu{font-size: 2rem;} /* That means 2*10 pixels = 20 pixels */
.menu li{font-size: 1.5rem;} /* that means 1.5*10 pixels = 15 pixels */

然后你可以创建一个脚本来修改相对于容器宽度的字体大小。
但这不是我推荐的。因为在一个900像素宽的容器中,例如,你会有一个带有12像素字体大小的p元素。而你的想法将成为一个300像素宽的容器,4像素字体大小。必须有一个下限。

其他解决方案将使用媒体查询,以便您可以设置不同宽度的字体。

但我建议的解决方案是使用一个可以帮助你的JavaScript库。到目前为止我发现的fittext.js。


这是功能:

1
2
3
4
5
document.body.setScaledFont = function(f) {
  var s = this.offsetWidth, fs = s * f;
  this.style.fontSize = fs + '%';
  return this
};

然后将所有文档子元素字体大小转换为em%

然后在代码中添加类似的内容以设置基本字体大小。

1
2
3
4
document.body.setScaledFont(0.35);
window.onresize = function() {
    document.body.setScaledFont(0.35);
}

http://jsfiddle.net/0tpvccjt/


带有calc(),CSS单位和数学的纯CSS解决方案

这正是OP所要求的,但可能会成为某人的一天。这个答案并非易于使用,需要对开发人员进行一些研究。

我最终使用不同单位的calc()来获得纯CSS解决方案。您将需要对公式的基本数学理解来计算calc()的表达式。

当我解决这个问题时,我不得不得到一个整页宽度响应的标题,其中一些填充在DOM中的父母很少。我会在这里使用我的值,用你自己的值替换它们。

对数学

你会需要:

  • 在某些视口中调整好的比例。我使用320像素,因此我得到24像素高和224像素宽,因此比率为9.333 ...或28/3
  • 容器宽度,我有padding: 3em和全宽,所以这到100wv - 2 * 3em

X是容器的宽度,因此请将其替换为您自己的表达式,或者调整该值以获取整页文本。 R是您将拥有的比率。您可以通过调整某些视口中的值,检查元素宽度和高度并使用您自己的值替换它们来获取它。此外,它是width / heigth;)

1
2
3
4
5
6
7
8
x = 100vw - 2 * 3em = 100vw - 6em
r = 224px/24px = 9.333... = 28 / 3

y = x / r
  = (100vw - 6em) / (28 / 3)
  = (100vw - 6em) * 3 / 28
  = (300vw - 18em) / 28
  = (75vw - 4.5rem) / 7

砰!有效!我写

1
font-size: calc((75vw - 4.5rem) / 7)

到我的标题,它在每个视口中调整得很好。

但它是如何工作的?

我们需要一些常量。 100vw表示视口的整个宽度,我的目标是使用一些填充建立全宽标题。

比例。在一个视口中获得宽度和高度让我得到一个比率,并且我知道在其他视口宽度中的高度应该是多少。用手计算它们需要花费大量时间,至少需要大量带宽,所以这不是一个好的答案。

结论

我想知道为什么没有人想到这一点,有些人甚至说这不可能修补CSS。我不喜欢在调整元素时使用JavaScript,所以我不接受JavaScript甚至jQuery的答案而不需要更多。总而言之,这一点很好,这是网站设计中纯CSS实现的一步。

我为我的文本中的任何不寻常的约定道歉,我不是英语母语,也是编写StackOverflow答案的新手。

还应该注意的是,在某些浏览器中我们有邪恶的滚动条。例如,当使用Firefox时,我注意到100vw表示视口的整个宽度,在滚动条下延伸(内容无法展开!),因此必须仔细地对全文文本进行边距处理,最好使用许多浏览器和设备进行测试。


没有JavaScript,有一种方法可以做到这一点!

您可以使用内联SVG图像。如果SVG是内联的,您可以在SVG上使用CSS。您必须记住,使用此方法意味着您的SVG图像将响应其容器大小。

尝试使用以下解决方案......

HTML

1
2
3
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360.96 358.98">
      <text>SAVE $500</text>
  </svg>

CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
div {
  width: 50%; /* Set your container width */
  height: 50%; /* Set your container height */

}

svg {
  width: 100%;
  height: auto;

}

text {
  transform: translate(40px, 202px);
  font-size: 62px;
  fill: #000;
}

例:
https://jsfiddle.net/k8L4xLLa/32/

想要更华丽的东西吗?

SVG图像还允许你做形状和垃圾的酷东西。查看这个可扩展文本的大用例...

https://jsfiddle.net/k8L4xLLa/14/


这可能不太实用,但是如果你想让一个字体成为父类的直接函数,而没有任何监听/循环(间隔)的JavaScript来读取div / page的大小,那么有一种方法可以做到这一点。 。 I帧。

iframe中的任何内容都会将iframe的大小视为视口的大小。因此,诀窍是只创建一个iframe,其宽度是您希望文本的最大宽度,其高度等于特定文本的纵横比的最大高度*。

抛开视口单元不能同时出现文本的旁边父单元的限制(如同,%大小的行为与其他人一样),视口单元确实提供了一个非常强大的工具:能够获得最小/最大尺寸。你不能在其他地方做到这一点 - 你不能说......让这个div的高度成为父*的宽度。

话虽这么说,诀窍是使用vmin,并设置iframe大小,以便当高度是限制尺寸时,[fraction] *总高度是一个好的字体大小,当宽度是时,[fraction] *总宽度限制尺寸。这就是为什么高度必须是宽度和纵横比的乘积。

对于我的具体例子,你有

1
2
3
4
5
6
7
8
9
10
.main iframe{
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: calc(3.5 * 100%);
  background: rgba(0, 0, 0, 0);
  border-style: none;
  transform: translate3d(-50%, -50%, 0);
}

使用此方法的小麻烦是您必须手动设置iframe的CSS。如果附加整个CSS文件,则会占用许多文本区域的大量带宽。所以,我所做的是直接从我的CSS附加我想要的规则。

1
2
3
var rule = document.styleSheets[1].rules[4];
var iDoc = document.querySelector('iframe').contentDocument;
iDoc.styleSheets[0].insertRule(rule.cssText);

您可以编写小函数来获取可能影响文本区域的CSS规则/所有CSS规则。

没有一些自行车/听力JavaScript,我想不出另一种方法。真正的解决方案是浏览器提供一种方法来缩放文本作为父容器的函数,并提供相同的vmin / vmax类型功能。

的jsfiddle:
https://jsfiddle.net/0jr7rrgm/3/
(单击一次将红色方块锁定到鼠标,然后再次单击以释放)

小提琴中的大多数JavaScript都只是我的自定义点击拖动功能。


使用vwem&co。肯定是有效的,但IMO总是需要人的触摸才能进行微调。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
$('#controller').click(function(){
    $('h2').each(function(){
        var
            $el = $(this),
            max = $el.get(0),
            el = null
        ;
        max =
            max
            ? max.offsetWidth
            : 320
        ;
        $el.css({
            'font-size': '1em',
            'display': 'inline',
        });
        el = $el.get(0);

        el.get_float = function(){
            var
                fs = 0
            ;
            if (this.style && this.style.fontSize) {
                fs = parseFloat(this.style.fontSize.replace(/([\d\.]+)em/g, '$1'));
            }
            return fs;
        };

        el.bigger = function(){
            this.style.fontSize = (this.get_float() + 0.1) + 'em';
        };

        while (el.offsetWidth < max) {
            el.bigger();
        }

        // Finishing touch.
        $el.css({
            'font-size': ((el.get_float() -0.1) +'em'),
            'line-height': 'normal',
            'display': '',
        });
    });  // end of (each)
});    // end of (font scaling test)
1
2
3
4
5
6
7
8
9
10
11
12
13
div {
  width: 50%;
  background-color: tomato;
  font-family: 'Arial';
}

h2 {
  white-space: nowrap;
}

h2:nth-child(2) {
  font-style: italic;
}
1
2
3
4
5
6
7
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
<input type="button" id="controller" value="Apply" />

  Lorem ipsum dolor
  Test String
  Sweet Concatenation
  Font Scaling

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

的jsfiddle


我自己的解决方案,基于jQuery,通过逐渐增加字体大小,直到容器的高度大幅增加(意味着它有一个换行符)。

它非常简单,但效果相当好,而且非常易于使用。您不必了解正在使用的字体,浏览器会处理所有内容。

你可以在http://jsfiddle.net/tubededentifrice/u5y15d0L/2/上玩它

魔术发生在这里:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var setMaxTextSize=function(jElement) {
    // Get and set the font size into data for reuse upon resize
    var fontSize=parseInt(jElement.data(quickFitFontSizeData)) || parseInt(jElement.css("font-size"));
    jElement.data(quickFitFontSizeData, fontSize);

    // Gradually increase font size until the element gets a big increase in height (i.e. line break)
    var i = 0;
    var previousHeight;
    do
    {
        previousHeight=jElement.height();
        jElement.css("font-size","" + (++fontSize) +"px");
    }
    while(i++ < 300 && jElement.height()-previousHeight < fontSize/2)

    // Finally, go back before the increase in height and set the element as resized by adding quickFitSetClass
    fontSize -= 1;
    jElement.addClass(quickFitSetClass).css("font-size","" + fontSize +"px");

    return fontSize;
};


你可能在寻找这样的东西:

http://jsfiddle.net/sijav/dGsC9/4/
http://fiddle.jshell.net/sijav/dGsC9/4/show/

我使用了flowtype,它工作得很好(但它是JavaScript而不是纯CSS解决方案):

1
2
3
4
5
6
7
$('body').flowtype({
    minFont: 10,
    maxFont: 40,
    minimum: 500,
    maximum: 1200,
    fontRatio: 70
});

此Web组件更改字体大小,以使内部文本宽度与容器宽度匹配。检查演示。

你可以像这样使用它:

1
<full-width-text>Lorem Ipsum</full-width-text>


试试http://simplefocus.com/flowtype/。这是我用于我的网站,它完美地工作。


在CSS内部,尝试在底部添加此项,在设计开始破坏的任何地方更改320像素宽度:

1
2
3
4
5
    @media only screen and (max-width: 320px) {

        body { font-size: 1em; }

    }

然后根据需要在"px"或"em"中给出font-size。


100%是相对于基本字体大小的,如果您尚未设置,则将是浏览器的用户代理默认值。

为了获得你想要的效果,我将使用一段JavaScript代码来调整相对于窗口尺寸的基本字体大小。


我已经使用CSS变换而不是font-size准备了一个简单的缩放函数。您可以在任何容器内使用它,您不必设置媒体查询等。:)

博客文章:
全宽CSS和JS可扩展标头

代码:

1
2
3
4
5
6
7
8
9
10
11
12
function scaleHeader() {
  var scalable = document.querySelectorAll('.scale--js');
  var margin = 10;
  for (var i = 0; i < scalable.length; i++) {
    var scalableContainer = scalable[i].parentNode;
    scalable[i].style.transform = 'scale(1)';
    var scalableContainerWidth = scalableContainer.offsetWidth - margin;
    var scalableWidth = scalable[i].offsetWidth;
    scalable[i].style.transform = 'scale(' + scalableContainerWidth / scalableWidth + ')';
    scalableContainer.style.height = scalable[i].getBoundingClientRect().height + 'px';
  }
}

工作演示:
https://codepen.io/maciejkorsan/pen/BWLryj


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

所以我编写了自己的小插件,减小了字体大小以适应容器,假设你有overflow: hiddenwhite-space: nowrap,这样即使将字体缩小到最小值也不允许显示完整的标题,它只是切断了它能表现出什么。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
(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);

使用CSS变量

还没有人提到CSS变量,这种方法对我来说效果最好,所以:

假设您的页面上有一列是移动用户屏幕宽度的100%,但是max-width为800px,因此在桌面上,列的两侧都有一些空间。把它放在页面顶部:

1
 document.documentElement.style.setProperty('--column-width', Math.min(window.innerWidth, 800)+'px');

现在您可以使用该变量(而不是内置的vw单元)来设置字体的大小。例如。

1
2
3
p {
  font-size: calc( var(--column-width) / 100 );
}

它不是纯粹的CSS方法,但它非常接近。


尝试使用fitText插件,因为Viewport大小不是此问题的解决方案。

只需添加库:

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

并通过设置文本系数来更改font-size以获得正确:

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

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

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


看看我的代码。它使font size smallerfit无论如何。

但我认为这不会带来良好的用户体验

1
2
3
4
5
6
7
8
9
10
11
12
var containerWidth = $("#ui-id-2").width();
var items = $(".quickSearchAutocomplete .ui-menu-item");
var fontSize = 16;

items.each(function(){
    // Displaying a value depends sometimes on your case. You may make it block or inline-table instead of inline-block or whatever value that make the div take overflow width.
    $(this).css({"whiteSpace":"nowrap","display":"inline-block"});
    while ($(this).width() > containerWidth){
         console.log("$(this).width()" + $(this).width() +"containerWidth" + containerWidth)
         $(this).css("font-size", fontSize -= 0.5);
    }
});

Result


这对我有用:

我尝试根据设置`font-size:10px`得到的宽度/高度来近似字体大小。基本上,这个想法是"如果我有20像素的宽度和11像素的高度,`font-size:10px`,那么最大的字体大小是什么,数学容量为50像素宽度和30像素高度?"

答案是双比例系统:

{20:10 = 50:X,11:10 = 30:Y} = {X =(10 * 50)/ 20,Y =(10 * 30)/ 11}

现在X是一个匹配宽度的字体大小,Y是一个匹配高度的字体大小;取最小的价值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function getMaxFontSizeApprox(el){
    var fontSize = 10;
    var p = el.parentNode;

    var parent_h = p.offsetHeight ? p.offsetHeight : p.style.pixelHeight;
    if(!parent_h)
        parent_h = 0;

    var parent_w = p.offsetHeight ? p.offsetWidth : p.style.pixelWidth;
    if(!parent_w)
        parent_w = 0;

    el.style.fontSize = fontSize +"px";

    var el_h = el.offsetHeight ? el.offsetHeight : el.style.pixelHeight;
    if(!el_h)
        el_h = 0;

    var el_w = el.offsetHeight ? el.offsetWidth : el.style.pixelWidth;
    if(!el_w)
        el_w = 0;

    // 0.5 is the error on the measure that JavaScript does
    // if the real measure had been 12.49 px => JavaScript would have said 12px
    // so we think about the worst case when could have, we add 0.5 to
    // compensate the round error
    var fs1 = (fontSize*(parent_w + 0.5))/(el_w + 0.5);
    var fs2 = (fontSize*(parent_h) + 0.5)/(el_h + 0.5);

    fontSize = Math.floor(Math.min(fs1,fs2));
    el.style.fontSize = fontSize +"px";
    return fontSize;
}

注意:函数的参数必须是span元素或小于其父元素的元素,否则如果children和parent具有相同的width / height函数将失败。


始终拥有包含此属性的元素:

JavaScript:element.style.fontSize ="100%";

要么

CSS:style ="font-size: 100%;"

当您全屏显示时,您应该已经计算了比例变量(比例> 1或比例= 1)。然后,全屏:

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

它与很少的代码很好地协作。


对于动态文本,此插件非常有用:

http://freqdec.github.io/slabText/

只需添加CSS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
.slabtexted .slabtext
{
    display: -moz-inline-box;
    display: inline-block;
    white-space: nowrap;
}
.slabtextinactive .slabtext
{
    display: inline;
    white-space: normal;
    font-size: 1em !important;
    letter-spacing: inherit !important;
    word-spacing: inherit !important;
    *letter-spacing: normal !important;
    *word-spacing: normal !important;
}
.slabtextdone .slabtext
{
    display: block;
}

和剧本:

1
$('#mydiv').slabText();


如果它对任何人都有帮助,那么这个主题中的大多数解决方案都是将文本包装成多行,形式为e。

但后来我发现了这个,它起作用了:

https://github.com/chunksnbits/jquery-quickfit

用法示例:

$('.someText').quickfit({max:50,tolerance:.4})


作为JavaScript后备(或您唯一的解决方案),您可以使用我的jQuery Scalem插件,它允许您通过传递reference选项相对于父元素(容器)进行缩放。


HTML

1
    test

用于最大化字体大小的JavaScript代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
el = document.getElementById('qwe');
maxFontPixels = 50;
maxHeight = el.parentElement.offsetHeight;
fontSize = Number(maxFontPixels || maxHeight);
el.style.width = '100%';
el.style.overflowWrap = 'break-word';
var minFS = 3, maxFS = fontSize;
while (fontSize != minFS) {
  el.style.fontSize = `${fontSize}px`;
  if (el.offsetHeight < maxHeight) {
    minFS = fontSize;
  }
  else {
    maxFS = fontSize;
  }
  fontSize = Math.floor((minFS + maxFS)/2);
}
el.style.fontSize = `${minFS}px`;

我没有看到任何关于CSS flex属性的答案,但它也非常有用。


为了使font-size适合它的容器而不是窗口,请参阅我在这个问题中共享的resizeFont()函数(其他答案的组合,其中大部分已在此处链接)。它是使用window.addEventListener('resize', resizeFont);触发的。

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

JavaScript的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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动态分配emrem单位,确保在禁用JavaScript时字体会扩展到窗口。

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

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

注意:默认font-size必须设置为emrem%才能获得正确的结果。


直接的媒体查询似乎是一个更简单,更容易理解的解决方案,根据可能是动态的容器大小调整字体大小。

下面将字体大小调整为容器的大小,无论容器是否缩放到视口的大小,或者是否达到其最大值。如果您有非100%宽的容器,则可以相应地调整vw

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.container {
    width: 100%;
    max-width: 600px;
}
.headline {
    font-size: 20vw;
}
.subhead {
    font-size: 5vw;
}
@media (min-width:600px) {
    .headline {
        font-size: 120px;
    }
    .subhead {
        font-size: 32px;
    }
}

如果问题是在宽屏桌面上字体变得过大,我认为最简单的CSS方法就是这样(假设包装最大宽度为1000像素)

1
2
3
4
5
6
7
8
9
.specialText{
    font-size: 2.4vw;
}

@media only screen and (min-width: 1000px) {
    .specialText {
        width: 24px;
    }
}

因此,对于小于容器最大宽度的任何屏幕,它都是自动调整大小的,并且当屏幕较宽时(例如几乎所有台式机和笔记本电脑)都固定大小。


但是如果容器不是视口(正文)怎么办?

真正的答案是在transform属性中允许您通过倾斜,旋转,平移或缩放来可视地操作元素:

transform