现代 CSS 解决方案:数学函数 Round
在 CSS 中,存在许多数学函数,这些函数能够通过简单的计算操作来生成某些属性值,例如在现代 CSS 解决方案:CSS 数学函数一文中,我们详细介绍了
- calc():用于计算任意长度、百分比或数值型数据,并将其作为 CSS 属性值。
- min() 和 max():用于比较一组数值中的最大值或最小值,也可以与任意长度、百分比或数值型数据一同使用。
- clamp():用于将属性值限制在一个范围内,支持三个参数:最小值、推荐值和最大值。
在 现代 CSS 解决方案:CSS 原生支持的三角函数 一文中,给大家介绍了从 Chrome 111 开始也逐渐开始原生支持的三角函数:
- sin()
- cos()
- tan()
而本文,我们将介绍另外一个非常有意思的数学函数 - round()。
何为 round()?
简单来说,round() CSS 函数的作用就是根据选定的舍入策略返回舍入数。
举个例子,在 JavaScript 中,我们可以使用 Math.round() 返回一个数字四舍五入后最接近的整数。
譬如:
x = Math.round(20.49); //20
x = Math.round(20.5); //21
x = Math.round(-20.5); //-20
x = Math.round(-20.51); //-21
现在,CSS 借助 round() 函数也有了相同的能力:
line-height: round(2.2, 1); /* 2 */
line-height: round(14.82, 1); /* 15 */
line-height: round(5.5, 1); /* 6 */
也就是说,round(2.2, 1) 中的 2.2 四舍五入后,最后的计算值是 2。
round() 完整语法
round() 的完整语法规则还是比较复杂的。完整的介绍可以看 MDN - round()。
使用它,可以完美实现类似于 JavaScript 中的如下几个方法:
它的完整语法规则:
<round()> = round( <rounding-strategy>?, <valueToRound> , <roundingInterval> )
可以看到,它最多可以接收 3 个参数,并且第一个参数是可选参数:
<rounding-strategy>:可选参数,表示舍入策略。 这可能是以下值之一:up: 相当于 JavaScript Math.ceil() 方法,将 valueToRound 向上舍入到 roundingInterval 最接近的整数倍。 这相当于 JavaScript Math.ceil() 方法。down:将 valueToRound 向下舍入为 roundingInterval 最接近的整数倍。 这相当于 JavaScript Math.floor() 方法。nearest:将 valueToRound 舍入为 roundingInterval 的最接近的整数倍,该倍数可以高于或低于该值。 如果 valueToRound 是上方和下方舍入目标之间的一半,则会向上舍入。 相当于 JavaScript Math.round()。to-zero:将 valueToRound 舍入为 roundingInterval 接近/接近零的最接近整数倍。 这相当于 JavaScript Math.trunc() 方法。
<valueToRound>:需要被四舍五入的值。 必须是<number>、<dimension>或<percentage>,或者解析为这些值之一的数学表达式。<roundingInterval>:舍入的间隔规则。 这是一个<number>、<dimension>或<percentage>,或者解析为这些值之一的数学表达式。
基于此,举几个例子:
<div class="box-1"></div>
<div class="box-2"></div>
<div class="box-3"></div>
<div class="box-4"></div>
<div class="box-5"></div>
:root {
--rounding-interval: 25px;
}
div {
width: 100px;
background: rgba(255, 100, 0, .8);
}
div.box-1 {
height: round(nearest, 110px, var(--rounding-interval)); /* 最终计算值:100px */
}
div.box-2 {
height: round(up, 110px, var(--rounding-interval)); /* 最终计算值:125px */
}
div.box-3 {
height: round(down, 120px, var(--rounding-interval)); /* 最终计算值:100px */
}
div.box-4 {
height: round(to-zero, 120px, var(--rounding-interval)); /* 最终计算值:100px */
}
div.box-5 {
height: round(120px, var(--rounding-interval)); /* 最终计算值:125px */
}
结果如下:
图中背景一个格子的大小是
25px
完整的 DEMO 可以看这里 CodePen Demo - CSS Math Function Round() Demo
round 能解决什么问题?
OK,铺垫了那么久,我们下面进入实战环节。
那么,round() 函数在 CSS 中有什么具体的作用吗?能应用到什么地方?
解决基于 transform 的模糊问题
在之前的 疑难杂症:运用 transform 导致文本模糊的现象探究 这篇文章中,我们介绍了一种基于transform 的模糊问题。
我们来回顾一下问题现象:
在我们的页面中,经常会出现这样的问题,一块区域内的文本或者边框,在展示的时候,变得特别的模糊,如下(数据经过脱敏处理):
正常而言,应该是这样的:
emmm,可能大图不是很明显,我们取一细节对比,就非常直观了:
那么?什么时候会触发这种问题呢?在 Google 上,其实我们能搜到非常多类似的案例,总结而言:
- 当文本元素的某个祖先容器存在
transform: translate()或者transform: scale()等transform操作时,容易出现这种问题
当然,这只是必要条件,不是充分条件。继续深入探究,会发现,必须还得同时满足一些其它条件:
- 元素作用了
transform: translate()或者transform: scale()后的计算值产生了非整数
譬如,上述案例触发的 CSS 代码如下:
.container {
position: absolute;
width: 1104px;
height: 475px;
top: 50%;
transform: translateY(-50%);
// ...
}
由于元素的高度为 475px,translateY(-50%) 等于 237.5px,非整数,才导致了内部的字体模糊。
但是,需要注意的是,并非所有产生的非整数都会导致了内部的字体模糊。
这里有个简单的示意:
还是上述的例子,当高度从 477px 一直调整到 469px 的过程中,只有 477px 和 475px 导致了模糊,而 473, 471, 469 则没有。所以,这也只是引发模糊的一个必要条件。
- 文本内容是否模糊还与屏幕有关,高清屏(dpr > 2)下不容易触发,更多发生在普通屏幕下(dpr = 1)
在我实测的过程中还发现,这个现象基本只会发生在 dpr 为 1 的普通屏幕下。
类似于 MAC 的高清屏幕则不太会触发这个问题。
dpr = 物理像素 / 设备独立像素,表示设备像素比。这个与我们通常说的视网膜屏(多倍屏,Retina屏)有关。设备像素比描述的是未缩放状态下,物理像素和设备独立像素的初始比例关系。
- 并非所有浏览器都是这个表现,基本发生在 chromium 内核。
那么,为何会发生这种现象?针对这个问题,没有找到特别官方的回答,普遍的认为是因为:
由于浏览器将图层拆分到 GPU 以进行 3D 转换,而非整数的像素偏移,使得 Chrome 在字体渲染的时候,不是那么的精确。
关于这个问题,感兴趣的可以再看看这两个讨论:
- Chromium Bugs -- Issue 521364: Transformed text at fractional offsets is very blurry.
- Serious bug: Slick Slider turns off subpixel font rendering on the entire site in Chrome #2275
使用 round() 函数解决模糊问题
在之前,上面的这个基于 transform 的问题基本是无解的,想要不模糊,就需要替换掉 transfrom 方法。
而在有了 round() 后,我们可以通过 round() 函数,保证作用了 transform: translate() 或者 transform: scale() 后的计算值一定是正整数,从而避免模糊问题。
譬如,原本的 CSS 如下:
.container {
width: 50vw;
height: 50vh;
transform: translate(-50%, -50%);
}
此时,transform: translate() 的实际最终计算值是会出现小数的。因此,我们可以使用 round() 函数进行取整:
.container {
width: 50vw;
height: 50vh;
transform: translate(round(-50%, 1px), round(-50%, 1px));
}
我们可以使用如下 JavaScript 代码,打印出 transform 实时的计算值。
window.addEventListener("resize", () => {
const transform = getComputedStyle(document.querySelectorAll("div")[0]).transform;
console.log("transform:", transform);
});
如果使用 transform: translate(-50%, -50%) resize 整个页面,可以看到如下打印值:
可以看到,此时,transform: matrix(1, 0, 0, 1, -50.5, -106.75) 的中的后两位,其实就是 transform: translate(-50.5px, 106.75px),是存在小数值的。
而使用了 transform: translate(round(-50%, 1px), round(-50%, 1px)) 后,将不会再出现小数值:
完整的代码,你可以戳这里试一试:CodePen Demo -- round() Demo
借由 round() 函数,我们成功的解决了一直以来,Chrome 中非常棘手的一个模糊问题!
使用 round() 模拟步骤缓动动画
round() 还有一个有趣用法。我们可以使用 round() 实现类似于 CSS Animation 中的 steps() 步骤动画的效果。
我们来看这么一个 DEMO:
<div></div>
@property --angle {
syntax: '<angle>';
inherits: false;
initial-value: 0deg;
}
div {
width: 200px;
height: 200px;
border-radius: 50%;
background: conic-gradient(#fc0, #fc0 15deg, transparent 15deg, transparent 30deg);
transform: rotate(var(--angle));
animation: propertyRotate 2s infinite linear;
}
@keyframes propertyRotate {
100% {
--angle: 360deg;
}
}
这里,我们实现了这么一个动画效果:
我们可以利用 round(),把一个连贯动画,拆解成步骤动画:
div {
// ...
// transform: rotate(var(--angle));
transform: rotate(round(var(--angle), 30deg));
}
上面,我们使用 transform: rotate(round(var(--angle), 30deg)) 替换了 transform: rotate(var(--angle))。
而 round(var(--angle), 30deg) 保证了其取值只能是 30deg 的倍数或者 0deg。因此,我们可以得到和使用 stpes() 步骤动画一样的效果:
上面使用了 round() 的动画,和如下的动画效果是一致的:
div {
transform: rotate(round(var(--angle), 30deg));
}
// 等同于
div {
transform: rotate(var(--angle));
animation: propertyRotate 2s infinite steps(12);
}
因此,使用 round(),我们也可以轻松的实现类似如下的 Loading 动画效果:
完整的代码,你可以戳这里进行了解:CodePen Demo -- CSS Math Function Round() Animation Demo
最后
好了,本文到此结束,希望本文对你有所帮助
更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。
如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。
现代 CSS 解决方案:数学函数 Round的更多相关文章
- 现代 CSS 解决方案:CSS 数学函数
在 CSS 中,其实存在各种各样的函数.具体分为: Transform functions Math functions Filter functions Color functions Image ...
- hive函数之数学函数
hive函数之数学函数 round(double d)--返回double型d的近似值(四舍五入),返回bigint型: round(double d,int n)--返回保留double型d的n ...
- CSS 数学函数与容器查询实现不定宽文本溢出跑马灯效果
在许久之前,曾经写过这样一篇文章 -- 不定宽溢出文本适配滚动.我们实现了这样一种效果: 文本内容不超过容器宽度,正常展示 文本内容超过容器的情况,内容可以进行跑马灯来回滚动展示 像是这样: 但是,之 ...
- Myth – 支持变量和数学函数的 CSS 预处理器
Myth 是一个预处理器,有点类似于 CSS polyfill .Myth 让你写纯粹的 CSS,同时还让你可以使用类似 LESS 和 Sass 的工具.您仍然可以使用变量和数学函数,就像你在其它预处 ...
- Delphi 常用函数(数学函数)round、trunc、ceil和floor
源:Delphi 常用函数(数学函数)round.trunc.ceil和floor Delphi 常用函数(数学) Delphi中怎么将实数取整? floor 和 ceil 是 math unit 里 ...
- Delphi 数学函数:常用的几个数学函数(Power、Abs、Int、Trunc、Round、Frac、sqr、sqrt)
Delphi 常用的几个数学函数 1 Power函数,求次方 定义:function Power(X,Y): (Same type as parameter); 说明:X可以是整型,也可以是实型:返回 ...
- javascript函数一共可分为五类: ·常规函数 ·数组函数 ·日期函数 ·数学函数 ·字符串函数
javascript函数一共可分为五类: ·常规函数 ·数组函数 ·日期函数 ·数学函数 ·字符串函数 1.常规函数 javascript常规函数包括以下9个 ...
- Sql Server函数全解<二>数学函数
阅读目录 1.绝对值函数ABS(x)和返回圆周率的函数PI() 2.平方根函数SQRT(x) 3.获取随机函数的函数RAND()和RAND(x) 4.四舍五入函数ROUND(x,y) 5.符号函数SI ...
- Sql Server函数全解(二)数学函数
数学函数主要用来处理数值数据,主要的数学函数有:绝对值函数,三角函数(包括正弦函数,余弦函数,正切函数,余切函数).对数函数,随机函数等.在错误产生时,数学函数将返回空值null.本次介绍各种数学 ...
- Python数学函数
1.Python数学函数 1.abs(x):取绝对值,内建函数 2.math.ceil(x):向上取整,在math模块中 3.cmp(x,y):如果 x < y ,返回-1:如果 x == y ...
随机推荐
- Error in render: “TypeError: Cannot read property ‘0‘ of null“
我们web的同学运行程序时经常会遇到如下错误,而查找起来却相当费劲 看错误提示第一反应会想到是不是我的js 方法中的某个对象取值错误了,如: 但完全错了,当你把方法里的js 翻来覆去找了一遍又一遍,任 ...
- ✗ CocoaPods not installed.
mac 配置 flutter 会提示许多 关于xcode的 如图 显示 ✗ CocoaPods installed but not initialized. 其实最开始提示的是 ✗ CocoaPods ...
- GPUImage框架使用
GPUImage框架简介 GPUImage框架是一个基于OpenGL ES 2.0的iOS图像和视频处理框架.它充分利用GPU并行计算能力可以实时处理图像和视频,可以让开发者轻松地实现各种滤镜效果. ...
- How to fix the problem that Raspberry Pi cannot use the root user for SSH login All In One
How to fix the problem that Raspberry Pi cannot use the root user for SSH login All In One 如何修复树莓派无法 ...
- 如何获取 C#程序 内核态线程栈
一:背景 1. 讲故事 在这么多的案例分析中,往往会发现一些案例是卡死在线程的内核态栈上,但拿过来的dump都是用户态模式下,所以无法看到内核态栈,这就比较麻烦,需要让朋友通过其他方式生成一个蓝屏的d ...
- uniapp主题切换功能的第二种实现方式(scss变量+require)
在上一篇 "uniapp主题切换功能的第一种实现方式(scss变量+vuex)" 中介绍了第一种如何切换主题,但我们总结出一些不好的地方,例如扩展性不强,维护起来也困难等等,那么接 ...
- 深入浅出MySQL事务
Photo by Lukas Hartmann from Pexels 辞职这段时间以来看见了很多工作之外的东西,我认为这是值得的.同时也有时间和机会来好好整理所学所想,准备开启下一段旅途. 事务的定 ...
- Linux可视化管理-webmin工具
环境:连接工具:tabby,操作系统:centos7.6. webmin 介绍 Webmin 是功能强大的基于 Web 的 Unix/linux 系统管理工具.管理员通过浏览器访问 Webmin ...
- SQL Server中的NULL值处理:判断与解决方案
摘要: 在SQL Server数据库中,NULL是表示缺少数据或未知值的特殊标记.处理NULL值是SQL开发人员经常遇到的问题之一.本文将介绍SQL Server中判断和处理NULL值的不同方法,以及 ...
- range嵌套range beego前端页面渲染
range嵌套range beego前端页面渲染 问题 listA(name,age...) listB(hobby...) 有多个不同的list 对象,在前端中需要用range渲染,但是多个list ...