Is there any way to use or implement modulus operator in css calc function?
I know there is mod operator and IE supports it, but what about other browsers?
For example
#element-id{
width: calc( 100% mod 5 );
}
Is there any way to use or implement modulus operator in css calc function?
I know there is mod operator and IE supports it, but what about other browsers?
For example
#element-id{
width: calc( 100% mod 5 );
}
Unfortunately, there is no more mention of the mod
operator in recent specs.
The calc() function allows mathematical expressions with addition (+), subtraction (-), multiplication (*), and division (/) to be used as component values.
You may want to resort to using javascript to achieve such behaviour.
var el = document.getElementById('element-id');
el.style.width = (100 % 5) + '%';
Simply..."NO".
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>
.
CSS Values and Units Module Level 4
(W3C Working Draft, 27 April 2022) has mod()
(general information about CSS4 at Wikipedia).
As of this writing (April 2022), this feature is so new that no browser supports it yet; in fact, it's so fresh that even Can I use doesn't have an entry for it. In the future, Can I use will probably have a dedicated page for mod()
at https://caniuse.com/mod.
While there currently is no support for mod()
, the modulo operation can be achieved with other CSS features, as presented in 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));
}
This technique leverages 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)
.
The following demo uses this technique to calculate the width
of some of its div
s:
div
s have hard-coded width
; no modulo magic here. Their purpose is to act as references for comparison to the div
s with modulo-calculated width. Note that the first, "green", div
is effectively invisible due to its width: 0px
.div
s, colored yellow, calculate their width according to the rule 100px * (a mod 3)
, for values a=[0, 1, 2, 3, 4]
. Due to 0 mod 3
and 3 mod 3
equaling 0
, their div
s have a width of 0px
and are therefore effectively invisible..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>
Besides the limited browser support, there is another possible caveat in using this calculated modulo technique: "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."
This operator is no longer supported in browsers. You can only use standard operations with calc:
This calc() article provides a further detailed explanation on the function.
Well, it supports 4 things; /
, *
, +
, -
.
And we just need a few maths.
Let's try, 10 divided by 5.
To get the remainder, we need to subtract "the multiplication of divisor and quotient" out of "the dividend." 10 / 5
will give us the quotient and that's enough for us to work things around.
--dividend = 10;
--divisor = 5;
// 10 - (5 * (10 / 5))
// 10 - (5 * 2)
// 10 - 10
// 0
Let's try again with 15 divided by 2.
--dividend = 15;
--divisor = 2;
// 15 - (2 * (15 / 2))
// 15 - (2 * 7)
// 15 - 14
// 1
So, it will be like this...
calc(var(--dividend) - (var(--divisor) * (var(--dividend) / var(--divisor))));
FYI, +
and -
operators must be surrounded by whitespace. But it's a good practice to use whitespace before and after the operator. See here for more.
calc(15 / 2)
is 7.5
not 7
. MDN: Usage with Integers –
Scutter Only Internet Explorer supports the mod function, I'm afraid, and it has been dropped from the CSS spec, so other browsers are not likely to support it any time soon.
If you dynamically generate your CSS, I created a small class to do simple functions like abs(), ceil(), floor(), mod() and sign() -- it can be used to build complex calc rules which you can pass to each other as arguments. If you use "var(--my-variable)" as a parameter, the CSS variable will be used. Note: it works best with raw numbers and has a utility function toUnit to convert to pixels (etc) at the end.
you can call it like so, jquery as an example to set the style:
$('#my-element').css('width', `${cssHack.toUnit(cssHack.mod(254,25),'px')}`)
Below is the code for the class (es6, no dependencies):
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}) `);
}
}
My recommendation would be to use JavaScript to set document.documentElement.style.setProperty(‘--variable’, ‘value’)
so that you can do the math in JS and use the variable in css.
document.documentElement.style.setProperty(‘--elementWidth’, ‘300px’)
, and in CSS: #elementID { width: var(--elementWidth); }
. –
Upandcoming this formula works for me :
@temp :(@value - (2 * (floor(@value / 2))));
if(@temp > 0, rgba(200, 200, 200, 0.20), rgba(100, 100, 100, 0.20)) ;
floor method help to remove decimal part of number and then final result can be checked if divisible to number 2 or not
© 2022 - 2024 — McMap. All rights reserved.