Units & Arithmetic

Aaron Iba edited this page Jul 27, 2018 · 3 revisions


So far we've got all the core pieces to start building basic stylesheets. But it would be useful to have something for working with one of CSS's most fundamental data types: units!

Fortunately, Garden has built in support for working with all the major CSS units. This includes creation, conversion, and arithmetic. To start using units use/require the garden.units namespace.

user=> (require '[garden.units :as u :refer [px pt]])

For demonstration purposes we're only refering the px and pt units but Garden supports all of the usual suspects. Also we'll use the css macro to render the units as strings but note this is not necessary when authoring a stylesheet.

Unit creation is straightforward:

user=> (px 16)
#garden.types.CSSUnit{:unit :px, :magnitude 16}

Unit functions take a number n and construct a new garden.types.CSSUnit record with n as the magnitude. Unit functions also accept other units as values returning their conversion if possible. This makes working with unit values very flexible.

user=> (px (px 16))
user=> (px (pt 1))

Unit arithmetic is available via the - spoiler alert- unit arithmetic functions.

user=> (require '[garden.units :refer (px+ px* px- px-div)])
user=> (px+ 1 2 3 4 6)
user=> (px-div 2 4)
user=> (px* 2 2)

Since the arithmetic functions use the primary unit functions in their definitions, conversion occurs seamlessly (when possible):

user=> (px* 2 (pt 1))

You might be wondering, which units can be converted to another? This depends on the type of unit you are working with. The CSS spec outlines a few categories of units but only absolute (px, pt, pc, in, cm, and mm), angle (deg, grad, rad, turn), time (s, ms), and frequency (Hz, kHz) units may be freely converted and only between their respective groups. This means you cannot, for example, convert px to rad or Hz to cm. Doing so will raise an error.

In the future, some exceptions to this rule might apply for working with ems since it's technically possible to compute their contextual value.


Now that we have a solid understanding of how units and colors operate, we can talk about Garden's generic arithmetic operators. While working with functions like px+, color+, etc. have their advantages, sometimes they can get in the way. To get around this you can use the operators in the garden.arithmetic namespace.

(ns user
  ;; Unless you want to see a bunch of warnings add this line.
  (:refer-clojure :exclude [+ - * /])
  (:require [garden.arithmetic :refer [+ - * /]]))

This will allow you to perform operations like this:

user> (+ 20 (color/hsl 0 0 0) 1 (color/rgb 255 0 0))
user> (- 20 (px 1) 5 (pt 5))
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.