我有以下情况:
div {
width: calc((100% / 11) - 9.09px);
}
在这种情况下,100%
等于1440px
,而9.09px
在Sass中通过数学计算生成。结果为:
94.55px
,因为calc
将其向上舍入,但我需要94.54px
(向下舍入)。如何将其向下舍入到最接近的百分之一位?
编辑:示例。
一般而言,我会说这是不可能的,但有一个黑客技巧。然而在网络上,黑客技巧似乎成为了常态,而非例外,所以我只能说这是可能的:
div {
--shf: 4.9406564584124654e-322;
width: calc(((100% / 11) - 9.09px) * var(--shf) / var(--shf));
}
这段代码的作用:将要四舍五入的数值乘以一个非常小的值,使其在第三个小数点后溢出。然后,它将截断的值除回去,得到数值的四舍五入版本。这种方法假定您支持的所有浏览器都使用64位浮点数值。如果不是这样的话,不仅会导致错误,而且在使用更小的浮点数据类型时可能会返回零,从而完全破坏您的页面。
将指数改为-323可在第一位小数点处进行四舍五入,将指数改为-324可在整数值处进行四舍五入。
Floor(x) = Round(x - 0.5)
和Ceiling(x) = Round(x + 0.5)
。 - Eliseo D'Annunzio很遗憾,CSS中没有原生的方法来四舍五入(或向上/向下取整)数字。
不过,你提到你正在使用Sass。我找到了一个小型的Sass库,可以将数字四舍五入、向下取整或向上取整到指定的精度。
例如,如果你有一个数值为94.546
,你可以使用decimal-floor(94.546, 2)
,它会返回94.54
。
不幸的是,如果你必须使用calc()
在CSS中进行实时计算,这可能无法帮助你。但是,如果你可以预先计算width
并通过Sass将其向下取整,那么就可以满足你的需求。一种可能的解决方案是使用@media
查询作为设置断点的方式,并在Sass预处理中使用这些断点。
round()
CSS 函数在 CSS Values and Units Module Level 4 中,您可以使用 round()
CSS 函数 对数字或尺寸进行任意舍入。
round(<rounding-strategy>, valueToRound, roundingInterval)
rounding-strategy
可以是 up
, down
, nearest
(默认值) 或者 to-zero
,分别对应于 Javascript 中的 Math.ceil
, Math.floor
, Math.round
和 Math.trunc
。
将 <canvas>
元素调整大小到与其父元素几乎相同(“舍入间隔为 a CSS pixel,而不是设备像素。”),保持画布像素宽高比为 1:1(假设 window.devicePixelRatio
是自然数):
canvas {
display: block;
width: round(down, 100%, 1px);
height: round(down, 100%, 1px);
}
如果你的问题是与一个像素舍入误差相关的视觉差异,那么在大多数情况下,你实际上不需要进行舍入。一个相对简单的解决方案是使其中一个项目占据所有剩余空间。
在弹性布局的情况下,如果你不需要布局换行,甚至可以选择其中一个中心项目,以获得最不明显的效果。
.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%;
}
calc()
就变得无关紧要了,所有这些都可以在Sass中完成,Sass具有更强大的数学工具,并且不会让客户端为计算而劳累。width: 100%
设置为,因为没有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%;
}
$('#my-element').css('width', `${cssHack.toUnit(cssHack.round(1000/3),'px')}`)
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}) `);
}
}
你不能用Sass进行四舍五入吗?既然你已经在使用它,那就试试它的round、floor和ceil方法: https://sass-lang.com/documentation/modules/math#bounding-functions
(在较旧版本的Sass中也可以使用,不过语法略有不同)
calc()
会向上取整。因此,如果您想要向下取整,您需要使用JavaScript。 - TylerH