Skip to content
Generate CSS from clojure code with an embedded DSL
Clojure Shell
Find file
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
script
src
test
.gitignore
.travis.yml
README.textile
epl-v10.html
project.clj

README.textile

cssgen

A clojure library to generate CSS code using an embedded domain-specific language (EDSL). In plain words: generate CSS files
by writing clojure code.

You can go here to read more about cssgen.

Please take a look at the upcoming syntax in version 0.3.0, tell me what you think: 0.3.0-SNAPSHOT

Using clojure instead of plain CSS you get a lot of benefices. You can use the full power of the language to do things
like:

  • Define constants and use them in your rules

    (def width (px 960))

  • Operate with your constants using clojure expressions

    (def main-width (* width 0.62))

  • Define nested rules

    (rule "a.plain"
      :color :inherit
      :text-decoration :inherit
      :cursor :inherit
      (rule "&:active, &:focus"
        :outline :none)))

  • Define reusable CSS snippets using plain old clojure functions and vars

    (def has-layout
      (mixin
        ; This makes ie6 get layout
        :display "inline-block"
        ; and this puts it back to block
        (rule "&" :display :block)))

    (def clearfix
      (mixin
        :overflow :hidden
        has-layout))

  • Generate readable styles with better code organization

    (rule "#nav"
      (horizontal-list (px 9))
      (rule "a"
        (link-colors my-link-color my-visited-color my-hover-color)))

  • Easy CSS ‘hacks’

    (defn- float-side [side]
      (mixin :display :inline :float side))

    (defvar float-left (float-side :left)
      "Implementation of float:left with fix for double-margin bug")

    (defvar float-right (float-side :right)
      "Implementation of float:right with fix for double-margin bug")

    (rule "#secondary"
      float-right)

Installation

The easiest way to install cssgen is by using Leiningen. Just add the following dependency to your project.clj file:


    [cssgen "0.2.6"]

Usage

I’ll show some examples of use, but you should read the wiki for more details and information.

  • CSS rules: to create a simple rule you use the rule function, passing the selector as first argument, and a
    series of property pairs.

    (rule "ul.nav, ol"
      :color :black
      :background-color :#ddd
      :padding [:1px "2px" (px 3) 0])

  • Property values could be
    • keywords,
    • strings,
    • any other type convertible to string with as-str,
    • values sequences
    • special constructions like (px 9), (% 30), (col :#aaa) (more about this
      later).

If a property key must be associated with several values, you use a sequence of values, like in the padding
property above. Of course, if everything is “literal”, you could simply do :padding "1px 2px 3px 4px".

  • You can nest rules:

    (rule "#main, #secondary"
      :padding "10px"

      (rule "h1"   ; this will generate a rule for "#main h1, #secondary h1"
        :color :blue))

  • If you need the parent selector on the nested rule, you can use “&” and it will get replaced:

    (rule "a"
      :color "#00C"

      (rule "&:hover"  ; this will generate a rule for a:hover
        :color "#0CC"))

  • You can define mixins with multiple rules and properties using functions or vars. Those can later be used in other
    definitions

    (defn link-colors
      ([normal] (link-colors normal nil))
      ([normal hover]
        (mixin
          :color normal
          (if visited (rule "&:visited" :color visited))
          (if hover   (rule "&:hover" :color hover)))))

    (rule "a"
      (link-colors "#00c" "#0cc"))

  • As you can see in the previous example, nils in the properties list will be ignored:
  • You can easily define constants

    (def width (px 960))
    (def h1-font-size (em 1.5))
    (def h1-color (col :#0000ca))
    (def h2-color (col :#0dd))
    (def h3-color ($ :#0dd)) ;  $ is just an alias for col
    (def form-size (% 60))

  • And use the basic arithmetic operations on them

    (def main-width (* 0.7 width))
    (def h2-font-size (- h1-font-size (em 0.3)))
    (def h4-color (/ (+ h2-color h3-color) 2))

  • To generate a new CSS file from the current clj code do:

    (use 'cssgen.use)
    (css-ns killerapp.css.screen
      (:use (killerapp.css reset layout colors)))

    (css-file "public/css/screen.css"  ;this is the path to the target CSS file
      .......
      .......  ; all your rules
      .......)

Instead of css-ns you could use the normal (ns) call, but it gets a little tricky since we are redefining arithmetic
operations.

ToDo

  • More syntactic sugar
  • Helper functions to operate with colors and lengths
  • Helpers to define dimensions and colors
  • Methods to define rules without actually generating any CSS file
  • Watcher to re-generate css files if source changed ???
  • Property namespaces (font-*)
  • Write a sass “compiler” to migrate from sass to cssgen
  • Use that compiler to generate the whole compass tree in cssgen.
  • Document
  • Command line interface

Check the wiki for more usage information.

If you have a feature request, problem or comment, just drop me a line.

Something went wrong with that request. Please try again.