现代 CSS 解决方案:数学函数 Round

这篇具有很好参考价值的文章主要介绍了现代 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 中的如下几个方法:

  1. Math.ceil()
  2. Math.floor()
  3. Math.round()
  4. Math.trunc()

它的完整语法规则:

<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 */
}

结果如下:

现代 CSS 解决方案:数学函数 Round

图中背景一个格子的大小是 25px

完整的 DEMO 可以看这里 CodePen Demo - CSS Math Function Round() Demo

round 能解决什么问题?

OK,铺垫了那么久,我们下面进入实战环节。

那么,round() 函数在 CSS 中有什么具体的作用吗?能应用到什么地方?

解决基于 transform 的模糊问题

在之前的 疑难杂症:运用 transform 导致文本模糊的现象探究 这篇文章中,我们介绍了一种基于transform 的模糊问题。

我们来回顾一下问题现象:

在我们的页面中,经常会出现这样的问题,一块区域内的文本或者边框,在展示的时候,变得特别的模糊,如下(数据经过脱敏处理):

现代 CSS 解决方案:数学函数 Round

正常而言,应该是这样的:

现代 CSS 解决方案:数学函数 Round

emmm,可能大图不是很明显,我们取一细节对比,就非常直观了:

现代 CSS 解决方案:数学函数 Round

那么?什么时候会触发这种问题呢?在 Google 上,其实我们能搜到非常多类似的案例,总结而言:

  1. 当文本元素的某个祖先容器存在 transform: translate() 或者 transform: scale()transform 操作时,容易出现这种问题

当然,这只是必要条件,不是充分条件。继续深入探究,会发现,必须还得同时满足一些其它条件:

  1. 元素作用了 transform: translate() 或者 transform: scale() 后的计算值产生了非整数

譬如,上述案例触发的 CSS 代码如下:

.container {
    position: absolute;
    width: 1104px; 
    height: 475px;
    top: 50%;
    transform: translateY(-50%);
    // ...
}

由于元素的高度为 475pxtranslateY(-50%) 等于 237.5px,非整数,才导致了内部的字体模糊。

但是,需要注意的是,并非所有产生的非整数都会导致了内部的字体模糊。

这里有个简单的示意:

现代 CSS 解决方案:数学函数 Round

还是上述的例子,当高度从 477px 一直调整到 469px 的过程中,只有 477px475px 导致了模糊,而 473, 471, 469 则没有。所以,这也只是引发模糊的一个必要条件。

  1. 文本内容是否模糊还与屏幕有关,高清屏(dpr > 2)下不容易触发,更多发生在普通屏幕下(dpr = 1)

在我实测的过程中还发现,这个现象基本只会发生在 dpr 为 1 的普通屏幕下。

类似于 MAC 的高清屏幕则不太会触发这个问题。

dpr = 物理像素 / 设备独立像素,表示设备像素比。这个与我们通常说的视网膜屏(多倍屏,Retina屏)有关。设备像素比描述的是未缩放状态下,物理像素和设备独立像素的初始比例关系。

  1. 并非所有浏览器都是这个表现,基本发生在 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 整个页面,可以看到如下打印值:

现代 CSS 解决方案:数学函数 Round

可以看到,此时,transform: matrix(1, 0, 0, 1, -50.5, -106.75) 的中的后两位,其实就是 transform: translate(-50.5px, 106.75px),是存在小数值的。

而使用了 transform: translate(round(-50%, 1px), round(-50%, 1px)) 后,将不会再出现小数值:

现代 CSS 解决方案:数学函数 Round

完整的代码,你可以戳这里试一试: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;
    }
}

这里,我们实现了这么一个动画效果:

现代 CSS 解决方案:数学函数 Round

我们可以利用 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() 步骤动画一样的效果:

现代 CSS 解决方案:数学函数 Round

上面使用了 round() 的动画,和如下的动画效果是一致的:

div {
    transform: rotate(round(var(--angle), 30deg));
}
// 等同于
div {
    transform: rotate(var(--angle));
    animation: propertyRotate 2s infinite steps(12);
}

因此,使用 round(),我们也可以轻松的实现类似如下的 Loading 动画效果:

现代 CSS 解决方案:数学函数 Round

完整的代码,你可以戳这里进行了解:CodePen Demo -- CSS Math Function Round() Animation Demo

最后

好了,本文到此结束,希望本文对你有所帮助 😃

更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。

如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。文章来源地址https://www.toymoban.com/news/detail-693320.html

到了这里,关于现代 CSS 解决方案:数学函数 Round的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • css相邻元素边框重合问题,解决方案

    给每个元素设置margin-top以及margin-left为负的边框 我的解决方案是在宽度上下手,根据观察,发现一行三列,实际导致缺失的是两个边框的大小,那么将这两个边框的大小平分到每行三列模块的开宽度内即可解决,其他情况下,由此推导

    2024年03月08日
    浏览(37)
  • Github page数学公式无法正常显示解决方案(MathJax)

    在上传一篇文献阅读笔记到Github page时发现公式无法正常显示,之前在typora中能够正常显示的代码在网页上显示为纯latex格式于是进行了一些搜索。 我使用的Jekyll模板是chirpy,具体效果可能与使用的模板也有关系。 这个问题的原因出在GitHub Page里的Jekyll虽然支持Markdown,但是不

    2024年02月03日
    浏览(50)
  • 【vue项目部署CSS失效】VUE部署后css样式加载无效和失效多种情况解决方案

    【写在前面】vue3在vscode运行正常、build后在IDEA运行正常,但是当部署在服务器上运行发现样式加载不出来,下面我们针对这些情况进行复现与解决。 困扰我好久,当即百度原因,百度清一色下面三种情况: 1、nginx配置文件的问题 2、控制台样式404,文件没找到【文件路径错

    2023年04月09日
    浏览(42)
  • CSS使两个不同的div居中对齐的三种解决方案

    在CSS中,有多种方法可以让两个不同的div居中对齐,包括相对定位和绝对定位。以下是两种常见的方法: 方法一:使用Flexbox Flexbox是一个用于创建灵活布局的CSS3模块。使用Flexbox,可以很容易地对元素进行居中对齐。 HTML: CSS: 方法二:使用CSS Grid CSS Grid是另一个用于创建二维

    2024年02月10日
    浏览(60)
  • 本论文以图像识别为研究对象,采用数学建模方法,探索图像识别中的问题并提出解决方案。

    第一部分:问题描述 随着数字图像的广泛应用,图像识别技术逐渐成为热门研究领域。但是,在实际应用中,由于图像的复杂性和噪声的存在,图像识别的准确性和效率仍然存在一定的挑战。因此,本论文旨在研究图像识别中存在的问题,提出准确率和效率提高的解决方案。

    2024年02月10日
    浏览(38)
  • CSS笔记——font、line-height知识点及图片间隙、文本溢出等解决方案

    font-family(字体族 ):指定字体的名称或类别。可以指定多个字体族,用逗号分隔,浏览器会按照指定的顺序依次寻找可用字体。可取值: 字体名称:如\\\"Arial\\\"、\\\"Times New Roman\\\"等。 通用字体系列:如\\\"serif\\\"、“sans-serif”、\\\"monospace\\\"等。 自定义字体系列:如\\\"myFont, Arial, sans-serif

    2024年02月07日
    浏览(52)
  • pycharm中的 opencv-python 没有函数提示的解决方案

    pycharm中用 pip install opencv-python 安装的cv2可能没有函数提示功能,“ctrl+鼠标左键” 也不会进入源代码,解决方案如下: 1、找到cv2对应python编译器的安装路径 pycharm左下角,将鼠标放在编译器版本(我这里是本地环境的python3.7)上面,就可以看到当前的python路径: 2、进入py

    2024年02月12日
    浏览(49)
  • 微信小程序上拉触底事件函数onReachBottom不触发的解决方案

    配置属性问题 高度问题 滚动条不在顶部 需要回到顶部重新计算高度 onReachBottom函数被覆盖 1.配置属性问题 在app.json或者本页的json文件中配置 onReachBottomDistance 属性,区别在于全局还是只在本页生效 2.高度问题 3. 切换页面时 滚动条滚回到顶部 4. onReachBottom() 函数被覆盖 每个页

    2024年02月11日
    浏览(38)
  • hive分位函数percentile和percentile_approx误区和解决方案

    percentile和percentile_approx对分位数的计算是不同的!!! 拿中位数来说, percentile(col, 0.5),结果和正常理解的中位数相同,即col排序后最中间的一个数(col观察数为奇数时)或者最中间两个数的平均数(col观察数为偶数时)为中位数; percentile_approx(col, 0.5),则是按照 等频划分

    2024年02月05日
    浏览(41)
  • 解决VS中scanf()函数报错问题的四种方案(详细)

     scanf函数在VS中报错的主要原因是 scanf被认为不安全而被编译器默认设置为禁用。 那么如何解决这个问题呢 法一: 仅将函数 scanf 替换为 scanf_s 即可,其他语法不变。但scanf_s函数并不是C语言函数库里的标准函数,而是VS编译器所提供的函数,所以并不推荐用这种方法来解决

    2024年02月02日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包