arithmetic expressions on CSS variables,
tokenized & calculated in userland, w/o eval
.
zero deps, ~900 bytes
.
npm i https://github.com/nicholaswmin/arithmeticss.git
Assuming some.css
:
:root {
--foo: 10px;
--bar: 5;
--baz: 2;
}
then in some.js
:
import calc from '@nicholaswmin/arithmeticss'
const res = calc('--foo * --bar + --baz * 3')
console.log(res) // logs: 56
…thats all.
For example: 50% + 100em = 150
, which is wrong.
I didn’t need fancy units, so I didn’t bother, but it should be fairly easy to extend.1
e.g: --foo * (--bar + 5)
is invalid.
Fancy arithmetic requires a shunting-yard implementation, i.e., 10x more code. I’ll pass.
won’t work: --foo+--bar
. It’s ambiguous.
works: --foo + --bar
.
Parsing errors throw a SyntaxError
, the rest will either
be a TypeError
or (rarely) a RangeError
.
requires node
v23+
unit tests:
node --run test
coverage:
node --run coverage
bundling & min. are application-level concerns, not module-level concerns
so there’s no build
or dist/
versions here.
That being said, you can run:
npx esbuild index.js --bundle --minify --format=esm --outfile="dist/arithmeticss.js"
… which builds a minified bundle at: dist/arithmeticss.js
,
which you simply move to your own project & import
as usual:
<!-- ... some html -->
<script type="module">
import calc from './arithmeticss.js'
console.log(calc('--foo + --bar * 10'))
// 230
</script>
<!-- more html ... -->
MIT License
Copyright (c) 2024 Nicholas Kyriakides
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, ncluding without limitation the rights to: use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
em
is based on the font-size of the parent. Easy.
rem
is based on the font-size of the root. Also easy.
%
is based on the ??? … this is tricky because
its based on the property where the variable is assigned.
It’s doable but the syntax is gonna look like crap. ↩