当前位置: 首页 > 科技观察

现代CSS解决方案:数学函数的Min,Max,Clamp

时间:2023-03-22 11:21:28 科技观察

在CSS中,其实有各种各样的函数。具体分为:变换函数[1]数学函数[2]过滤函数[3]颜色函数[4]图像函数[5]计数器函数[6]字体函数[7]形状函数[8]参考函数[9]CSSgridfunctions[10]本文将专门介绍四种已被浏览器大规模支持的CSS数学函数(Mathfunctions):calc()min()max()clamp()为什么说支持浏览器?大规模支持?因为除了这四个已经被大规模支持的数学函数外,其实规范CSSValuesandUnitsModuleLevel4[11]已经定义了sin(),cos(),tan()等函数等。指数函数与pow()、sqrt()等数学函数相关,但目前处于实验室阶段,还没有浏览器支持,还需要给它们一些时间。我们在上一篇文章中详细介绍了calc(),在本文中我们将讨论其他三个。关于calc(),可以戳这里:ModernCSSsolution:calcofCSSmathfunction。min(),max(),clamp()min(),max(),clamp()适合一起聊。他们的角色是相互关联的。max():从逗号分隔的表达式列表中选择最大(正方向)的值作为属性的值。min():从逗号分隔的表达式列表中选择最小值作为属性的值。clamp():在上限和下限之间限制一个值。当此值超出最小值和最大值的范围时,选择一个介于最小值和最大值之间的值来使用。因为在现实中,很多元素的属性并不是一成不变的,而是会随着语境和环境的变化而变化。比如这样的布局:

.container{height:100px;background:#000;}效果如下,.container块会随着屏幕的增加而增加,一直占据整个屏幕:对于一个响应式item,我们肯定不希望它的宽度一直增长,但是当达到某个阈值时,宽度从相对单位变为绝对单位,适用于min(),只需修改代码:.container{width:min(100%,500px);高度:100px;background:#000;}容器的宽度值将在width:100%和width:500px之间选择,选择相对较小的。当屏幕宽度小于500px时,会显示为width:100%,否则显示为width:500px:同样,在类似的场景下,我们也可以使用max()从中选择一个比较大的值多值值。min(),max()支持多值列表min(),max()支持多值列表,例如width:max(1px,2px,3px,50px)。当然,对于上面的表达式:width:max(1px,2px,3px,50px)实际上等于width:50px。因此,对于min()和max()的具体使用,至多应该包括一个特定的绝对单位。不然像上面这样的代码,虽然语法支持,但是不管怎样,计算出来的值是确定的,其实是没有意义的。calcmin(),max(),clamp()可以和calc一起使用。例如:div{width:max(50vw,calc(300px+10%));}这种情况下calc和对应的括号可以省略,所以上面的代码可以写成:div{width:max(50vw,300px+10%);}根据max和min模拟clamp现在,有这样一个场景,如果我们需要限制最大值和最小值,我们应该怎么做呢?像这个场景,**font的最小尺寸是12px,随着屏幕变大逐渐变大,但是为了避免出现老机现象(随着屏幕变大,无限变大),我们也需要限制最大值为20px。我们可以使用vw给字体动态赋值。假设在移动端,当设备宽度的CSS像素为320px时,页面的字体宽度至少为12px。换算成vw,就是320/100=3.2,即1vw在屏幕上宽度为320px时,表现是3.2px,12px约等于3.75vw。同时我们需要限制最大字体值为20px,对应的CSS如下:p{font-size:max(12px,min(3.75vw,20px));}看效果:通过max()和min()的配合使用,加上一个相对单位vw,我们就成功的给字体设置了上下限,实现了上下限之间的动态变化。当然,上面的核心段落max(12px,min(3.75vw,20px))看起来有点绕,所以CSS引入了clamp()来简化这个语法,下面两种写法是等价的:p{font-size:max(12px,min(3.75vw,20px));//相当于font-size:clamp(12px,3.75vw,20px);}clamp()clamp()函数的作用是将一个值限制在一个上限和下限之间,当这个值超过最小值和最大值的范围,选择一个介于最小值和最大值之间的值来使用。它接收三个参数:最小值、首选值、最大值。有趣的是,clamp(MIN,VAL,MAX)实际上意味着max(MIN,min(VAL,MAX))。使用vwwithclamp实现响应式布局我们继续上面的话题。在不久的将来,在移动适配方面,可能更多的是使用rem适配方案,可能会使用一些现成的库,类似flexible.js、hotcss.js等库。rem解决方案的一个更大问题是它需要一段JavaScript来响应视口更改并重置根元素的字体大小,并且使用rem感觉有点hacky。现在,对于移动端的适配,我们更提倡vw纯CSS的方案,它和rem的方案类似,其本质也是页面的比例缩放。它的一个问题是,如果你只使用vw,随着屏幕不断变大或变小,内容元素会不断变大变小,这也导致很多元素在大屏幕上看起来太大了!因此,我们需要一种方法来控制最大最小阈值,像这样:这个时候clamp就可以派上大用场了,还是我们上面的例子,这段代码font-size:max(12px,min(3.75vw,20px));,可以将字体限制在12px-20px的范围内。因此,对于移动端页面,我们可以使用vw来设置所有与长度相关的单位。对于字体、内外边距、宽度等不应该精确缩放的东西,使用clamp()来控制最大和最小阈值。在文章ModernFluidTypographyUsingCSSClamp[12]中,对使用clamp()进行流体响应布局进行了更深入的讨论。感兴趣的可以深入阅读。综上所述,对于移动端页面,我们可以使用vw配合clamp()来完成整个移动端布局的适配。它的优点是没有引入额外的JavaScript代码,纯CSS解决方案。可以很好地控制边界阈值,合理地进行缩放显示。还有一个反向响应变化的技巧。使用带负值的clamp(),我们也可以反向操作,得到大屏小字体的反向响应效果:p{font-size:clamp(20px,-5vw+96px,60px);}看看效果:这个trick还是蛮有意思的,因为-5vw+96px的计算值会随着屏幕变小而增加,实现了反向字体响应的多样性。综上所述,合理使用min()、max()和clamp()是构建现代响应式布局的重点。我们可以告别一些需要JavaScript辅助的传统解决方案,所有的需求都可以基于CSS的这些数学功能来完成。.一些非常好的文章可供进一步阅读:min()、max()和clamp()CSS函数指南[13]。使用CSSClamp的现代流体排版[14]。最后,本文到此结束,希望这篇文章对你有所帮助:)参考文献【1】变换函数:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Functions#transform_functions.[2]数学函数:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Functions#math_functions。[3]过滤函数:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Functions#filter_functions。[4]颜色函数:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Functions#color_functions。[5]图像函数:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Functions#image_functions。[6]计数器函数:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Functions#counter_functions。[7]字体函数:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Functions#font_functions。[8]形状函数:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Functions#shape_functions。[9]参考函数:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Functions#reference_functions。[10]CSS网格函数:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Functions#css_grid_functions。[11]CSS值和单位模块级别4:https://drafts.c??sswg.org/css-values/#math。[12]ModernFluidTypographyUsingCSSClamp:https://www.smashingmagazine.com/2022/01/modern-fluid-typography-css-clamp/。[13]min()、max()和clamp()CSS函数指南:https://blog.logrocket.com/min-max-clamp-css-functions/。[14]使用CSSClamp的现代流体排版:https://www.smashingmagazine.com/2022/01/modern-fluid-typography-css-clamp/。