在 css 计算函数中使用模数
Using modulus in css calc function
有什么方法可以在 css 计算函数中使用或实现 modulus 运算符?
我知道有 mod 运算符并且 IE 支持它,但是其他浏览器呢?
例如
#element-id{
width: calc( 100% mod 5 );
}
干脆...“不”。
The expression can be any simple expression combining the following operators, using standard operator precedence rules:
+
Addition.
-
Subtraction.
*
Multiplication. At least one of the arguments must be a <number>
.
/
Division. The right-hand side must be a <number>
.
恐怕只有 Internet Explorer 支持 mod 功能,而且已经 dropped from the CSS spec,因此其他浏览器不太可能很快支持它。
遗憾的是,recent specs中不再提及mod
运算符。
The calc() function allows mathematical expressions with addition (+), subtraction (-), multiplication (*), and division (/) to be used as component values.
您可能希望使用 javascript 来实现这种行为。
var el = document.getElementById('element-id');
el.style.width = (100 % 5) + '%';
浏览器不再支持此运算符。
您只能将 标准操作 与计算一起使用:
- 加法+
- 减法-
- 乘法*
- 除法/
此 calc() article 提供了对该功能的进一步详细说明。
如果您动态生成 CSS,我创建了一个小的 class 来执行简单的函数,例如 abs()、ceil()、floor()、mod() 和sign() -- 它可用于构建复杂的计算规则,您可以将这些规则作为参数传递给彼此。如果您使用“var(--my-variable)”作为参数,将使用 CSS 变量。
注意:它最适合原始数字,并且有一个实用函数 toUnit 可以在最后转换为像素(等)。
可以这样调用,jquery以设置样式为例:
$('#my-element').css('width', `${cssHack.toUnit(cssHack.mod(254,25),'px')}`)
下面是 class 的代码(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}) `);
}
}
好吧,它支持 4 个东西; /
、*
、+
、-
。
我们只需要一些数学。
我们试试,10 除以 5。
要得到余数,我们需要从“被除数”中减去“除数与商的乘积”。 10 / 5
会给我们商数,这足以让我们解决问题。
--dividend = 10;
--divisor = 5;
// 10 - (5 * (10 / 5))
// 10 - (5 * 2)
// 10 - 10
// 0
让我们用 15 除以 2 再试一次。
--dividend = 15;
--divisor = 2;
// 15 - (2 * (15 / 2))
// 15 - (2 * 7)
// 15 - 14
// 1
所以,会是这样的……
calc(var(--dividend) - (var(--divisor) * (var(--dividend) / var(--divisor))));
仅供参考,+
和 -
运算符必须用空格包围。但在运算符前后使用空格是一个好习惯。 See here for more.
CSS 值和单位模块级别 4
(W3C 工作草案,2022 年 4 月 27 日)有 mod()
(general information about CSS4 at Wikipedia).
截至撰写本文时(2022 年 4 月),此功能太新了,尚无浏览器支持;事实上,它是如此新鲜,以至于 Can I use 都没有条目。将来,Can I use 可能会在 https://caniuse.com/mod.
有专门的 mod()
页面
虽然目前不支持 mod()
,但可以通过其他 CSS 功能[=76] 实现 取模运算 =],如 https://css-tricks.com/using-absolute-value-sign-rounding-and-modulo-in-css-today:
中所示
@property --floor {
syntax: '<integer>';
initial-value: 0;
inherits: false;
}
.a-mod-b-width {
background-color: yellow;
--floor: calc(var(--a)/var(--b) - 0.5);
--mod: calc(var(--a) - var(--b)*var(--floor));
width: calc(100px * var(--mod));
}
此技术利用 calc()
and @property
, albeit @property
having limited browser support as well as of this writing: Therefore, this technique works in Chrome, Edge, and Opera; but it currently does not work in Firefox and Safari. The main trick is to define a CSS property --floor
with "syntax" <integer>
, which calculates values using the floor function. Having a floor function available this way, a mod b
is calculated in the --mod
property using the function a - b * floor(a / b)
。
以下演示使用此技术计算其某些 div
的 width
:
- 在第 1 到 4 行中,right-column
div
有 hard-coded width
;这里没有 modulo 魔法。它们的目的是作为与 模 计算宽度的 div
进行比较的参考。请注意,第一个“绿色”div
由于其 width: 0px
. 实际上是不可见的
- 从第 5 行开始,黄色的 right-column
div
根据规则 100px * (a mod 3)
计算它们的宽度,值 a=[0, 1, 2, 3, 4]
。由于 0 mod 3
和 3 mod 3
等于 0
,它们的 div
宽度为 0px
,因此实际上是不可见的。
.grid-container {
display: grid;
grid-template-columns: auto auto;
background-color: lightgray;
grid-gap: 10px;
}
.grid-container > *:nth-child(2n + 1) {
background-color: silver;
font-family: monospace;
}
.green {
background-color: green;
width: 0px;
}
.aqua {
background-color: aqua;
width: 100px;
}
.orange {
background-color: orange;
width: 200px;
}
.red {
background-color: red;
width: 300px;
}
@property --floor {
syntax: '<integer>';
initial-value: 0;
inherits: false;
}
.a-mod-b-width {
background-color: yellow;
--floor: calc(var(--a)/var(--b) - 0.5);
--mod: calc(var(--a) - var(--b)*var(--floor));
width: calc(100px * var(--mod));
}
.a0 {
--a: 0;
}
.a1 {
--a: 1;
}
.a2 {
--a: 2;
}
.a3 {
--a: 3;
}
.a4 {
--a: 4;
}
.a5 {
--a: 5;
}
.b0 {
--b: 0;
}
.b1 {
--b: 1;
}
.b2 {
--b: 2;
}
.b3 {
--b: 3;
}
.b4 {
--b: 4;
}
<div class="grid-container">
<div>width: 0px (green)</div>
<div class="green"></div>
<div>width: 100px (aqua)</div>
<div class="aqua"></div>
<div>width: 200px (orange)</div>
<div class="orange"></div>
<div>width: 300px (red)</div>
<div class="red"></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div>width: 100px * (0 mod 3)</div>
<div class="a0 b3 a-mod-b-width"></div>
<div>width: 100px * (1 mod 3)</div>
<div class="a1 b3 a-mod-b-width"></div>
<div>width: 100px * (2 mod 3)</div>
<div class="a2 b3 a-mod-b-width"></div>
<div>width: 100px * (3 mod 3)</div>
<div class="a3 b3 a-mod-b-width"></div>
<div>width: 100px * (4 mod 3)</div>
<div class="a4 b3 a-mod-b-width"></div>
<div>width: 100px * (5 mod 3)</div>
<div class="a5 b3 a-mod-b-width"></div>
</div>
除了有限的浏览器支持之外,使用这种计算模数技术还有一个可能的注意事项:"The Chrome browser currently won't accept some values returned by calc() when an integer is expected. This includes any division, even if it results in an integer. ie. z-index: calc(4 / 2); will not be accepted."
有什么方法可以在 css 计算函数中使用或实现 modulus 运算符?
我知道有 mod 运算符并且 IE 支持它,但是其他浏览器呢?
例如
#element-id{
width: calc( 100% mod 5 );
}
干脆...“不”。
The expression can be any simple expression combining the following operators, using standard operator precedence rules:
+
Addition.
-
Subtraction.
*
Multiplication. At least one of the arguments must be a<number>
.
/
Division. The right-hand side must be a<number>
.
恐怕只有 Internet Explorer 支持 mod 功能,而且已经 dropped from the CSS spec,因此其他浏览器不太可能很快支持它。
遗憾的是,recent specs中不再提及mod
运算符。
The calc() function allows mathematical expressions with addition (+), subtraction (-), multiplication (*), and division (/) to be used as component values.
您可能希望使用 javascript 来实现这种行为。
var el = document.getElementById('element-id');
el.style.width = (100 % 5) + '%';
浏览器不再支持此运算符。 您只能将 标准操作 与计算一起使用:
- 加法+
- 减法-
- 乘法*
- 除法/
此 calc() article 提供了对该功能的进一步详细说明。
如果您动态生成 CSS,我创建了一个小的 class 来执行简单的函数,例如 abs()、ceil()、floor()、mod() 和sign() -- 它可用于构建复杂的计算规则,您可以将这些规则作为参数传递给彼此。如果您使用“var(--my-variable)”作为参数,将使用 CSS 变量。 注意:它最适合原始数字,并且有一个实用函数 toUnit 可以在最后转换为像素(等)。
可以这样调用,jquery以设置样式为例:
$('#my-element').css('width', `${cssHack.toUnit(cssHack.mod(254,25),'px')}`)
下面是 class 的代码(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}) `);
}
}
好吧,它支持 4 个东西; /
、*
、+
、-
。
我们只需要一些数学。
我们试试,10 除以 5。
要得到余数,我们需要从“被除数”中减去“除数与商的乘积”。 10 / 5
会给我们商数,这足以让我们解决问题。
--dividend = 10;
--divisor = 5;
// 10 - (5 * (10 / 5))
// 10 - (5 * 2)
// 10 - 10
// 0
让我们用 15 除以 2 再试一次。
--dividend = 15;
--divisor = 2;
// 15 - (2 * (15 / 2))
// 15 - (2 * 7)
// 15 - 14
// 1
所以,会是这样的……
calc(var(--dividend) - (var(--divisor) * (var(--dividend) / var(--divisor))));
仅供参考,+
和 -
运算符必须用空格包围。但在运算符前后使用空格是一个好习惯。 See here for more.
CSS 值和单位模块级别 4
(W3C 工作草案,2022 年 4 月 27 日)有 mod()
(general information about CSS4 at Wikipedia).
截至撰写本文时(2022 年 4 月),此功能太新了,尚无浏览器支持;事实上,它是如此新鲜,以至于 Can I use 都没有条目。将来,Can I use 可能会在 https://caniuse.com/mod.
有专门的mod()
页面
虽然目前不支持 mod()
,但可以通过其他 CSS 功能[=76] 实现 取模运算 =],如 https://css-tricks.com/using-absolute-value-sign-rounding-and-modulo-in-css-today:
@property --floor {
syntax: '<integer>';
initial-value: 0;
inherits: false;
}
.a-mod-b-width {
background-color: yellow;
--floor: calc(var(--a)/var(--b) - 0.5);
--mod: calc(var(--a) - var(--b)*var(--floor));
width: calc(100px * var(--mod));
}
此技术利用 calc()
and @property
, albeit @property
having limited browser support as well as of this writing: Therefore, this technique works in Chrome, Edge, and Opera; but it currently does not work in Firefox and Safari. The main trick is to define a CSS property --floor
with "syntax" <integer>
, which calculates values using the floor function. Having a floor function available this way, a mod b
is calculated in the --mod
property using the function a - b * floor(a / b)
。
以下演示使用此技术计算其某些 div
的 width
:
- 在第 1 到 4 行中,right-column
div
有 hard-codedwidth
;这里没有 modulo 魔法。它们的目的是作为与 模 计算宽度的div
进行比较的参考。请注意,第一个“绿色”div
由于其width: 0px
. 实际上是不可见的
- 从第 5 行开始,黄色的 right-column
div
根据规则100px * (a mod 3)
计算它们的宽度,值a=[0, 1, 2, 3, 4]
。由于0 mod 3
和3 mod 3
等于0
,它们的div
宽度为0px
,因此实际上是不可见的。
.grid-container {
display: grid;
grid-template-columns: auto auto;
background-color: lightgray;
grid-gap: 10px;
}
.grid-container > *:nth-child(2n + 1) {
background-color: silver;
font-family: monospace;
}
.green {
background-color: green;
width: 0px;
}
.aqua {
background-color: aqua;
width: 100px;
}
.orange {
background-color: orange;
width: 200px;
}
.red {
background-color: red;
width: 300px;
}
@property --floor {
syntax: '<integer>';
initial-value: 0;
inherits: false;
}
.a-mod-b-width {
background-color: yellow;
--floor: calc(var(--a)/var(--b) - 0.5);
--mod: calc(var(--a) - var(--b)*var(--floor));
width: calc(100px * var(--mod));
}
.a0 {
--a: 0;
}
.a1 {
--a: 1;
}
.a2 {
--a: 2;
}
.a3 {
--a: 3;
}
.a4 {
--a: 4;
}
.a5 {
--a: 5;
}
.b0 {
--b: 0;
}
.b1 {
--b: 1;
}
.b2 {
--b: 2;
}
.b3 {
--b: 3;
}
.b4 {
--b: 4;
}
<div class="grid-container">
<div>width: 0px (green)</div>
<div class="green"></div>
<div>width: 100px (aqua)</div>
<div class="aqua"></div>
<div>width: 200px (orange)</div>
<div class="orange"></div>
<div>width: 300px (red)</div>
<div class="red"></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div>width: 100px * (0 mod 3)</div>
<div class="a0 b3 a-mod-b-width"></div>
<div>width: 100px * (1 mod 3)</div>
<div class="a1 b3 a-mod-b-width"></div>
<div>width: 100px * (2 mod 3)</div>
<div class="a2 b3 a-mod-b-width"></div>
<div>width: 100px * (3 mod 3)</div>
<div class="a3 b3 a-mod-b-width"></div>
<div>width: 100px * (4 mod 3)</div>
<div class="a4 b3 a-mod-b-width"></div>
<div>width: 100px * (5 mod 3)</div>
<div class="a5 b3 a-mod-b-width"></div>
</div>
除了有限的浏览器支持之外,使用这种计算模数技术还有一个可能的注意事项:"The Chrome browser currently won't accept some values returned by calc() when an integer is expected. This includes any division, even if it results in an integer. ie. z-index: calc(4 / 2); will not be accepted."