这篇文章发布于 2024年09月26日,星期四,00:04,归类于 CSS相关。 阅读 2980 次, 今日 5 次 一条评论
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=11363 鑫空间-鑫生活
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。
一、CSS又更强了一点
好消息,时隔两年,原本仅Safari浏览器支持的mod()
/rem()
/round()
现在Chrome浏览器也支持啦。
mod()函数
CSS mod()函数返回第一个参数除以第二个参数的取模结果,类似于JavaScript余数运算符(%)。
使用示意:
/* 数值,无单位 */ line-height: mod(7, 2); /* 1 */ line-height: mod(14, 5); /* 4 */ line-height: mod(3.5, 2); /* 1.5 */ /* 百分比或者带单位的尺寸 */ margin: mod(15%, 2%); /* 1% */ margin: mod(18px, 4px); /* 2px */ margin: mod(19rem, 5rem); /* 4rem */ margin: mod(29vmin, 6vmin); /* 5vmin */ margin: mod(1000px, 29rem); /* 72px - 如果根字号是16px */ /* 正负值 */ rotate: mod(100deg, 30deg); /* 10deg */ rotate: mod(135deg, -90deg); /* -45deg */ rotate: mod(-70deg, 20deg); /* 10deg */ rotate: mod(-70deg, -15deg); /* -10deg */ /* 计算*/ scale: mod(10 * 2, 1.7); /* 1.3 */ rotate: mod(10turn, 18turn / 3); /* 4turn */ transition-duration: mod(20s / 2, 3000ms * 2); /* 4s */
这个CSS函数日常开发使用的机会并不大。
rem()函数
CSS rem()
函数返回第一个参数除以第二个参数后的余数,类似于JavaScript余数运算符(%)。
使用示意:
/* U数值,无单位 */ line-height: rem(21, 2); /* 1 */ line-height: rem(14, 5); /* 4 */ line-height: rem(5.5, 2); /* 1.5 */ /* 百分比或者带单位的尺寸 */ margin: rem(14%, 3%); /* 2% */ margin: rem(18px, 5px); /* 3px */ margin: rem(10rem, 6rem); /* 4rem */ margin: rem(26vmin, 7vmin); /* 5vmin */ margin: rem(1000px, 29rem); /* 72px - if root font-size is 16px */ /* 正负值 */ rotate: rem(200deg, 30deg); /* 20deg */ rotate: rem(140deg, -90deg); /* 50deg */ rotate: rem(-90deg, 20deg); /* -10deg */ rotate: rem(-55deg, -15deg); /* -10deg */ /* 计算*/ scale: rem(10 * 2, 1.7); /* 1.3 */ rotate: rem(10turn, 18turn / 3); /* 4turn */ transition-duration: rem(20s / 2, 3000ms * 2); /* 4s */
rem和mod的区别
mod 函数生成一个为零或与除数具有相同符号的结果。
rem 函数生成一个为零或与被除数具有相同符号的结果。
这两个数学函数日常开发鲜有机会出场。
但是有个数学函数是例外,那就是round()
函数,这个函数的语法更加复杂,但同时也更加实用。
二、实用必学round()函数
很多人以为round()
函数就是简单的四舍五入,其实这个函数设计得非常巧妙,通过不同的参数设置,可以实现多种取值方法,例如(以JS API示意):
- Math.ceil()
- Math.floor()
- Math.round()
- Math.trunc()
都怎么实现的呢?看案例。
模拟Math.ceil()取值
Math.ceil()
是向上取整,使用CSS语法表示则是:
canvas { border: round(up, 1.01px, 1px) solid; }
结果渲染的边框宽度则是2px,实时渲染效果如下所示:
其中,up表示向上取整,第三个参数表示最终计算值需要可以被此数值整除,例如round(up, 2.01px, 2px)的计算值就是4px
。
canvas { border: round(up, 2.01px, 2px) solid; }
实时渲染效果如下所示:
模拟Math.floor()取值
Math.floor()
是向下取整,因此,下面CSS代码的边框大小就是1px。
canvas { border: round(down, 1.99px, 1px) solid; }
模拟Math.round()取值
语法:
round( nearest, <valueToRound> , <roundingInterval> )
或者直接:
round( <valueToRound> , <roundingInterval> )
就是我们常说的四舍五入。
模拟Math.trunc()取值
语法:
round( to-zero, <valueToRound> , <roundingInterval> )
表示将valueToRound
舍入为roundingInterval
接近/接近零的最接近整数倍。
例如:
canvas { border: round(to-zero, 5.5px, 2px) solid; }
边框宽度是4px,因为5.5px往0走,最靠近2px倍数的值就是4px。
效果示意:
而round(to-zero, 5.5px, 3px)的计算值就是3px,比5.5px小的又是3px备注的最大值就是3px。
效果示意:
二、round()函数的实际应用
举两个实用案例吧。
1. 让响应式font-size永远是整数
移动端开发会使用rem单位和屏幕尺寸关联,例如:
html { font-size: clamp(16px, calc(100% + 4 * (100vw - 375px) / 105), 20px); }
此时,1rem对应的尺寸就有可能是小数。
小数就会有什么问题,例如一些SVG图标尺寸使用rem表示,由于出现了小数,图标边缘就很可能出现缝隙。
又或者是圆角边缘,或者box-shadow边缘出现很微小的缝隙风。
此时,就可以使用round()函数让尺寸取整,以规避这些问题。
使用示意:
<ul> <li>HTML并不简单</li> <li>CSS新世界</li> <li>好书推荐</li> </ul>
ul { font-size: round(1rem, 1px); }
此时,<ul>
列表的字号大小一定是整数。
如果没有round四舍五入,则字号大小则就可能是小数。
参见下图GIF动态示意(不应用round是小数18.2476px,应用round()函数则是整数18px):
2. 模拟animation的steps()步阶函数效果
round()函数的最后一个参数表示取舍的最小数值单元,试想下,如果是一个0-100的动画,如果我们设置取整的单元是20,那岂不是应用round()函数后,最终的计算值只可能是0、20、40、60、80和100,不就和CSS动画中的steps()步阶函数很像了么?
例如有个静态的loading图标:
<img src="loading.png" class="spin" />
实际渲染效果如下,是个静态的:
则下面这段CSS代码就可以让此图标loading旋转效果:
.spin { transform: rotate(round(calc(var(--seed) * 3.6deg), 45deg)); animation: seed 1s linear infinite; } @property --seed { syntax: "<integer>"; inherits: false; initial-value: 0; } @keyframes seed { from { --seed: 0; } to { --seed: 100; } }
眼见为实,您可以狠狠地点击这里:使用CSS round()函数模拟steps动画demo
效果截图如下所示:
是不是实现得非常巧妙!
虽然steps()
函数可以实现一样的效果,但是steps()
的学习和理解成本要比round()
函数高多了,唯一的优势就是兼容性了。
不过这个例子也可以看出round()
函数的应用潜力。
四、结语巴拉巴拉
目前,规范里面提及的数学函数大部分都已经支持了吧。
首先第一批支持的是min()/max()/clamp()这些数学函数,详见“了解CSS min()/max()/clamp()数学函数”一文。
再然后就是,sin()
/cos()
这些函数支持,去年开始支持的,之前也介绍过,参见“CSS sin()/cos()等数学三角函数简介与应用”一文。
其他数学函数,如求平方根的sqrt()函数,幂指数的pow()函数,返回给定数字的幂的数学常数e的特殊指数函数exp(),返回数字对数的log()函数,则是去年底支持的,算是第3波吧。
然后就是本文这几个数值取舍函数,属于第4批次。
最后一波应该就是绝对值abs()函数,正负零判断的sign()的函数。
总之很奇怪,不知道为何Chrome浏览器不一次性支持,而是分5波进行。
好吧,就说这么多吧。
感谢阅读,欢迎!
本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=11363
(本篇完)
- CSS sin()/cos()等数学三角函数简介与应用 (0.479)
- 基于vw等viewport视区单位配合rem响应式排版和布局 (0.210)
- 纯CSS实现未读消息超过100自动显示为99+ (0.210)
- CSS3 animation属性中的steps功能符深入介绍 (0.131)
- 小tips: 纯CSS实现打字动画效果 (0.131)
- 了解CSS min()/max()/clamp()数学函数 (0.120)
- jQuery之replace字符串替换实现不同尺寸图片切换 (0.030)
- 翻译 - CSS继承详解 (0.030)
- 拜拜了,浮动布局-基于display:inline-block的列表布局 (0.030)
- 去除inline-block元素间间距的N种方法 (0.030)
- 这回试试使用CSS实现抛物线运动效果 (RANDOM - 0.011)
感觉最适合使用的是兼容响应式计算中,由于小数运算导致宽 / 高溢出,更新父容器宽 / 高,再重复此过程,最后导致的宽度无限变长问题