浅析现代CSS解决方案:数学函数min、max、clamp、calc及使用vw配合clamp实现响应式布局
一、min()、max()、clamp()
min()、max()、clamp() 适合放在一起讲,它们的作用彼此之间有所关联。
- max():从一个逗号分隔的表达式列表中选择最大(正方向)的值作为属性的值
- min():从一个逗号分隔的表达式列表中选择最小的值作为属性的值
- clamp():把一个值限制在一个上限和下限之间,当这个值超过最小值和最大值的范围时,在最小值和最大值之间选择一个值使用
1、简单使用介绍
由于在现实中,有非常多元素的的属性不是一成不变的,而是会根据上下文、环境的变化而变化。
.container {
width: min(100%, 500px);
height: 100px;
background: #000;
}
对于一个响应式的项目,我们肯定不希望它的宽度会一直变大,而是当达到一定的阈值时,宽度从相对单位变成了绝对单位,这种情况就适用于 min()
容器的宽度值会在 width: 100%
与 width: 500px
之间做选择,选取相对小的那个。在屏幕宽度不足 500px 时候,也就表现为 width: 100%
,反之,则表现为 width: 500px
同理,在类似的场景,我们也可以使用 max()
从多个值中,选取相对更大的值。
2、min()、max() 支持多个值的列表
min()、max() 支持多个值的列表,譬如 width: max(1px, 2px, 3px, 50px)
,但其实等价于 width: 50px
。
因此,对于 min()、max() 的具体使用而言,最多应该只包含一个具体的绝对单位。否则,这样的像上述这种代码,虽然语法支持,但是任何情况下,计算值都是确定的,其实没有意义。
3、配合 calc()
min()、max()、clamp() 都可以配合 calc 一起使用。
div {
width: max(50vw, calc(300px + 10%));
}
// 在这种情况下,calc 和相应包裹的括号可以省略,因此,上述代码又可以写成:
div {
width: max(50vw, 300px + 10%);
}
4、基于 max、min 模拟 clamp
现在,有这样一种场景,如果,我们又需要限制最大值,也需要限制最小值,怎么办呢?
我们可以利用 vw 来实现给字体赋动态值,假设在移动端,设备宽度的 CSS 像素为 320px 时,页面的字体宽度最小为 12px,换算成 vw 即是 320 / 100 = 3.2
,也就是 1vw 在 屏幕宽度为 320px 时候,表现为 3.2px,12px 约等于 3.75 vw。
同时,我们需要限制最大字体值为 20px,对应的 CSS 如下:
p {
font-size: max(12px, min(3.75vw, 20px));
// 等价于
font-size: clamp(12px, 3.75vw, 20px);
}
通过 max()
、min()
的配合使用,以及搭配一个相对单位 vw,我们成功地给字体设置了上下限,而在这个上下限之间实现了动态变化。
当然,上面核心的这一段 max(12px, min(3.75vw, 20px))
看上去有点绕,因此,CSS 推出了 clamp()
简化这个语法,下面两个写法是等价的:
5、clamp() 作用是把一个值限制在一个上限和下限之间,当这个值超过最小值和最大值的范围时,在最小值和最大值之间选择一个值使用。
它接收三个参数:最小值、首选值、最大值。有意思的是,clamp(MIN, VAL, MAX)
其实就是表示 max(MIN, min(VAL, MAX))
二、使用 vw 配合 clamp 实现响应式布局
1、响应式布局
在不久的过去,移动端的适配方面,使用更多的 rem 适配方案,可能会借助一些现成的库,类似于 flexible.js、hotcss.js 等库。rem 方案比较大的一个问题在于需要一段 JavaScript 响应视口变化,重设根元素的 font-size
,并且,使用 rem 多少有点 hack 的感觉。
在现在,在移动端适配,我们更为推崇的是 vw 纯 CSS 方案,与 rem 方案类似,它的本质也是页面的等比例缩放。它的一个问题在于,如果仅仅使用 vw,随着屏幕的不断变大或者缩小,内容元素将会一直变大变小下去,这也导致了在大屏幕下,许多元素看着实在太大了!
因此,我们需要一种能够控制最大、最小阈值的方式,像是这样
此时,clamp 就能非常好的派上用场,还是我们上述的例子,这一段代码 font-size: max(12px, min(3.75vw, 20px));
,就能将字体限制在 12px - 20px
的范围内。
因此,对于移动端页面而言,所有涉及长度的单位,我们都可以使用 vw 进行设置。而诸如字体、内外边距、宽度等不应该完全等比例缩放的,采用 clamp() 控制最大最小阈值。
总结而言,对于移动端页面,我们可以以 vw 配合 clamp() 的方式,完成整个移动端布局的适配。它的优势在于:
(1)没有额外 JavaScript 代码的引入,纯 CSS 解决方案
(2)能够很好地控制边界阈值,合理的进行缩放展示
2、反向响应式变化
还有一个技巧,利用 clamp()
配合负值,我们也可以反向操作,得到一种屏幕越大,字体越小的反向响应式效果:
p {
font-size: clamp(20px, -5vw + 96px, 60px);
}
这个技巧挺有意思的,由于 -5vw + 96px
的计算值会随着屏幕的变小而增大,实现了一种反向的字体响应式变化。
合理运用 min()、max()、clamp(),是构建现代响应式布局的重点,我们可以告别传统的需要 JavaScript 辅助的一些方案,基于 CSS 这些数学函数即可完成所有的诉求
三、关于calc()
在进行自适应布局的时候有时候会碰到需要有给固定宽高的地方,比如一个div宽度为屏幕尺寸的一半,但是有10px的padding,那在这种情况下假如我们直接给宽度50%,或者计算完之后的rem单位,再给padding,因为盒模型的关系导致其宽度为50%+20px。但是又因为50%是一个不固定的值,导致很难计算出一个具体的值,在这种情况下我们就可以使用css3中的一个计算方法:calc(),可以设置
div{
width: calc(50% - 20px);
}
这样设置之后得到的结果就是计算之后的结果,任何需要给具体的值的地方都可以使用calc来进行计算,不过需要注意目前此方法只能进行 + - * / 的四则运算,并且在计算符号前后都需要有一个空格。当然上面的50%也可以换成计算之后的rem单位。
注意点:calc 内部的表达式,在使用运算符号时,两遍必须加上空格(虽然乘除可以无视,但还是建议带上),不然会解析错误。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律