css-lite is a library for generating CSS from an s-exp based syntax. When compiled with Parenscript loaded in the Lisp image, it also provides the same CSS generation facilities in Parenscript-generated JavaScript code.
First, install Quicklisp.
After that, type in your Lisp prompt the following:
(ql:quickload 'css-lite)
It should download and load css-lite. This download is only done once, after that Quicklisp will always load your local copy of css-lite.
Note: In previous versions of css-lite there was a bug where you
sometimes couldn’t call (ql:quickload 'css-lite)
without having
previously called (ql:quickload 'parenscript)
. This bug has
hopefully now been fixed.
After loading the css-lite library, you are now ready to try these examples.
Set the width of the “body” tag to be 70%
(css-lite:css (("body") (:width "70%")))
Output:
" body { width:70%; } "
By default, css-lite doesn’t indent the properties. If you wish to
indent them, see the documentation for the variable
css-lite:*indent-css*
, or the section “Change the indentation” of
this README. For example, if you change the value of the variable
css-lite:*indent-css*
to 4, this would be the output:
" body { width:70%; } "
Set the height of the ID “foo” to 50px and the width to 10em
(css-lite:css (("#foo") (:height "50px" :width "10em")))
Output:
" #foo { height:50px; width:10em; } "
To do the same thing, but to a class “foo”, simply replace “#foo” with “.foo”.
(css-lite:css ((".foo") (:height "50px" :width "10em")))
Output:
" .foo { height:50px; width:10em; } "
Define the properties of rules “#foo” and “#foo li”
(css-lite:css (("#foo") (:length "50px" :margin "50 px 30 px" :border "1px solid red") (("li") (:width "50px" :float "left" :margin "50 px 30 px" :border "1px solid red"))))
Output:
" #foo { length:50px; margin:50 px 30 px; border:1px solid red; } #foo li { width:50px; float:left; margin:50 px 30 px; border:1px solid red; } "
In the third example, the rules “margin:50 px 30 px;” and “border:1px solid red;” are repeated twice. css-lite has something called CSS variables that allow to abstract this.
You create a CSS variable by using the macro css-lite:make-css-var
.
(css-lite:make-css-var my-favorite-border-var '(:border "1px solid red")) (css-lite:make-css-var my-margin-var '(:margin "50px 30px"))
Then you could write the third example as this:
(css-lite:css (("#foo") (:length "50px" my-margin-var my-favorite-border-var) (("li") (:width "50px" :float "left" my-margin-var my-favorite-border-var))))
Output:
" #foo { length:50px; margin:50px 30px; border:1px solid red; } #foo li { width:50px; float:left; margin:50px 30px; border:1px solid red; } "
In addition to the CSS variables, css-lite also provides the ability to define CSS functions. This allows you to perform arbitrary modifications on the rules.
This function is declared using the macro css-lite:make-css-func
and can receive any number of arguments. However, it should return
a list with 2 values, the first being the name of the property and
the second its value.
For example, to create a function that receives the name of a property and its value in inches and converts that value into centimeters use this:
(css-lite:make-css-func convert-in-to-cm (property-name value) ;; Assumes that `value' is a string with the following ;; format: XXin, where XX represents a number greater than 0 (let* ((inches (parse-integer (string-right-trim "in " value))) (centimeters (round (* inches 2.54)))) (list property-name (concatenate 'string (write-to-string centimeters) "cm"))))
So this call:
(convert-in-to-cm :width "10in")
Returns this list:
(:WIDTH "4cm")
So to use this function to convert the height of the identifier “#foo” from inches to centimeters, you would write this code:
(css-lite:css (("#foo") (:length "50px" my-margin-var (convert-in-to-cm :width "10in") my-favorite-border-var)))
Output:
" #foo { length:50px; margin:50px 30px; width:4cm; border:1px solid red; } "
To add a CSS comment use the function css-lite:comment
(css-lite:css (("body") ((css-lite:comment "These are the rules for the body tag") :width "80%" :float "left")))
Output:
" body { /*These are the rules for the body tag*/ width:80%; float:left; } "
To see more examples, see the file example-usage.lisp
As you can see be the above examples, by default, css-lite doesn’t indent the rules.
However you can customize this behaviour by changing the value of
the variable css-lite:*indent-css*
.
There are three possible values:
- nil - The default value, indicates that no indentation should be performed
- the symbol ‘tab - Indicates that the rules should be indented using a #\Tab character
- a number greater than 0 - Indicates that the rules should be indented with that many #\Space characters.
For example, to indent the rules with 4 spaces, you would type:
(setf css-lite:*indent-css* 4)
The next time you call the css-lite:css
function, the code will be
indented with 4 spaces.
For example, calling the function css-lite:css
with this value:
(css-lite:css (("body") ((css-lite:comment "These are the rules for the body tag") :width "80%" :float "left")))
Output:
" body { /*These are the rules for the body tag*/ width:80%; float:left; } "
Test implemented using the FiveAM test library.
Run tests via the ASDF :TEST-OP
(asdf:oos ':test-op 'css-lite/test)
Or using the FiveAM run command
(fiveam:run! :css-lite)