All Projects → paraseba → Cssgen

paraseba / Cssgen

Generate CSS from clojure code with an embedded DSL

Programming Languages

clojure
4091 projects

h1. cssgen

"!https://secure.travis-ci.org/paraseba/cssgen.png!":http://travis-ci.org/paraseba/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":http://wiki.github.com/paraseba/cssgen/ 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":https://github.com/paraseba/cssgen/tree/0.3.0

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)

h2. 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"]

h2. Usage

I'll show some examples of use, but you should read the "wiki":http://wiki.github.com/paraseba/cssgen/ 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.

h2. 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":http://compass-style.org/ tree in cssgen.
  • Document
  • Command line interface

h3. Check the "wiki":http://wiki.github.com/paraseba/cssgen/ for more usage information.

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

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].