CSS abs() and sign(): Absolute values without JS
Absolute values and direction without JavaScript math
Negative custom properties used to need JavaScript Math.abs or a Sass helper before you could use them as lengths. abs() and sign() do that math in CSS, so spacing and offsets stay positive and direction-aware.
The old hack vs the modern fix
View demo.panel {
--offset: -1.5rem;
/* max() fallback for abs, or JS Math.abs before setting the var */
margin-inline-start: max(var(--offset), -1 * var(--offset));
}
/* JS: el.style.setProperty('--offset', Math.abs(raw) + 'rem'); */.panel {
--offset: -1.5rem;
margin-inline-start: abs(var(--offset));
translate: calc(1rem * sign(var(--offset))) 0;
}
/* positive length + direction from one variable */Abs sign browser support
Live demo
Why the modern way wins
No JS clamp
Skip Math.abs and class toggles. A negative custom property can still resolve to a valid length.
Direction from the sign
sign() returns -1, 0, or 1. Multiply it to flip translate, margin, or gradient angle from one variable.
Works inside calc()
Both functions take a calc-sum, so they compose with percentages, lengths, and other math functions.
- Key Change
- Native math
- Browser handles abs and sign
- Old Approach
- Math.abs or Sass
- Script or build step
- Modern Approach
- abs() + sign()
- CSS Values Level 4
How it works
abs() returns the absolute value of its argument, keeping the same unit. Wrap a custom property that might be negative and you always get a positive length: margin-inline-start: abs(var(--offset)).
sign() returns 1, -1, or 0 based on the numeric sign. Multiply that by a length to push an element left or right from one variable: translate: calc(1rem * sign(var(--offset))) 0.
Before these shipped, the usual fallback was max(var(--x), -1 * var(--x)) for absolute values, or JavaScript to normalize the number before writing a style. Prefer abs() when you can, and keep the max() pattern only as a fallback for older browsers.