基于容器宽度的字体缩放


1185

我很难理解字体缩放。

目前,我有这个网站与身体font-size的100%。不过是100%这似乎可以计算出16个像素。

我给人的印象是100%会以某种方式引用浏览器窗口的大小,但是显然不是因为将窗口缩小到移动宽度还是全尺寸的宽屏桌面总是16像素。

如何使网站上的文本相对于其容器而言?我尝试使用em,但这也无法扩展。

我的理由是,当你调整,这东西像我的菜单中就被压扁,所以我需要降低px font-size.menuItem相对其它元素的容器的宽度之中。(例如,在大型桌面上的菜单中,22px效果很好。向下移动至数位板宽度16px比较合适。)

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


34
font-size: 100%;表示文本原尺寸的100%(即从其父级继承的文本)。默认情况下为16px。因此,如果您使用50%,则字体大小为:8px
Andy

31
您正在寻找的是所谓的响应式或视口大小的版式。css-tricks.com/viewport-size-typography
gearsdigital

8
FitText看看。
Patsy Issa 2013年

12
@Andy:实际上,默认情况下,用户将浏览器的文字大小设置为“默认”,不一定将其解析为16px。
ScottS

Answers:


1494

编辑:如果容器不是正文, CSS Tricks将在“将文本适合容器”中涵盖您的所有选项。

如果容器是主体,则您要查找的是视口百分比长度

视口百分比长度是相对于的尺寸初始包含块。更改初始包含块的高度或宽度时,将对其进行相应缩放。但是,当根元素上的溢出值为auto时,则假定不存在任何滚动条。

值是:

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

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

使用它看起来像这样:

p {
    font-size: 4vw;
}

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

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

浏览器支持相当不错,但是您可能需要一个备用,例如:

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

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

另外,请查看CSS技巧以获得更广泛的外观:视口大小的版式

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

以下是有关使用calc()设置大小以使文本填充视口的文章:http : //codepen.io/CrocoDillon/pen/fBJxu

另外,请查看这篇文章,该文章也使用一种称为“熔化引导”的技术来调整行高。熔融领先CSS


546
但是,如果容器不是视口(正文)怎么办?
亚历克斯

12
@Alex,那是JS领域。尝试使用FitText.js@jbenjohnson提供的文章底部提供的替代方法。
罗伯特

10
这就是所谓的元素查询的来源。与媒体查询不同,元素查询将根据其包含块(而不是视口)调整大小,这真是太棒了!但是不幸的是它还不存在。但是,如果您有兴趣,可以使用一些填充和概念验证:coding.smashingmagazine.com/2013/06/25/…filamentgroup.com/lab/element_query_workarounds
jbenjohnson 2013年

139
降级,因为这不能解决问题。他问的是货柜,而不是视口。完全不同的用例。
SongBox '16

6
“初始包含块”是指根元素。这不是对所提问题的正确答案。
Glyph'2

319

但是,如果容器不是视口(主体)怎么办?

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

这个事实并不意味着vw不能在某种程度上使用该容器的大小。现在,要想看到所有变化,就必须假设容器在某种程度上是灵活的。是通过直接百分比width还是通过100%减去利润。如果容器始终设置为(例如)200px宽,则该点变为“模拟”,然后设置一个font-size适合该宽度的值。

例子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是的子项body,则它是50%100%宽度的宽度,在这种基本情况下,该宽度即为视口大小。基本上,您想设置一个vw看起来对您来说很好的。正如您在上述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为例。如果通过或JavaScript 将div切换为,则同时需要在媒体查询或JavaScript中将调整为的新计算。这将使文本大小与将原始容器的“宽度” 从视口大小减小一半时的大小相同,但由于其自身百分比计算的更改而现在减小了。25%@mediafont-size5vw * .25 = 1.2550%

一个挑战

使用CSS3 calc()功能时,动态调整将变得困难,因为该功能目前无法正常使用font-size。因此,如果您更改宽度,则无法进行纯CSS 3调整calc()。当然,对边距宽度的微小调整可能不足以保证的任何变化font-size,因此可能无关紧要。


(存在一个具有视口百分比长度并调整窗口大小的Chrome错误:code.google.com/p/chromium/issues/detail?
id=124331

@thirtydot:不幸的是(但是很高兴知道,谢谢)。希望该错误能尽快得到解决,但看起来它已经存在了一段时间。
ScottS

20
好的答案,但是,如果包含元素具有最大宽度,它将无法工作。
Himmators 2014年

3
@KristofferNolgren:这与我的回答中提出的两点有关:(1)“假设容器在某种程度上具有弹性”(一旦达到“最大宽度”,它将不再弯曲,因此便出现了问题)。(2)如果可以确定在什么时候达到“最大宽度”,那么正如我所指出的,您可以设置一个@media断点来更改字体在该点的大小设置(在到达时基本上给定固定大小max-width) 。只是想与max-width情况结合使用。
ScottS 2014年

您是否认为可以通过媒体查询动态更改容器元素的时间?我不确定我是否理解。
J82 2015年

58

SVG解决方案:

<div style="width: 60px;">  
  <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>
</div>

https://jsfiddle.net/qc8ht5eb/


使用SVG和文本包装的解决方案foreignObject

<svg viewBox="0 0 100 100">
  <foreignObject width="100%" height="100%">
    <h1>heading</h1>

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

https://jsfiddle.net/2rp1q0sy/


1
首先,这个想法看起来不错。然后,您意识到无法轻松控制<html>中SVG上的字体。移动设备和台式机上的字体不同,这会影响最终宽度。
Stopi,2016年

@Stopi您如何看待iFrame解决方案?示例
Dantio '17

10
您可以完全通过HTML / CSS设置SVG的样式
gman,

1
如果svg是内联的,则可以使用CSS设置SVG的样式(不要使用img标签)。

8
这是基于动态容器扩展的最佳,最可预测的解决方案。
JoshuaDavid '18 -4-10

35

在我的一个项目中,我在vw和vh之间使用“混合”来调整字体大小以满足我的需要,例如:

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

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


3
您最好使用vmin和/或vmax代替。
sebastian_k

4
chrome开发者工具将此称为无效的属性值
phil294 '18

29

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

这恰恰不是OP要求的,但是可能会让某人感到高兴。这个答案并非一spoon而就,需要在开发人员方面进行一些研究。

我终于来了一个用于calc()不同单元的纯CSS解决方案。您将需要对公式有一些基本的数学理解,以计算出的表达式calc()

当我解决这个问题时,我必须获得一个全页面宽度的响应头,并在DOM中填充一些父母。我将在这里使用我的值,并用您自己的值替换。

对数学

你会需要:

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

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

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

砰!有效!我写

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

到我的标题,它在每个视口中都进行了很好的调整。

但是它是如何工作的呢?

我们在这里需要一些常量。100vw表示视口的全宽,我的目标是建立具有一定填充量的全宽标题。

比例。在一个视口中获取宽度和高度可以使我有一个可以玩的比例,并且通过比例我知道在另一个视口宽度中高度应该是多少。手工计算它们将花费大量时间,并且至少会占用大量带宽,因此这不是一个好答案。

结论

我不知道为什么没人能弄清楚这一点,而有些人甚至告诉我们,修改CSS是不可能的。我不喜欢在调整元素中使用JavaScript,因此我不接受JavaScript(而不必考虑jQuery)答案,而无需进行更多的研究。总而言之,弄清楚这一点是一件好事,这是网站设计中纯CSS实现的第一步。

我很抱歉我的文字中有任何不寻常的约定,我不是英语母语人士,并且对于编写Stack Overflow答案也很陌生。

还应该注意的是,在某些浏览器中,我们有邪恶的滚动条。例如,当我使用Firefox时,我注意到这100vw意味着视口的整个宽度在滚动条下扩展(其中内容无法扩展!),因此必须小心留白全角文本,并且最好在许多浏览器和设备上进行测试。


13
仅当(1)您知道字体,(2)该字体在用户设备上可用以及(3)文本始终相同时,此解决方案才有效。这使其成为非常有限的用例。
Andrei Volgin

我不明白如果我的容器是固定的,例如:640px和16:9的比例。我应该写哪个算术?
pery mimon '17

1
您的容器宽度x为640px,比例为r16:9,因此: x = 640px, r = 16 / 9, y = x / r = 640px / (16 / 9) = 360px
hegez

注意:仅当您实际使用16:9大小的文本时这才有效,这是一种奇怪的情况。也许第二次阅读答案可能有所帮助。而且,这仅适用于单线。
hegez

老实说,您不会解释“在某些视口中调整得很好的比率。我使用了320像素,因此我得到了24像素高和224像素宽,所以比率是9.333 ...或28/3”,我建议解释比率多一点。该比率代表什么?
3limin4t0r

28

这个问题有一个大哲学。

最简单的方法是为body指定一定的字体大小(我建议为10),然后所有其他元素的字体都在em或中rem。我将举一个例子来理解这些单元。 Em总是相对于其父级:

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 总是相对于身体:

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像素宽度的容器中,您将拥有p一个12像素字体大小的元素。在您的想法上,它将变成一个300像素宽的容器,字体大小为4像素。必须有一个下限。

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

但是,我建议的解决方案是使用JavaScript库来帮助您解决此问题。以及到目前为止我找到的fittext.js


6
rem单元是相对于该根元素,这意味着该html元件,而不是body元件。DOM中的根元素是html标签。developer.mozilla.org/zh-CN/docs/Web/CSS/length .. rem始终相对于html标签,标签是根元素,而不是body标签..但很好的回答:)
Jonathan Marzullo

fittext.js使工作完成,我建议该解决方案!
杰西克·齐祖斯基斯基

FitText是我的赢家。尝试了一些替代方法,但这似乎是最简单的方法,并且与Drupal / Backdrop CMS集成得很好。github.com/davatron5000/FitText.js
辅助Joel,

23

这是函数:

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

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

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

document.body.setScaledFont(0.35);
window.onresize = function() {
    document.body.setScaledFont(0.35);
}

http://jsfiddle.net/0tpvccjt/


1
到目前为止,这是最好的解决方案
wp学生

不良做法和严重低效
Jack Giffin

@tntrox与今天一样低效,但4年前效率低得多。我拒绝此答案,以替代更好的选择。是的,要获得IE支持,就需要Javascript。但是,不需要那么可怕的Javascript。
杰克·吉芬

3
我想我的无知在这里显示。但是,为什么上述可怕?

我认为这并不可怕。我建议进行一些小的格式更改,以使其更具可读性。我至少将每个var放在单独的行上。return this函数结尾可能没有必要。为了提高性能,您可能还希望对onresize进行反跳,以便在拖动时不会重绘。这是一些非常简单的代码,因此有人可以毫不费力地基于其改进的解决方案。
Mnebuerquo

19

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

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

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

的HTML

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

的CSS

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/


4
此解决方案与已接受的vw调整大小没有什么不同。如果您更改文本,一切都会超出范围。
N69S

14

这可能不太实用,但是如果您希望字体是父字体的直接功能,而没有任何侦听/循环(间隔)以读取div /页面大小的JavaScript,则有一种方法可以做到这一点。 。iframe。

iframe中的所有内容都会将iframe的大小视为视口的大小。因此,诀窍是仅制作一个iframe,其宽度是您希望文本成为的最大宽度,并且其高度等于最大高度*特定文本的纵横比。

排除视口单位不能同时出现在文字的旁边父单位的限制(例如,具有%大小的行为与其他所有人一样),视口单位确实提供了一个非常强大的工具:能够获得最小/最大尺寸。您无法在其他任何地方执行此操作-您不能说...使此div的高度成为父级*的宽度。

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

对于我的特定示例,您有

.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中附加我想要的规则。

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只是我自定义的单击拖动功能。


@quemeful当我们引入“ new”“ shiny”(请打鼓 ...)srcdoc属性时,情况并非如此:jsfiddle.net/wauzgob6/3
Jack Giffin

9

使用vwem&co。当然可以工作,但是IMO它始终需要人的触动才能进行微调。

这是我基于@ tnt-rox' 答案编写的脚本,该脚本试图使人的触摸自动化:

$('#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)
div {
  width: 50%;
  background-color: tomato;
  font-family: 'Arial';
}

h2 {
  white-space: nowrap;
}

h2:nth-child(2) {
  font-style: italic;
}
<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>Test String</h2>
  <h2>Sweet Concatenation</h2>
  <h2>Font Scaling</h2>
</div>

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

JSFiddle


1
仅仅为承认ems需要人的触觉和垂直节奏的人而+1 并不是某种巫术。
serraosays

7

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

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


7

在CSS内,尝试将其添加到底部,以将320像素的宽度更改为设计开始中断的位置:

    @media only screen and (max-width: 320px) {

        body { font-size: 1em; }

    }

然后根据需要在“ px”或“ em”中指定字体大小。


7

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

它非常简单,但是效果很好,并且非常易于使用。你不必知道任何有关字体使用,一切由浏览器的照顾。

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

魔术发生在这里:

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;
};

1
由于此脚本将在每次调整大小事件和/或方向更改时运行,因此不建议使用此脚本。而不是使用基于javascript的解决方案,而是寻找如上所述的基于CSS的解决方案。
皮拉图斯2015年

1
调整大小和方向是“稀有”事件,这里没有性能问题。如果愿意,请不要绑定到事件(例如,如果它们不调整容器的大小,例如对于无响应的网站)。CSS解决方案并非在所有情况下都可以正常工作,而无需像该解决方案那样考虑任何事情(例如字体的宽度等)。
文森特

我将您的答案包装为jQuery函数。它接收最大允许高度,最小和最大字体大小。参见jsfiddle.net/oriadam/qzsy760k
oriadam '16

6

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

您可以像这样使用它:

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


6

我准备了使用CSS转换而不是font-size的简单缩放功能。您可以在任何容器中使用它,而不必设置媒体查询等。:)

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

编码:

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


我认为OP正在寻找CSS解决方案。
m02ph3u5

5

使用CSS变量

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

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

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

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

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

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



5

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

因此,我编写了自己的小插件,假设您拥有overflow: hidden,可以减小字体大小以适合容器,white-space: 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);

5

从艺术上讲,如果您需要在同一宽度内容纳两行或更多行文本,而不管它们的字符数如何,那么您就有不错的选择。

最好找到一个动态的解决方案,这样无论输入什么文本,我们最终都能得到漂亮的显示。

让我们看看我们该如何处理。

var els     = document.querySelectorAll(".divtext"),
refWidth    = els[0].clientWidth,
refFontSize = parseFloat(window.getComputedStyle(els[0],null)
                               .getPropertyValue("font-size"));

els.forEach((el,i) => el.style.fontSize = refFontSize * refWidth / els[i].clientWidth + "px")
#container {
  display: inline-block;
  background-color: black;
  padding: 0.6vw 1.2vw;
}
.divtext {
  display: table;
  color: white;
  font-family: impact;
  font-size: 4.5vw;
}
<div id="container">
  <div class="divtext">THIS IS JUST AN</div>
  <div class="divtext">EXAMPLE</div>
  <div class="divtext">TO SHOW YOU WHAT</div>
  <div class="divtext">YOU WANT</div>
</div>

我们要做的就是获取第一行的宽度(els[0].clientWidth)和字体大小(parseFloat(window.getComputedStyle(els[0],null).getPropertyValue("font-size")))作为参考,然后相应地计算后续行的字体大小。


4

尝试使用fitText插件,因为视口大小不能解决此问题。

只需添加库:

<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' });

这仅对大显示文本有用,而对段落不建议使用。
Shiv

3

看一下我的代码。这使得font size smallerfit任何那里。

但是我认为这并不能带来良好的用户体验

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);
    }
});

结果


2

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



2

始终让您的元素具有以下属性:

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

要么

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

全屏显示时,您应该已经计算出一个比例变量(比例> 1或比例= 1)。然后,在全屏模式下:

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

只需少量代码即可很好地工作。


2

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

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

只需添加CSS:

.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;
}

和脚本:

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

2

这为我工作:

我尝试根据设置`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是将与高度匹配的字体大小;取最小值

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元素或一个小于其父元素的元素,否则,如果子元素和parent都具有相同的width / height函数,则会失败。



1

为了使字体大小适合其容器而不是窗口,请参阅resizeFont()我在此问题中共享的功能(其他答案的组合,其中大多数答案已在此处链接)。使用触发window.addEventListener('resize', 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用作后备广告,因此您可以动态分配emrem使用JavaScript使用单位,以确保在禁用JavaScript的情况下字体确实可以缩放到窗口。

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

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

注意:font-size必须将默认值设置为emrem%获得适当的结果。


1

的HTML

<div style="height:100px; width:200px;">
  <div id='qwe'>
    test
  </div>
</div>

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

var fontSize, maxHeight, maxWidth, textElement, parentElement;
textElement = document.getElementById('qwe');
parentElement = textElement.parentElement;    
maxHeight = parentElement.clientHeight;
maxWidth = parentElement.clientWidth;
fontSize = maxHeight;
var minFS = 3, maxFS = fontSize;
while (fontSize != minFS) {
  textElement.style.fontSize = `${fontSize}px`;
  if (textElement.offsetHeight < maxHeight && textElement.offsetWidth <= maxWidth) {
    minFS = fontSize;
  } else{
    maxFS = fontSize;
  }
  fontSize = Math.floor((minFS + maxFS)/2);
}
textElement.style.fontSize = `${minFS}px`;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.