CSS中的响应式字体大小

442

我使用Zurb Foundation 3网格创建了一个网站。每个页面都有一个大的h1标签:

body {
  font-size: 100%
}

/* Headers */

h1 {
  font-size: 6.2em;
  font-weight: 500;
}
<div class="row">
  <div class="twelve columns text-center">
    <h1> LARGE HEADER TAGLINE </h1>
  </div>
  <!-- End Tagline -->
</div>
<!-- End Row -->

当我将浏览器调整为移动设备大小时,大字体不会自动调整大小,导致浏览器需要包含水平滚动条来适应大文本。

我发现在Zurb Foundation 3排版示例页面上,标题会随着浏览器的压缩和扩展而自适应。

我是否漏掉了一些非常明显的东西?我该如何实现这一点?


CSS的rem单位不会根据视口窗口动态调整大小。如果您需要这样做,则需要使用Javascript或以下纯CSS3答案之一。这只是在大标题文本上需要的东西。 - Evan Donovan
@ToolmakerSteve 这是一个非常幼稚的说法,特别是在跨所有设备响应的问题上。rem并不是一个很好的选择,你似乎只是因为它“复杂”而忽略了答案? - Emobe
@Emobe - 我同意 - 我的评论过于简单。我目前不从事Web编程,但如果我从事,我可能会像Buzz的答案一样将css calcremvw结合起来,以避免在极小/大尺寸时出现问题。主要是想让人们意识到rem避免了em的问题,从而简化了响应式解决方案(通过媒体查询减少重复)。并且使其不必依赖于SASS来实现此目的。 - ToolmakerSteve
@Emobe - csuwldcat的回答是一个很好的起点:使基础字体在所有情况下都保持合理大小可能会简化其他计算。通过使用几个媒体查询来微调基础(正文)大小可能就足够了;然后使用rem来处理其他元素的工作。偶尔使用上面提到的calc。最重要的是避免重复的媒体查询,这些查询容易在进行更改时出现错误。 - ToolmakerSteve
如果您根据宽度设置基础字体大小,字体大小似乎会变得响应式。嘭! - Jovylle
34个回答

695

您可以使用视口单位(viewport)代替ems、pxs或pts:

1vw = 视口宽度的1%

1vh = 视口高度的1%

1vmin = 1vw和1vh中较小的那个

1vmax = 1vw和1vh中较大的那个

h1 {
  font-size: 5.9vw;
}
h2 {
  font-size: 3.0vh;
}
p {
  font-size: 2vmin;
}

来自CSS-Tricks:视窗尺寸大小的排版


2
我目前只编写针对 WebKit 的代码 - 我非常喜欢这个度量标准,谢谢。 - Jeff Voss
21
@MurtazaHussain 请参考:“我可以使用视口单位:vw,vh,vmin,vmax吗? - insertusernamehere
42
太好了,我可以使用vw来缩放文本,这样在桌面上看起来就不会太小了!完美…哦。嗯,现在当在手机上查看时,文字太小了,无法阅读。好吧,我可以使用“max(x,y)”来确保它不会被缩小到最小尺寸以下。完美…哦。嗯。看起来Chrome没有正确支持“max”。好吧,猜我还是得再用“px”。 - original_username
14
在移动设备上,它会变得太小,在高分辨率桌面设备上则会变得太大,所以我认为这不太实际。 - Mr_Green
9
这就是为什么你需要使用媒体查询。在较小的视口上,使字体变大,在较大的视口上,使字体变小。 - Alistair
显示剩余11条评论

340

当调整浏览器窗口大小时,font-size不会做出相应的调整。相反,它们会响应浏览器缩放/字体大小设置,例如在浏览器中同时按下键盘上的Ctrl+

媒体查询

您需要查看使用媒体查询的方法,在某些间隔处降低字体大小,以防止设计出现问题并创建滚动条。

例如,请尝试在底部的CSS中添加以下内容,将320像素宽度更改为设计开始出现问题的位置:

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

   body { 
      font-size: 2em; 
   }

}

视口百分比长度

您还可以使用视口百分比长度,例如vwvhvminvmax。官方的W3C文档说明如下:

视口百分比长度相对于初始包含块的大小。当初始包含块的高度或宽度改变时,它们会相应缩放。

同样来自于W3C文档,每个单独的单位可以定义为以下内容:

vw单位 - 相当于初始包含块宽度的1%。

vh单位 - 相当于初始包含块高度的1%。

vmin单位 - 相当于vw和vh中较小的值。

vmax单位 - 相当于vw和vh中较大的值。

它们的使用方式与任何其他CSS值完全相同:

.text {
  font-size: 3vw;
}

.other-text {
  font-size: 5vh;
}

兼容性相对较好,可以在这里看到。但是,一些版本的Internet Explorer和Edge不支持vmax。此外,iOS 6和7存在vh单位问题,该问题已在iOS 8中修复。


48
font-size: 1.5vw; 是什么意思? - Dev_NIX
51
更好的是,font-size: calc(12px + 1vw) - cuzox
6
@Dev_NIX 这是什么意思? - Christiaan Westerbeek
@Cuzox,你应该将其作为答案提交,其他解决方案使测试过小,无法将这些方法用于任何有用的事情。当您结合静态高度时,它变得有用。 - ricks

94
h1{
  font-size : clamp(2rem, 10vw, 5rem);
}

这里的 clamp 函数有 3 个参数。

  • 第一个参数是最小允许的字体大小。

  • 第三个参数是最大允许的字体大小。

  • 第二个参数是您希望始终拥有的字体大小,其单位必须是相对单位(vw、vh、ch),而不是绝对单位(例如 px、mm、pt)。相对单位将使它根据屏幕尺寸的变化而改变大小。

考虑一个例子: 假设有一个很大的 FontAwesome 图标,您想要动态调整其大小(响应式图标)。

fa-random-icon{
   font-size: clamp( 15rem, 80vw, 80vh)   
}

  • 首选字体大小为80vw。
  • 最小字体大小为15rem(下限)。
  • 最大字体大小为80vh(上限)。

例如:

  • 如果在某个特定的移动屏幕尺寸中,80vw < 15rem,则字体大小为15rem。

  • 如果屏幕太宽,则如果80vw > 80vh,则字体大小为80vh。

人们建议的那些方法总是有一点不确定的结果...就像当我们只使用vw时,字体大小有时可能会太大或太小(无法界定)。

@media查询可以使用,但必须使用至少3个媒体查询才能使字体大小响应式。


这个解决方案太出色了。我之前从未听说过“clamp”。谢谢! - Laura Sage
4
这个解决方案需要在2022年成为被接受的答案。现代CSS必胜无疑。 - Joshua Dance
为“clamp”冠军鼓掌。这对我的表格非常有效。 - Blake Frederick

74
我一直在尝试找到解决这个问题的方法,我相信我已经找到了一个解决方案:
如果您可以针对Internet Explorer 9(及更高版本)和所有其他支持CSS calc()、rem单位和vmin单位的现代浏览器编写应用程序,则可以使用此方法实现可扩展文本而无需媒体查询:
body {
  font-size: calc(0.75em + 1vmin);
}

这是它的演示效果:http://codepen.io/csuwldcat/pen/qOqVNO


2
我应该指出的是,使用calc来组合这两个单位是一个简单的方法,可以帮助消除极端情况下vw文本比例的差异。 - csuwldcat
视口单位非常适用于不需要兼容旧浏览器的任何项目。这个计算技巧正是你所说的,可以平滑地缩放文本(与媒体查询设置的严格限制相反),但比屏幕尺寸变化的比例小(或大!)。 - Ward D.S.
它应该如何使用?我的意思是,如果我想改变字体的大小,我应该只改变 em 单位,只改变 vmin 单位还是两者都改变? - snoob dogg
我来这里写这个非常简单的解决方案,但看到你的答案后给了一个加1。我们可以将此解决方案应用于每个元素。例如图像宽度:calc(50px + 10vw) - y.selimdogan
使用vmin很有趣,但这意味着如果窗口的宽度或高度发生变化,文本大小也会随之改变!尝试缩小CodePen窗口(在桌面上),就会明白我的意思。 - changokun

36
使用CSS的media规范(这是[zurb]使用的方式)进行响应式样式设计:
@media only screen and (max-width: 767px) {

   h1 {
      font-size: 3em;
   }

   h2 {
      font-size: 2em;
   }

}

29

18

有几种方法可以实现这一点。

使用媒体查询,但需要为多个断点设置字体大小:

body
{
    font-size: 22px;
}

h1
{
    font-size: 44px;
}

@media (min-width: 768)
{
    body
    {
        font-size: 17px;
    }
    h1
    {
        font-size: 24px;
    }
}

请使用%或em来设置尺寸。只需更改基础字体大小,一切都会改变。与以前的方法不同,你可以仅更改正文字体而不是每次都更改h1,或者让基础字体大小保持设备默认值,其余所有内容都在em中:
  1. "Ems" (em): "em"是可缩放的单位。例如,如果文档的字体大小为12pt,则1个em等于12pt。em具有可伸缩性,因此2 em将等于24pt,0.5 em将等于6pt,依此类推。
  2. 百分比 (%):百分比单位与“em”单位非常相似,但也存在一些根本性的区别。首先,当前字体大小等于100%(即12pt = 100%)。使用百分比单位时,文本在移动设备和可访问性方面仍然完全可缩放。
请参见kyleschaeffer.com/.... CSS 3支持相对于视口的新尺寸。但这在Android上无法使用:
  1. 3.2vw = 3.2% of width of viewport
  2. 3.2vh = 3.2% of height of viewport
  3. 3.2vmin = Smaller of 3.2vw or 3.2vh
  4. 3.2vmax = Bigger of 3.2vw or 3.2vh

    body
    {
        font-size: 3.2vw;
    }
    

请查看CSS-Tricks...,并且也要看看Can I Use...


16

还有一种响应式字体大小的方法 - 使用rem单位。

html {
    /* Base font size */
    font-size: 16px;
}

h1 {
    font-size: 1.5rem;
}

h2 {
    font-size: 1.2rem;
}

在媒体查询中,您可以通过更改基础字体大小来调整所有字体大小:

@media screen and (max-width: 767px) {
    html {
      /* Reducing base font size will reduce all rem sizes */
      font-size: 13px;
    }

    /* You can reduce font sizes manually as well */
    h1 {
        font-size: 1.2rem;
    }
    h2 {
        font-size: 1.0rem;
    }
}

为了使其在Internet Explorer 7和Internet Explorer 8中工作,您必须添加一个具有px单位的备选方案:

h1 {
    font-size: 18px;
    font-size: 1.125rem;
}

如果你正在使用 Less 进行开发,你可以创建一个 mixin 来为你执行计算。

Rem 单位支持 - http://caniuse.com/#feat=rem


13

在非常小的屏幕上,“vw”解决方案存在问题。您可以使用calc()设置基本大小并从那里开始逐步增加:

“vw”解决方案对于极小屏幕存在问题,可通过设置基础大小,并使用calc()进行逐步增加解决。

font-size: calc(16px + 0.4vw);

我在标题中使用了 font-size: calc(1.2rem + 1vw)。这样我就可以使用非像素单位的优势(虽然这可能不适用于此处)。我还为旧浏览器提供了纯 ems 的备选方案。最后,由于在移动设备上字体有点小,我使用了媒体查询。这可能有点繁琐,但它似乎实现了我想要的效果。 - Evan Donovan

11

我看到了一篇非常棒的文章来自CSS-Tricks。它完全正常:

body {
    font-size: calc([minimum size] + ([maximum size] - [minimum size]) * ((100vw -
    [minimum viewport width]) / ([maximum viewport width] - [minimum viewport width])));
}
例如:
body {
    font-size: calc(14px + (26 - 14) * ((100vw - 300px) / (1600 - 300)));
}
我们可以将相同的方程应用于line-height属性,以使其随着浏览器一起变化。
body {
    font-size: calc(14px + (26 - 14) * ((100vw - 300px) / (1600 - 300)));
    line-height: calc(1.3em + (1.5 - 1.2) * ((100vw - 300px)/(1600 - 300)));
}

有没有办法使字体大小不大于定义的[最大尺寸]? - Igor Janković

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接