Skip to content

Instantly share code, notes, and snippets.

@dy
Last active December 4, 2020 13:50
Show Gist options
  • Save dy/3b306b55638bcf9b6b5d75d09c25d7b7 to your computer and use it in GitHub Desktop.
Save dy/3b306b55638bcf9b6b5d75d09c25d7b7 to your computer and use it in GitHub Desktop.
CSS-calc based math expressions in JS
<script>
let hiddenNode = document.documentElement.appendChild(document.createElement('div'))
hiddenNode.style.visibility = 'hidden'
hiddenNode.style.height = 0
function calc(expression) {
let cssExpression = expression
// a + b → var(--a) + var(--b)
.replace(/([a-z]\w*)(\b[^(]|$)/ig, 'var(--$1)$2')
// -var(--a) → -1 * var(--a)
.replace(/-var/g, '-1 * var')
let measurer = hiddenNode.appendChild(document.createElement('div'))
measurer.style.setProperty('left', `calc((${cssExpression}) * 1px)`)
return (vars) => {
for (let v in vars) measurer.style.setProperty(`--${v}`, vars[v])
return parseFloat(getComputedStyle(measurer).getPropertyValue('left'))
}
}
let e1 = calc('a / b')
console.log(e1({a:1, b: 3}))
let e2 = calc('-a/b')
console.log(e2({a:1, b: 4}))
let e3 = calc('min(a,b)')
console.log(e3({a:1, b: -1}))
let e4 = calc('min(a,b) * max(c,d)')
console.log(e4({a:1,b:2, c:2,d:1}))
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment