CSS Calc
Implemented from : https://drafts.csswg.org/css-values-4/ on 2023-02-17
Usage
Add CSS calc to your project:
npm install @csstools/css-calc @csstools/css-parser-algorithms @csstools/css-tokenizer --save-dev
With string values :
import { calc } from '@csstools/css-calc';
console.log(calc('calc(10 * 2)'));
With component values :
import { stringify, tokenizer } from '@csstools/css-tokenizer';
import { parseCommaSeparatedListOfComponentValues } from '@csstools/css-parser-algorithms';
import { calcFromComponentValues } from '@csstools/css-calc';
const t = tokenizer({
css: 'calc(10 * 2)',
});
const tokens = [];
{
while (!t.endOfFile()) {
tokens.push(t.nextToken());
}
tokens.push(t.nextToken());
}
const result = parseCommaSeparatedListOfComponentValues(tokens, {});
const calcResult = calcFromComponentValues(result, { precision: 5, toCanonicalUnits: true });
const calcResultStr = calcResult.map((componentValues) => {
return componentValues.map((x) => stringify(...x.tokens())).join('');
}).join(',');
console.log(calcResultStr);
Options
precision
:
The default precision is fairly high.
It aims to be high enough to make rounding unnoticeable in the browser.
You can set it to a lower number to suit your needs.
import { calc } from '@csstools/css-calc';
console.log(calc('calc(1 / 3)', { precision: 1 }));
console.log(calc('calc(1 / 3)', { precision: 2 }));
globals
:
Pass global values as a map of key value pairs.
Example : Relative color syntax (lch(from pink calc(l / 2) c h)
) exposes color channel information as ident tokens.
By passing globals for l
, c
and h
it is possible to solve nested calc()
's.
import { calc } from '@csstools/css-calc';
const globals = new Map([
['a', '10px'],
['b', '2rem'],
]);
console.log(calc('calc(a * 2)', { globals: globals }));
console.log(calc('calc(b * 3)', { globals: globals }));
toCanonicalUnits
:
By default this package will try to preserve units.
The heuristic to do this is very simplistic.
We take the first unit we encounter and try to convert other dimensions to that unit.
This better matches what users expect from a CSS dev tool.
If you want to have outputs that are closes to CSS serialized values you can pass toCanonicalUnits: true
.
import { calc } from '@csstools/css-calc';
console.log(calc('calc(0.01khz + 10hz)', { toCanonicalUnits: true }));
console.log(calc('calc(10hz + 0.01khz)', { toCanonicalUnits: true }));
console.log(calc('calc(0.01khz + 10hz)', { toCanonicalUnits: false }));
console.log(calc('calc(10hz + 0.01khz)', { toCanonicalUnits: false }));