-
Notifications
You must be signed in to change notification settings - Fork 92
Units & Arithmetic
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]])
nil
For demonstration purposes we're only refer
ing 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))
16px
user=> (px (pt 1))
1.3333333333px
Unit arithmetic is available via the - spoiler alert- unit arithmetic functions.
user=> (require '[garden.units :refer (px+ px* px- px-div)])
nil
user=> (px+ 1 2 3 4 6)
16px
user=> (px-div 2 4)
0.5px
user=> (px* 2 2)
4px
Since the arithmetic functions use the primary unit functions in their definitions, conversion occurs seamlessly (when possible):
user=> (px* 2 (pt 1))
2.6666666666px
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 em
s
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))
#ff1515
user> (- 20 (px 1) 5 (pt 5))
7.333333333500001px