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个回答

10

这部分在Foundation 5中已经部分实现。

在文件_type.scss中,他们有两组标题变量:

// We use these to control header font sizes
// for medium screens and above

$h1-font-size: rem-calc(44) !default;
$h2-font-size: rem-calc(37) !default;
$h3-font-size: rem-calc(27) !default;
$h4-font-size: rem-calc(23) !default;
$h5-font-size: rem-calc(18) !default;
$h6-font-size: 1rem !default;


// We use these to control header size reduction on small screens
$h1-font-reduction: rem-calc(10) !default;
$h2-font-reduction: rem-calc(10) !default;
$h3-font-reduction: rem-calc(5) !default;
$h4-font-reduction: rem-calc(5) !default;
$h5-font-reduction: 0 !default;
$h6-font-reduction: 0 !default;

对于中等尺寸,他们基于第一组变量生成尺寸:

@media #{$medium-up} {
    h1,h2,h3,h4,h5,h6 { line-height: $header-line-height; }
    h1 { font-size: $h1-font-size; }
    h2 { font-size: $h2-font-size; }
    h3 { font-size: $h3-font-size; }
    h4 { font-size: $h4-font-size; }
    h5 { font-size: $h5-font-size; }
    h6 { font-size: $h6-font-size; }
}

对于默认(即小屏幕),它们使用第二组变量来生成CSS:

h1 { font-size: $h1-font-size - $h1-font-reduction; }
h2 { font-size: $h2-font-size - $h2-font-reduction; }
h3 { font-size: $h3-font-size - $h3-font-reduction; }
h4 { font-size: $h4-font-size - $h4-font-reduction; }
h5 { font-size: $h5-font-size - $h5-font-reduction; }
h6 { font-size: $h6-font-size - $h6-font-reduction; }

您可以使用这些变量并在自定义的 SCSS 文件中进行覆盖,以设置相应屏幕尺寸的字体大小。


7
如果您正在使用构建工具,则可以尝试使用 Rucksack。 否则,您可以使用 CSS 变量(自定义属性)来轻松控制最小和最大字体大小,方法如下(demo):
* {
  /* Calculation */
  --diff: calc(var(--max-size) - var(--min-size));
  --responsive: calc((var(--min-size) * 1px) + var(--diff) * ((100vw - 420px) / (1200 - 420))); /* Ranges from 421px to 1199px */
}

h1 {
  --max-size: 50;
  --min-size: 25;
  font-size: var(--responsive);
}

h2 {
  --max-size: 40;
  --min-size: 20;
  font-size: var(--responsive);
}

你有提到的那个 Rucksack 的参考资料吗? - Peter Mortensen
由于某些原因,@PeterMortensen,这篇CSS技巧文章中提到我们现在可以使用min(),即使MDN和caniuse声称min()被所有浏览器支持,但由于某些原因它仍然无法正常工作? - oldboy

7

6

我刚想到一个想法,您只需要在每个元素中定义一次字体大小即可,但它仍然受媒体查询的影响。

首先,我使用媒体查询将变量“--text-scale-unit”设置为“1vh”或“1vw”,具体取决于视口。

然后,我使用calc()函数和我的字体大小乘数来使用该变量:

/* Define a variable based on the orientation. */
/* The value can be customized to fit your needs. */
@media (orientation: landscape) {
  :root{
    --text-scale-unit: 1vh;
  }
}
@media (orientation: portrait) {
  :root {
    --text-scale-unit: 1vw;
  }
}


/* Use a variable with calc and multiplication. */
.large {
  font-size: calc(var(--text-scale-unit) * 20);
}
.middle {
  font-size: calc(var(--text-scale-unit) * 10);
}
.small {
  font-size: calc(var(--text-scale-unit) * 5);
}
.extra-small {
  font-size: calc(var(--text-scale-unit) * 2);
}
<span class="middle">
  Responsive
</span>
<span class="large">
  text
</span>
<span class="small">
  with one
</span>
<span class="extra-small">
  font-size tag.
</span>

在我的示例中,我只使用了视口的方向,但是原则上可以使用任何媒体查询。

3
为什么不直接使用vminvmax,而要用这个@media的东西呢? - Gark Garcia

4

我使用这些CSS类,可以让我的文字在任何屏幕尺寸下都具有流动性:

.h1-fluid {
    font-size: calc(1rem + 3vw);
    line-height: calc(1.4rem + 4.8vw);
}

.h2-fluid {
    font-size: calc(1rem + 2vw);
    line-height: calc(1.4rem + 2.4vw);
}

.h3-fluid {
    font-size: calc(1rem + 1vw);
    line-height: calc(1.4rem + 1.2vw);
}

.p-fluid {
    font-size: calc(1rem + 0.5vw);
    line-height: calc(1.4rem + 0.6vw);
}

"h3" 的那个似乎运行良好。谢谢! - LeOn - Han Li

4

这个现在支持吗?尽管MDN和caniuse都说它被全面支持,但对我来说它不起作用。 - oldboy
这是一个很好的选择,因为Safari 13.0.5不支持clamp,而且这个版本在2023年1月还不算太旧(发布于2020年,约2年前)。使用min/max可以扩展兼容性到Safari 11.1,该版本发布于2018年,约4年前。通过这个简单的解决方案,我们可以大大提高对Mac用户的响应式字体大小、边距、位置等的兼容性。 - Diego Somar

3
在实际的原始Sass(不是scss),您可以使用以下mixin自动设置段落和所有标题的font-size
我喜欢它,因为它更加紧凑。而且输入速度更快。除此之外,它提供了相同的功能。无论如何,如果您仍然想坚持新语法-scss,则可以在此将我的Sass内容转换为scss: [在此处将Sass转换为scss] 下面给出四个Sass mixin。您将需要根据自己的需求调整其设置。
=font-h1p-style-generator-manual() // You don’t need to use this one. Those are only styles to make it pretty.
=media-query-base-font-size-change-generator-manual() // This mixin sets the base body size that will be used by the h1-h6 tags to recalculate their size in a media query.
=h1p-font-size-generator-auto($h1-fs: 3em, $h1-step-down: 0.3, $body-min-font-size: 1.2em, $p-same-as-hx: 6) // Here you will set the size of h1 and size jumps between h tags
=config-and-run-font-generator() // This one only calls the other ones

在你完成设置后,只需调用一个 mixin - 即:+config-and-run-font-generator()。请参见下面的代码和注释以获取更多信息。

我猜你可以像标题标签一样自动为媒体查询执行此操作,但我们都使用不同的媒体查询,因此这对每个人来说都不合适。我采用移动优先设计方法,所以这就是我会这样做的方式。随意复制并使用此代码。

将这些 mixin 复制并粘贴到您的文件中:

=font-h1p-style-generator-manual()
  body
    font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif // google fonts
    font-size: 100%
    line-height: 1.3em
  %headers
    line-height: 1em
    font-weight: 700
  p
    line-height: 1.3em
    font-weight: 300
  @for $i from 1 through 6
    h#{$i}
      @extend %headers


=media-query-base-font-size-change-generator-manual()
  body
    font-size: 1.2em
  @media screen and (min-width: 680px)
    body
      font-size: 1.4em
  @media screen and (min-width: 1224px)
    body
      font-size: 1.6em
  @media screen and (min-width: 1400px)
    body
      font-size: 1.8em

=h1p-font-size-generator-auto($h1-fs: 3em, $h1-step-down: 0.3, $body-min-font-size: 1.2em, $p-same-as-hx: 6)
  $h1-fs: $h1-fs // Set first header element to this size
  $h1-step-down: $h1-step-down // Decrement each time by 0.3
  $p-same-as-hx: $p-same-as-hx // Set p font-sieze same as h(6)
  $h1-fs: $h1-fs + $h1-step-down // Looping correction
  @for $i from 1 through 6
    h#{$i}
      font-size: $h1-fs - ($h1-step-down * $i)
    @if $i == $p-same-as-hx
      p
        font-size: $h1-fs - ($h1-step-down * $i)

// RUN ONLY THIS MIXIN. IT WILL TRIGGER THE REST
=config-and-run-font-generator()
  +font-h1p-style-generator-manual() // Just a place holder for our font style
  +media-query-base-font-size-change-generator-manual() // Just a placeholder for our media query font size
  +h1p-font-size-generator-auto($h1-fs: 2em, $h1-step-down: 0.2, $p-same-as-hx: 5) // Set all parameters here

将所有的混合器配置为您所需的样式 - 玩得开心! :) 然后在您实际的SASS代码顶部调用它:

+config-and-run-font-generator()

这将生成如下输出。您可以自定义参数以生成不同的结果集。但是,由于我们都使用不同的媒体查询,因此某些混合器必须手动编辑(样式和媒体)。
生成的CSS:
body {
  font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 100%;
  line-height: 1.3em;
  word-wrap: break-word; }

h1, h2, h3, h4, h5, h6 {
  line-height: 1em;
  font-weight: 700; }

p {
  line-height: 1.3em;
  font-weight: 300; }

body {
  font-size: 1.2em; }

@media screen and (min-width: 680px) {
  body {
    font-size: 1.4em; } }
@media screen and (min-width: 1224px) {
  body {
    font-size: 1.6em; } }
@media screen and (min-width: 1400px) {
  body {
    font-size: 1.8em; } }
h1 {
  font-size: 2em; }

h2 {
  font-size: 1.8em; }

h3 {
  font-size: 1.6em; }

h4 {
  font-size: 1.4em; }

h5 {
  font-size: 1.2em; }

p {
  font-size: 1.2em; }

h6 {
  font-size: 1em;

}

3

有很多答案,但我没有看到任何人提到与媒体查询相结合的min或max函数。

CSS中有一个max()函数,因此我们上面的示例变成了一行代码:

font-size: max(30vw, 30px);

或者使用最小值和最大值进行双倍化:

font-size: min(max(16px, 4vw), 22px);

这与以下内容完全相同:

font-size: clamp(16px, 4vw, 22px);

接下来别忘了将这个内容包裹在媒体查询中,并按照您的喜好应用到h1、h2、h3、h4、h5、h6标签上。

    @media (max-width: 600px) {
      h1 {
           font-size: clamp(16px, 4vw, 22px);
         }
    }

3
我们可以使用CSS的calc()函数。
p{
font-size: calc(48px + (56 - 48) * ((100vw - 300px) / (1600 - 300))) !important;
}

数学公式为:calc(minsize +(maxsize-minsize)*(100vm-minviewportwidth)/(maxwidthviewoport-minviewportwidth))

Codepen


3

2
这似乎不是关于字体为什么不调整的直接答案。无论如何,在SO中,仅链接回答并不受鼓励。请考虑添加更多细节/示例代码。 - Harry

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