在本文中,我们将深入研究如何使用 CSSclamp()
函数在各种设备尺寸范围内缩放文本大小。
Web 开发和设计的格局在不断发展。近年来,我们看到了强大的 CSS API(如Grid和容器查询)的引入。除此之外,我们还做出了一些重大努力,推动了我们在不断变化的设备环境中控制排版大小的范式转变。
本文将讨论一个术语"流体排版"。这是一项新技术,主要依赖于名为 的新 CSS 函数clamp()
。流体排版的基本概念可能很难真正掌握,所以我希望这篇深入的文章既能解释核心概念,又能让您对在下一个项目中实施流体排版感到兴奋。
理解流体排版的必要性 {#understandingtheneedforfluidtypography}
直到最近,调整字体大小以适应设备宽度还是一项相对手动的任务,需要使用 CSS 媒体查询。根据设备支持情况,这可能意味着需要一两个媒体查询,甚至多达十个。
媒体查询的静态特性迫使我们声明大于或小于某个设备宽度的字体大小。虽然这个字体大小在给定的断点处可能实际上工作正常,但前端工程师通常被迫添加额外的断点,以适应各种边缘情况下的较小字体大小。这会导致臃肿、低效和沮丧,因为为了满足这些需求,需要引入更多媒体查询。
由于设备宽度、像素比和屏幕尺寸各不相同,上述情况变得更加复杂。作为前端工程师和设计师,我们需要的是能够根据一组动态且经过深思熟虑的值来帮助我们调整字体大小以适应特定设备的功能。
这意味着我们可以摆脱媒体查询的限制性,编写更少的代码,变得更加高效,并且对我们的网站在各个设备上的显示效果更有信心。
流体排版为何如此重要 {#whyfluidtypographymatters}
那么,为什么我要费尽心思重构代码才能利用流体排版的优势呢?原因如下:
-
减少 CSS 臃肿。使用流畅排版需要一个定义,以便满足多种设备范围的需求。我们可以摆脱多个 CSS 媒体查询声明,并减少通过网络发送的 CSS 数量。
-
改善用户体验。随着字体适应屏幕尺寸,我们可以确保在设备环境中满足更多边缘情况,为用户带来更好、更一致的用户体验。
-
支持更多设备。媒体查询仅支持静态断点,这很有用,但不是一门精确的科学。借助
calc()
,前端工程师可以对排版渲染方式做出更动态的决定。 -
提高效率。实现流体排版意味着我们可以实现改进和简化的 CSS 声明,而无需手动测试每台设备。
现在我们了解了流体排版是什么以及它为什么重要,让我们看看如何在我们的项目中实现它。
clamp() 的功能 {#thepowerofclamp}
clamp()
是作为CSS Module 4 规范的一部分引入的、受到良好支持的 CSS 函数。CSS 函数对 CSS 来说并不陌生;我们已经使用其中的一些函数很多年了,例如rgb()
。与所有函数一样,clamp()
它接受多个输入并产生一个输出。
clamp()
需要三个输入:
-
最小值。这是范围的下限。首选值不能低于此最小值。
-
首选值。只要生成的数字不低于或高于所表达的最小值和最大值,就会使用此值。
-
最大值。这是范围的上限。首选值不能高于此最大值。
我们首先来看一个用来clamp()
设置元素宽度的例子:
width: clamp(350px, 50% ,600px)
在上面的例子中,我们将给定元素的宽度设置为不大于600px
、不小于350px
,理想情况下为50%
。您会注意到,无论容器有多宽或屏幕有多宽,灰色<article>
元素的宽度都不会超过600px
。同样,无论浏览器有多小,元素<article>
的宽度永远不会低于350px
。这就是使用 的美妙之处clamp()
。
你能看出这与排版有什么关系吗?我们对元素的行为有了更多的控制<article>
。值得注意的是,目前我们还没有使用任何媒体查询来实现这一点,也没有使用特别动态的值。如果我们确实必须用媒体查询重写 CodePen 演示的 CSS,我们可能会看到这样的内容:
article {
width: 350px;
}
@media only screen and (min-width: 480px) {
width: 50%;
}
@media only screen and (min-width: 960px) {
width: 600px;
}
大约十行代码,而 CSS 函数只有一个。我认为这是一次重大优化。再次强调,重要的是要理解clamp()
这里的工作原理:它首先查看首选值,然后计算该表达式是否实际上介于最小值和最大值之间。换句话说:
-
如果50%计算出的值小于350px,则使用350px 。
-
如果50%计算出的值大于600px,则将使用600px 。
-
如果50%计算出的值为最小值和最大值之间的值,则使用首选值。
说实话,使用静态值作为首选值是没有用的。此值需要是一个动态表达式才能起作用并确定最小值和最大值之间的线性关系。
CSS 有许多测量单位,它们会从动态表达式中产生静态值,因此我建议您在代码中使用em
、、、rem
百分比vw
,甚至这些测量单位的组合来calc()
动态计算首选值。clamp()
现在我们了解了它clamp()
的工作原理,让我们看看如何将其应用于流体排版。
使用 clamp() 实现流体排版 {#implementingfluidtypographywithclamp}
现在让我们深入了解如何为项目设置流畅的排版。我们将从设计样式表开始:
* {
box-sizing: border-box;
}
body {
font-family: system-ui;
font-size: 16px; /* 16px = 1rem */
}
h1 { font-size: clamp() }
h2 { font-size: clamp() }
h3 { font-size: clamp() }
h4 { font-size: clamp() }
h5 { font-size: clamp() }
h6 { font-size: clamp() }
我们的目标是创建通用的排版样式,以线性方式(以一致的方式缩小)优雅地响应断点。为此,我们需要运用一些数学知识,并需要考虑一些复杂因素。我将尽我所能尽可能清楚地解释一切。
正如我之前提到的,我们知道clamp()
需要三个输入:最小、首选和最大。首先确定最小和最大字体大小比较容易。这为我们提供了一些防护栏,并为要计算的首选值设置了一个范围。
假设我正在与设计师合作创建8px
字体比例。这意味着我的字体可以以 为增量增加8px
,从而提供自然的一致性:
8px: 0.5rem;
16px: 1rem;
24px: 1.5rem;
32px: 2rem;
40px: 2.5rem;
48px: 3rem;
56px: 3.5rem;
64px: 4rem;
我使用px
上面的值来阐述比例的概念,因为它更直观,但我们将rem
继续使用它,因为它是一个相对测量单位,并且可以出于可访问性原因进行缩放。接下来,我们需要根据支持的最小和最大屏幕尺寸做出一些假设。
确定最小和最大屏幕 {#determiningminandmaxscreens}
在继续之前,我想先解决选择最小值和最大值的问题。计算首选值的部分内容取决于我们实际处理的屏幕尺寸范围,但它也会影响我们的最小值和最大值。
举例来说,假设我们的网站支持 iPhone 5 之前的版本。该设备的屏幕宽度为320px。这大概是当前市场上浏览网站所能获得的最低宽度。我们还假设我们希望支持屏幕宽度大于或等于1920px的设备,这是当前市场上默认的笔记本电脑屏幕宽度。
最小和最大屏幕尺寸始终需要根据每个项目来确定。我鼓励您查看网站的分析,以帮助您确定这一点。
当我们翻译clamp()
成简单的语言时,我们基本上是在说:
-
首选值不能低于320px或以下的X。
-
我将让浏览器根据我给出的动态表达式来计算首选值,只要它不低于X或高于Y即可。
-
首选值不能高于1920px或以上的Y值。
考虑到我的设计师在这里为我提供了一些设计指导,并告诉我320px是我们要支持的最小屏幕宽度,而1920px是最大屏幕宽度。我可以将最小值和最大值添加到样式表中:
* {
box-sizing: border-box;
}
body {
font-family: system-ui;
font-size: 16px; /* 16px = 1rem */
}
h1 { font-size: clamp(2.5rem, <preferred-value>, 4rem) }
h2 { font-size: clamp(2rem, </preferred-value><preferred-value>, 3.5rem) }
h3 { font-size: clamp(2rem, </preferred-value><preferred-value>, 3rem) }
h4 { font-size: clamp(1.5rem, </preferred-value><preferred-value>, 2.5rem) }
h5 { font-size: clamp(15rem, </preferred-value><preferred-value>, 2rem) }
h6 { font-size: 1rem }
计算优先值 {#calculatingpreferredvalue}
现在我们需要确定我们想要的值。这需要一些数学知识才能得出一个线性表达式。与其自己尝试计算,我建议您使用Clamp 计算器,它是计算数值的众多便捷工具之一clamp()
。(有很多计算器可用,有些比 Clamp 计算器复杂得多,但我喜欢这个计算器,因为它很简单。我将在最后再介绍几个。)
让我们从我们的h1
规则开始。
我们输入了最小值、最大值以及最小和最大视口。如您所见,实际的最小值和最大值与上面的 CSS 声明相同。这里令人困惑的部分是上面的四个值如何组合成一个值2.2rem + 1.5vw
。
rem
让我们来分析一下。首先你需要知道的是,和单位的组合vw
是一种技术,用于确保我们仍然可以出于可访问性原因在浏览器中进行视觉放大。(请阅读下一节了解详情。)
简而言之,首选值是使用公式确定的。此公式确定字体大小在最小值和最大值之间的缩放率。该公式可以表示如下:
clamp(
min-value,
fluid-value + relative-value,
max-value
);
我们已经详细讨论了最小值和最大值,现在让我们来弄清楚如何计算fluid-value + relative-value
。
计算流体价值 {#calculatingfluidvalue}
流体值可以表示如下:
fluid-value = (
(max-font-size - min-font-size) /
(max-viewport-width - min-viewport-width)
) * 100;
流体值可以理解为字体缩放的速率,随着屏幕宽度的增加,该值会从最小值增加到最大值。
计算相对值 {#calculatingrelativevalue}
为了解决难题的第二部分,我们需要知道浏览器的根字体大小。这通常是16px
默认的,但用户可以更改它。这就是为什么我们总是希望将此值保持在 中rem
,因为它会随着用户增加其偏好而缩放。因此我们的相对值将是1rem
。
一个实际的例子 {#apracticalexample}
在大多数情况下,作为开发人员,您不需要在每次想要向项目添加流畅排版时计算所有这些。有很多工具和计算器可以为您提供帮助。您需要携带的唯一信息是您的最小和最大视口,以及您的最小和最大字体大小。
注意:每个计算器工具计算结果的具体公式并不总是一目了然。大多数情况下,您会看到相同的输出,但值可能会有差异rem
。这与公式本身有关,可以根据您的需求进行调整,而这些需求几乎总是特定于您网站的背景。
我们现在有了部分公式:
clamp(
2.5rem,
calc( <fluid-value> + 1rem),
4rem
);
让我们看看是否可以先使用上面的流体尺寸公式手动计算,然后将其插入计算器以可视化结果。我们的公式经过调整以使用上述值,如下所示:
fluid-value = ((64 - 40) / (1920 - 320)) * 100;
这会产生一个值 1.5,在本例中它将是1.5vw
。因此我们的clamp()
函数将类似于下面的代码。请记住,这里的流体值(1.5vw
即我们的线性缩放率)可以根据您希望字体缩放的程度进行调整。让我们测试一下:
font-size: clamp(2.5rem, calc(2.5vw + 1rem), 4rem);
看下DEMO:
<style>
body {
align-items: center;
display: flex;
font-family: system-ui;
font-size: 16px;
height: 100vh;
width: 100vw;
}
section {
margin-inline: auto;
}
h1 {
font-size: clamp(2.5rem, calc(2.5vw + 1rem), 4rem);
font-weight: bold;
text-align: center;
}
</style>
<section>
<h1>Hello, I'm a Fluid Heading<h1>
</section>
我们可以在DEMO里看到我们的规则在起作用。请注意字体如何优雅而逐渐地放大和缩小。
设计师需要考虑的问题 {#considerationsfordesigners}
流畅排版是一个难以理解的概念,即使是开发人员也难以理解。然而,设计师可能很难理解它。这实际上意味着设计需要放弃对断点的相当多的控制。但是,在定义最小和最大字体大小后,设计师的参与就结束了吗?
排版是一门艺术和科学,主要是因为它是设计中非常重要的一部分,但它的大小、节奏和比例都是由数学决定的。有些设计师可能会凭直觉行事,这完全没问题,但也有一些人对排版规划的数字方面很感兴趣。
作为计划实施流体排版项目的设计师,您需要与工程师一起根据您的网站确定以下内容:
-
您希望支持的最小屏幕尺寸。这应该通过检查您的网站分析和流量来确定。
-
您希望支持的最大屏幕尺寸。这应该通过检查您的网站分析和流量来确定。
-
每个印刷元素的最小和最大字体大小。包括标题、段落、副标题等。这与确定最小和最大屏幕尺寸同样重要。
-
缩放程度。在最小和最大屏幕尺寸之间,您希望字体在设备范围内缩放到多大程度?也就是说,应该在较大的范围内缓慢调整大小,还是在较小的范围内更积极地调整大小?
这些考虑因素将帮助您与工程团队进行良好的协作。值得注意的是,这clamp()
也可用于行高,因此不要忘记与您的工程团队讨论这一点,因为它是易读性和可读性的重要考虑因素。
关于可访问性的说明 {#anoteonaccessibility}
好的clamp()
声明看起来应该是这样的:
clamp(1rem, 2.5vw, 3rem);
更好的clamp
声明如下:
clamp(1rem, calc(2.5vw + 1rem), 3rem);
我建议使用 来定义代码中利用的任何字体值rem
。这是当今的标准最佳实践,实际上不需要进一步解释,只需将16px
(或您想要的任何值) 设置为根字体大小并用作rem
定义字体大小的相对测量单位即可,这对可访问性和用户体验都有好处。
对于我们的首选值,这一点尤为重要。大多数示例都clamp()
依赖于一个vw
值来根据视口宽度表示字体的大小。但是,当用户放大其设备或浏览器时,由于值表示为视口宽度,因此字体的大小不会增加。这是因为屏幕宽度不会增加。
为了解决这个问题,您可以使用和calc()
组合起来,这样您的首选值就变成一个动态计算的表达式,其结果不仅有利于可访问性和缩放,而且还具有与屏幕宽度相关的额外好处。rem``vw``rem
利用我们所知道的一切,我们可以对 CSS 样式表进行最后的润色。我再次使用了 Clamp Calculator 来确定流体排版值:
h1 { font-size: clamp(2.5rem, calc(2.2rem + 1.5vw), 4rem) }
h2 { font-size: clamp(2rem, calc(1.7rem + 1.5vw), 3.5rem) }
h3 { font-size: clamp(2rem, calc(1.8rem + 1vw), 3rem) }
h4 { font-size: clamp(1.5rem, calc(1.3rem + 1vw), 2.5rem) }
h5 { font-size: clamp(1rem, calc(0.8rem + 1vw), 2rem) }
h6 { font-size: 1rem }
以下是字体缩小的方式。(调整浏览器大小以查看标题如何放大和缩小。看!没有媒体查询!)
<style>
* {
box-sizing: border-box;
}
body {
align-items: center;
display: flex;
font-family: system-ui;
font-size: 16px; /* 16px = 1rem */
height: 100vh;
width: 100vw;
}
section {
margin-inline: auto;
}
h1 { font-size: clamp(2.5rem, calc(2.2rem + 1.5vw), 4rem) }
h2 { font-size: clamp(2rem, calc(1.7rem + 1.5vw), 3.5rem) }
h3 { font-size: clamp(2rem, calc(1.8rem + 1vw), 3rem) }
h4 { font-size: clamp(1.5rem, calc(1.3rem + 1vw), 2.5rem) }
h5 { font-size: clamp(1rem, calc(0.8rem + 1vw), 2rem) }
h6 { font-size: 1rem }
</style>
<section>
<h1>Hello, I'm a Fluid h1 Heading</h1>
<h2>Hello, I'm a Fluid h2 Heading</h2>
<h3>Hello, I'm a Fluid h3 Heading</h3>
<h4>Hello, I'm a Fluid h4 Heading</h4>
<h5>Hello, I'm a Fluid h5 Heading</h5>
<h6>Hello, I'm a Fluid h6 Heading</h6>
</section>
工具和资源 {#toolsandresources}
以下是我在项目中实现流体排版的一些常用资源。
首先,我强烈建议开发者们阅读MDNclamp()
上的工作原理。MDN 对其内部机制提供了详细的解释。
对于设计师,我建议阅读James Gilyead 的《使用流体类型尺度进行设计》。
除此之外,这里还有一些其他有用的资源:
-
Utopia Fluid Typography Calculator。此工具可帮助您计算
clamp()
跨断点的函数值,并提供可在 CSS 文件中实现的代码。 -
流体类型比例。这些实用的实用程序和预设工具包有助于实现流体排版,使设计工作更易于管理。
-
现代流体排版编辑器。Adrian Beck 开发了这个出色的工具,用于可视化最小值、首选值和最大值之间的线性关系
clamp()
。如果您想优化首选值,强烈推荐此工具。
结论 {#conclusion}
在本文中,我们讨论了流体排版的复杂性、我们为什么要使用它以及如何使用函数在 CSS 中实现它clamp()
。我们还讨论了它对设计师的影响以及对网络可访问性的影响。
计算字体大小的流畅排版值取决于您的网站和您希望支持的设备范围,以及您的网站如何适应每种设备。制作流畅排版可以保持我们的代码整洁,消除媒体查询的需要,并且只是向所有用户提供一致且愉快的用户体验迈出了一步。