css calc - 以小数点后两位向下取整
Posted
技术标签:
【中文标题】css calc - 以小数点后两位向下取整【英文标题】:css calc - round down with two decimal cases 【发布时间】:2016-10-11 19:02:52 【问题描述】:我有以下情况:
div
width: calc((100% / 11) - 9.09px);
在上下文中,100%
= 1440px
,9.09px
是在数学中用 sass 生成的。
结果是:94.55px
,因为 calc
将其舍入 up,但我需要 94.54px
(舍入 down) .
我如何向下取整到最接近的百分之一?
编辑:example。
【问题讨论】:
你不应该得到这些值中的任何一个。 (1440 / 11) = 130.90909 像素,减去 9.09 像素 = 121.89109 像素。您能否创建一个重现您的错误的minimal reproducible example? 但是按照规范,CSScalc()
会向上取整。所以如果你想四舍五入,你需要使用 javascript。
@TylerH,现在有问题的例子
W3C official discussion - “添加 round()/floor()/ceil() 函数” - 请捶打一下
相关:***.com/q/63667411/8620333
【参考方案1】:
一般来说,我会说这是不可能的,但有一个 hack。然而在网络中,黑客似乎是常态,而不是例外,所以我只想说这是可能的:
div
--shf: 4.9406564584124654e-322;
width: calc(((100% / 11) - 9.09px) * var(--shf) / var(--shf));
这是做什么的:它将要四舍五入的值乘以一个非常小的值,该值下溢从第三个小数点开始的值。然后,它将截断的值除回去,得到该值的四舍五入版本。这假定您支持的所有浏览器都使用 64 位浮点值。如果不这样做,这不仅会出错,而且在使用较小的浮点数据类型时可能会返回零,从而完全破坏您的页面。
将指数更改为 -323 以在第一个小数点处四舍五入,将指数更改为 -324 以在整数值处四舍五入。
【讨论】:
出于好奇,您是如何专门为--shf
找到这个号码的?
@DanielEinars 是最小次正规正双精度(en.wikipedia.org/wiki/…)
我打赌你会问自己突然之间所有的赞成票发生了什么xD
您的点赞来自reddit.com/r/webdev/comments/k0yj3k/…
@PhilippWilhelmparty-pooper,让他挠挠头=P【参考方案2】:
不幸的是,CSS 中没有原生方法来舍入(或 ceil/floor)数字。
但是——你提到你正在使用 Sass。我找到了一个small Sass library,它可以将数字四舍五入到指定的精度。
例如,如果您有一个 94.546
,您可以使用 decimal-floor(94.546, 2)
,这将返回 94.54
。
不幸的是,如果您必须使用 calc()
来使用 CSS 进行动态计算,这可能无济于事。但是,如果您可以预先计算 width
并使用 Sass 对其进行调整,它将满足您的需求。一种可能的解决方案是使用 @media
查询作为设置断点并在 Sass 预处理中使用这些断点的一种方式。
【讨论】:
不幸的是它并没有解决我的问题。非常感谢您解释这一点和您的建议。【参考方案3】:如果您的问题是与视觉差异相关的一个像素舍入误差,在大多数情况下,您实际上不需要舍入。一个相对简单的解决方案是让你的一个项目占据所有剩余空间。
在 flex 场景中,如果您不需要包装布局,您甚至可以选择中心项目中的 oen,以获得尽可能不引人注意的效果。
.some-block
width: calc( ( 100% / 11 ) - 9.09px );
flex-shrink: 0;
.some-block:nth-of-type(5)
// Will attempt to take the whole width, but its siblings refuse to shrink, so it'll just take every bit of remaining space.
width: 100%;
根据您的确切 CSS 案例,像素减法可能会通过使用填充或边距以及额外的嵌套元素来完全避免。这样一来,CSS calc()
就变得无关紧要了,这一切都可以在 Sass 中完成,Sass 具有更强大的数学工具,并且不会让客户端进行计算。
同样在 flex 上下文中,如果您的目标只是让每个元素都相等,那么您可能根本不需要计算。详情请见this question。
在表格中,由于单元格宽度是从左到右计算的,因此可以使用类似的技巧,但您必须将 width: 100%
分配给 last 单元格,因为没有flex-shrink
和列宽从左到右决定。
.my-table
table-layout: fixed;
.table-cell
width: calc( ( 100% / 11 ) - 9.09px );
.table-cell:last-of-type
// Will attempt to take the whole width, but since previous column widths have already been determined, it cannot grow any further than its allocated width plus any stray pixels.
width: 100%;
【讨论】:
【参考方案4】:如果您动态生成 CSS,我创建了一个小类来执行简单的函数,例如 round()、ceil()、floor()、abs()、mod() 和 sign()——它可以用来构建复杂的计算规则,您可以将它们作为参数传递给彼此。如果您使用“var(--my-variable)”作为参数,则将使用 CSS 变量。 注意:它最适用于原始数字,并且有一个实用函数 toUnit 可以在最后转换为像素(等)。
可以这样调用,以jquery为例来设置样式:
$('#my-element').css('width', `$cssHack.toUnit(cssHack.round(1000/3),'px')`)
下面是类的代码(es6,无依赖):
class cssHack
//primary used for dynamic css variables-- pass in 'var(--dynamic-height)'
static toUnit(val,unit)
unit='1'+unit;
return ` calc($val * $unit) `;
static round(val)
// the magic number below is the lowest possible integer, causing a "underflow" that happily results in a rounding error we can use for purposeful rounding.
return ` calc($val * $Number.MIN_VALUE / $Number.MIN_VALUE) `;
static abs(val)
return ` max($val, calc($val * -1)) `;
static floor(val)
return cssHack.round(` calc($val - .5) `);
static ceil(val)
return cssHack.round( `calc($val + .5) `);
static sign(val)
let n = ` min($val,0) `; //if val is positive then n =0. otherwise n=val.
let isNegative= ` min($cssHack.ceil(cssHack.abs(n)),1) `;
let p = ` max($val,0) `; //if val is negative then n=0, otherwise n = val;
let isPositive= ` min($cssHack.ceil(cssHack.abs(p)),1) `;
return ` calc($isPositive + calc($isNegative * -1)) `;
static mod(val, base)
let abs = cssHack.abs(val);
let div = ` calc($abs / $base)`;
let dec = ` calc($div - $cssHack.floor(div))`;
return cssHack.round(` calc($dec * $base) `);
【讨论】:
以上是关于css calc - 以小数点后两位向下取整的主要内容,如果未能解决你的问题,请参考以下文章
写出一个程序,接受一个正浮点数值,输出该数值的近似整数值。如果小数点后数值大于等于5,向上取整;小于5,则向下取整。