深入研究如何使用 CSS`clamp()`函数在各种设备尺寸上缩放文本大小

在本文中,我们将深入研究如何使用 CSSclamp()函数在各种设备尺寸上缩放文本大小。

Web 开发和设计的格局在不断发展。近年来,我们看到了强大的 CSS API(如Grid)和容器查询的引入。除此之外,我们还做出了一些重大努力,推动了我们在不断变化的设备环境中控制排版大小的范式转变。

本文将讨论一个称为"流体排版"的术语。这是一项新技术,很大程度上依赖于使用名为clamp().流体排版的基本概念可能很难真正掌握,因此我希望这次深入研究既能解释核心概念,又能让您对在下一个项目中实现流体排版感到兴奋。

理解流体排版的必要性

直到最近,调整字体大小以适应设备宽度还是一项相对手动的任务,涉及使用 CSS 媒体查询。根据您的设备支持,这可能意味着一到两个媒体查询,甚至多达十个。

媒体查询的静态性质迫使我们声明大于或小于特定设备宽度的字体大小。虽然这种字体大小实际上可能在给定的断点处工作得很好,但前端工程师通常被迫添加额外的断点,以适应不同边缘情况下较小的字体大小。这会导致臃肿、低效和沮丧,因为为了满足这些需求而引入了更多的媒体查询。

由于存在不同宽度、像素比和屏幕尺寸的设备,上述场景变得更加复杂。作为前端工程师和设计师,我们需要的是能够帮助我们根据一组动态且经过深思熟虑的值调整字体大小以适应给定设备的功能。

这意味着我们可以摆脱媒体查询的限制性,编写更少的代码,变得更加高效,并对我们的网站在不同设备上的显示方式更有信心。

为什么流体排版很重要

那么,为什么我要付出所有努力来重构我的代码以利用流体排版的好处呢?有以下几个原因:

  • 减少 CSS 臃肿。使用流体排版需要一个定义才能满足多种设备范围的需求。我们可以摆脱多个 CSS 媒体查询声明并减少通过网络发送的 CSS 量。
  • 提高用户体验。随着字体适应屏幕尺寸,我们可以确保在整个设备环境中满足更多边缘情况,为用户带来更好、更一致的用户体验。
  • 支持更多设备 。媒体查询仅支持静态断点,这很有帮助,但不是一门精确的科学。借助calc(),前端工程师可以对版式呈现方式做出更动态的决策。
  • 提高效率。实现流畅的排版意味着我们可以实现改进和简化的 CSS 声明,而无需手动测试每个设备。

现在我们了解了什么是流体排版以及它为何重要,让我们看看如何在我们的项目中实现它。

clamp的力量

clamp()是作为CSS Module 4 规范的一部分引入的、受到良好支持的 CSS 函数。CSS 函数对 CSS 来说并不陌生;我们已经使用其中的一些函数很多年了,例如rgb()。与所有函数一样,clamp()它接受多个输入并产生一个输出。

clamp()需要三个输入:

  • 一个最小值。这是范围的下限。首选值不能低于此最小值。
  • 首选 。只要生成的数字不低于或高于所表示的最小值最大值,就使用该值。
  • 一个最大值。这是范围的上限。首选值不能高于此最大值。

我们先看一个使用clamp()设置元素宽度的例子:

css 复制代码
width: clamp(350px, 50% ,600px)

在上面的示例中,我们将给定元素的宽度设置为不大于600px、不小于350px,理想情况下为50%。看看下面的 CodePen 演示并水平调整浏览器大小。您会注意到,无论容器有多宽或屏幕有多宽,灰色<article>元素永远不会比 宽600px。同样,无论您将浏览器做得多么小,元素的<article>宽度都不会低于350px.这就是使用clamp()的美妙之处。

你能看出这与排版有何关系吗?我们对元素的行为有更多的控制<article>。值得注意的是,此时我们尚未使用单个媒体查询来实现此目的,也没有使用特别动态的值。如果我们确实必须使用媒体查询重写 CodePen 演示的 CSS,我们可能会看到如下内容:

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 有许多测量单位,可以从动态表达式中生成静态值,因此我建议您使用emremvw、 百分比,甚至这些测量单位的组合,并在calc()使用时动态计算首选值clamp()你的代码。

现在我们了解了如何clamp()工作,让我们看看如何将其应用到流体排版中。

使用clamp()实现流体排版

现在让我们深入了解为项目设置流体排版的细节。我们将从一个设计的样式表开始:

css 复制代码
* {
 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,从而提供自然的一致性:

css 复制代码
8px: 0.5rem;
16px: 1rem;
24px: 1.5rem;
32px: 2rem;
40px: 2.5rem;
48px: 3rem;
56px: 3.5rem;
64px: 4rem;

我使用px上面的值来基础比例的想法,因为它更直观,但我们将rem继续使用,因为它是相对的测量单位,并且可以出于可访问性原因进行缩放/缩放。接下来,我们需要根据支持的最小和最大屏幕尺寸做出一些假设。

确定最小和最大屏幕

在我们进一步讨论之前,我想解决选择最小值和最大值的问题。计算首选值的一部分取决于我们实际处理的屏幕尺寸范围,但它也会影响我们的最小值和最大值。

举例来说,我们的网站支持一直追溯到 iPhone 5。该设备的屏幕宽度为320px 。它可能与您在当前市场上查看网站的价格一样低。我们还假设我们希望支持屏幕宽度大于或等于1920px的设备,这是当前市场默认的笔记本电脑屏幕宽度。

最小和最大屏幕尺寸始终需要根据每个项目来确定。我鼓励您检查网站的分析以帮助您确定这一点。

当我们翻译clamp()成简单的语言时,我们基本上是在说:

  • 首选值不能低于X 或低于320px
  • 我将让浏览器根据我给出的动态表达式计算首选值,只要它不低于X 或高于Y
  • 首选值不能高于Y 且等于或高于1920px

考虑一下我的设计师在这里为我提供了一些设计指导,并告诉我320px 是我们支持的最小屏幕宽度,1920px是我们的最大值。我可以将最小值和最大值添加到样式表中:

css 复制代码
* {
 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 }

计算首选值

现在我们需要确定我们的首选值。这需要一些数学才能得出线性表达式。我建议您不要尝试自己计算,而是使用"clamp计算器",它是用于计算值的众多方便工具之一clamp()。 (有很多可用的计算器,有些比钳形计算器复杂得多,但我喜欢这个,因为它很简单。我会在接近尾声时再注明一些。)

让我们从我们的h1规则开始。

我们已经输入了最小值、最大值以及最小和最大视口。正如你所看到的,实际的最小值和最大值与我们上面的 CSS 声明相同。这里令人困惑的部分是上面的四个值如何组合成一个值2.2rem + 1.5vw

让我们来分解一下。您需要知道的第一件事是,rem和单位的组合vw是一种技术,用于确保我们仍然可以出于可访问性原因在浏览器中进行视觉缩放。 (阅读下一节了解详细信息。)

简而言之,首选值是使用公式确定的。此公式确定字体大小在最小值和最大值之间缩放的速率。公式可以表示为:

arduino 复制代码
clamp(
  min-value, 
  fluid-value + relative-value, 
  max-value
);

我们已经详细讨论了最小值和最大值,所以让我们弄清楚如何计算fluid-value + relative-value

计算流体值

流体值可以表示如下:

arduino 复制代码
fluid-value = (
  (max-font-size - min-font-size) / 
  (max-viewport-width - min-viewport-width)
) * 100;

流体值可以解释为字体缩放的速率。随着屏幕宽度的增加,该值将从最小值增加到最大值。

计算相对值

为了弄清楚难题的第二部分,我们需要知道浏览器的根字体大小是多少。这通常是16px默认的,但用户可以更改它。这就是为什么我们总是希望将此值保留在 中rem,因为它会随着用户偏好的增加而扩展。因此我们的相对价值是1rem

一个实际的例子

在大多数情况下,作为开发人员,每次想要向项目添加流体排版时,您不需要计算所有这些。有很多工具和计算器可以帮助您。您需要携带的唯一信息是最小和最大视口,以及最小和最大字体大小。

注意:每个计算器工具使用什么确切公式来计算其结果并不总是立即显而易见。在大多数情况下,您会看到相同的输出,但可能会出现值差异rem。这与公式本身有关,并且可以根据您的需求进行调整,这些需求几乎总是特定于您网站的上下文。

现在我们得到了公式的一部分:

vbscript 复制代码
clamp(
  2.5rem, 
  calc( <fluid-value>  + 1rem), 
  4rem
);

让我们看看是否可以使用上面的流体尺寸公式先手动计算,然后将其插入计算器以可视化我们的结果。我们的公式经过调整以使用上述值,如下所示:

ini 复制代码
fluid-value = ((64 - 40) / (1920 - 320)) * 100;

这会产生一个值 1.5,在本例中它将是1.5vw。因此我们的clamp()函数将类似于下面的代码。请记住,此处的流体值(1.5vw即我们的线性缩放率)可以根据您希望字体缩放的程度进行调整。让我们测试一下:

css 复制代码
font-size: clamp(2.5rem, calc(2.5vw + 1rem), 4rem); 

在上面的CodePen 演示中,我们可以看到我们的规则正在发挥作用。请注意排版如何优雅且逐渐地缩放。

广告

但是,在下面的 CodePen 演示中,我已将该clamp()功能更新为:

vbscript 复制代码
clamp(2.5rem, calc(3.5vw + 1rem), 4rem);

你注意到的第一件事是什么?字体一开始就较大,即使它尚未超过其最大值。它可以扩展,但扩展的速度要快得多。您可以使用这些数字,直到您在不同设备上获得良好的节奏。这里没有硬性或快速的规则。

在任何时候,我都建议使用下面"工具和资源"部分中列出的计算器工具。这不仅是为了提高效率,也是为了看看什么对你有用。

设计师的考虑因素

即使对于开发人员来说,流体排版也是一个很难掌握的概念。然而,设计师可能很难消化它。它实际上意味着设计需要放弃相当多的跨断点控制。但是,在定义了最小和最大字体大小之后,设计师的参与就结束了吗?

版式是一门艺术,也是一门科学,主要是因为它是设计的重要组成部分,但它的大小、节奏和比例都是由数学决定的。有些设计师可能会凭自己的直觉去做这件事,这绝对没问题,但有些人对规划版式的数字方面很感兴趣。

作为一名从事计划实施流体排版项目的设计师,您需要与工程师合作,根据您的网站确定以下内容:

  1. 您希望支持的最小屏幕尺寸。这应该以对您的网站分析和流量的审查为指导。
  2. 您希望支持的最大屏幕尺寸。这应该以对您的网站分析和流量的审查为指导。
  3. 每个印刷元素的最小和最大字体大小。这包括标题、段落、副标题等。这与确定最小和最大屏幕尺寸同样重要。
  4. 规模程度。您希望排版在最小和最大屏幕尺寸之间的设备范围内缩放的程度如何?也就是说,应该在大范围内温和地调整大小,还是在较小范围内更积极地调整大小?

这些注意事项将帮助您与工程团队良好协作。值得注意的是,它clamp()也可以用于行高,所以也不要忘记与您的工程团队讨论这一点,因为它是易读性和可读性的重要考虑因素。

关于可访问性的说明

一个好的clamp()声明应该是这样的:

scss 复制代码
clamp(1rem, 2.5vw, 3rem);

更好的clamp声明如下所示:

vbscript 复制代码
clamp(1rem, calc(2.5vw + 1rem), 3rem);

我建议使用 定义您在代码中使用的任何字体值rem。这是当今标准的最佳实践,实际上不需要进一步解释以下事实:设置16px(或您想要的任何值)作为根字体大小并使用rem作为相对测量单位来定义字体大小是有好处的可访问性和用户体验。

当涉及到我们的首选值时,这一点尤其重要。大多数示例都clamp()依赖一个vw值来表示基于视口宽度的字体大小。但是,当用户放大其设备或浏览器时,由于值表示为视口宽度,因此字体大小不会增加。这是因为屏幕宽度不会增加。

为了解决这个问题,您可以使用calc()rem和组合vw在一起,以便您的首选值成为动态计算的表达式,从而产生一个rem有利于可访问性和缩放的值,但还具有相对于屏幕宽度的额外好处。

利用我们所知道的一切,我们可以对 CSS 样式表进行最后的修饰。我再次使用 Clamp Calculator 来确定流体排版值:

css 复制代码
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 }

应用于我们的 CodePen 演示,以下是排版如何缩小的。 (调整浏览器大小以查看标题如何放大和缩小。看吧,没有媒体查询!

工具和资源

以下是我在项目中实施流体排版的一些常用资源。

首先,我强烈建议开发人员阅读MDNclamp()的工作原理。 MDN 提供了其内部机制的详细解释。

对于设计师来说,我建议阅读James Gilyead 所著的《Designing with Fluid Type Scales》 。

结论

在本文中,我们讨论了流体排版的复杂性、为什么我们可能想要使用它,以及如何使用该clamp()函数在 CSS 中实现它。我们还讨论了它对设计师的影响以及对网络可访问性的影响。

计算字体大小的流体排版值取决于您的网站和您希望支持的设备范围,以及您的网站如何适应每个设备。制作流畅的排版可以使我们的代码保持干净,消除对媒体查询的需要,并且只是向所有用户提供一致且愉快的用户体验的又一步。

相关推荐
Justinc.1 分钟前
CSS3新增边框属性(五)
前端·css·css3
fruge9 分钟前
纯css制作声波扩散动画、js+css3波纹催眠动画特效、【css3动画】圆波扩散效果、雷达光波效果完整代码
javascript·css·css3
CXDNW15 分钟前
【网络面试篇】HTTP(2)(笔记)——http、https、http1.1、http2.0
网络·笔记·http·面试·https·http2.0
neter.asia17 分钟前
vue中如何关闭eslint检测?
前端·javascript·vue.js
~甲壳虫18 分钟前
说说webpack中常见的Plugin?解决了什么问题?
前端·webpack·node.js
光影少年37 分钟前
vue2与vue3的全局通信插件,如何实现自定义的插件
前端·javascript·vue.js
As977_38 分钟前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习
susu108301891140 分钟前
vue3 css的样式如果background没有,如何覆盖有background的样式
前端·css
Ocean☾42 分钟前
前端基础-html-注册界面
前端·算法·html
Rattenking42 分钟前
React 源码学习01 ---- React.Children.map 的实现与应用
javascript·学习·react.js