css
syntax
Below is the grammar for the css form:
external-css-stylesheet ::= (css import-clause* rule+) internal-css-stylesheet ::= (css/html import-clause* rule+) import-clause ::= ( import string ) rule ::= ( complex-selector css-avp+ ) complex-selector ::= single-selector | grouping-selector simple-selector ::= symbol | (class symbol) | (class symbol symbol) | -- (class <type> <class>) (pclass symbol) | (pclass symbol symbol) | -- (pclass <type> <pseudo-class>) (id symbol) | (id symbol symbol) -- (id <type> <id>) path-selector ::= ( // simple-selector+ ) single-selector ::= simple-selector | path-selector grouping-selector ::= ( single-selector+ ) css-avp ::= ( symbol scheme-expression ) | (! (symbol scheme-expression))
Note 1: scheme-expression must evaluate to a string
Note 2: internal-css-stylesheet translates to
(style type: "text/css" (css import-clause* rule+))
What follows is a basic example illustrating webIt!'s embedding off CSS in Scheme. this example creates a simple HTML document which uses an external CSS stylesheet. The CSS stylesheet is used to color the background navy, and set different text fragments yellow, white, and red.
(require (lib "xml.ss" "webit") (lib "html.ss" "webit") (lib "css.ss" "webit"))
The css
syntax creates a CSS stylesheet. Informally, css
takes a list of rules, each of which consists of a
selector and a property list. In the first rule, for example, the selector is body,
and the property list includes settings for font-family, font-size, and
background-color.
(define ex-css (css (body (font-family "sans-serif") (font-size "12pt") (background-color "navy")) (p (color "white")) (p.ex (color "red")) (h1 (color "yellow"))))
This creates the following stylesheet:
body { font-family: sans-serif; font-size: 12pt; background-color: navy; } p { color: white; } p.ex { color: red; } h1 { color: yellow; }
(define ex (h4:html (h4:head (css-link "a.css") (h4:title "Stylesheet Example")) (h4:body (h4:h1 "Stylesheet Example; this text is yellow") (h4:p "This text is white") (h4:p h4:class: "ex" "This text is red"))))
(write-xml ex-css (open-output-port "a.css"))
(write-xml ex (open-output-port "a.html"))
In the HTML above, we can see the use of the css-link form, which takes a single argument, the URL of the external stylesheeet. This form is simply shorthand for the construction of the following HTML:
(h4:link h4:rel: "stylesheet" h4:href: "a.css" h4:type: "text/css")
The sections below describe in more detail the construction of CSS stylesheets in Webit!.
The simplest form is the simple selector:
p { color: white; }
The simple selector is just a symbol that is the element type to which this style property applies. This is written as:
(css (p (color "white")))
Elements can also be selected by "class", that is, by the value of the HTML "class" attribute:
.ex {color: red;}
This is written as:
(css (.ex (color "red")))
This is a convenient notation--and one which is supported by PLT. But not all Scheme's support symbols which begin with a ".". This example can also be written in a more verbose form:
(css ((class ex) (color "red")))
A selector can also be written with both an element type and a class.
p.ex {color: red; }
This is written as:
(css (p.ex (color "red")))
or, in the verbose notation:
(css ((class p ex) (color "red")))
Using PLT's "infix" notation, this last can also be written as:
(css ((p . class . ex) (color "red"))))
if that is to one's taste.
Pseudo-classes are supported in a similar manner. One can color a visited link "lime":
a:visited { color: lime; }
which is written as:
(css (a:visited (color "lime")))
or, in the verbose notation:
(css ((pclass a visited) (color "lime")))
or
(css ((a . pclass . visited) (color "lime"))))
As with classes, a selector may include only a pseudo-class:
:visited { color: lime; }
which is written as:
(css (:visited (color "lime")))
or as
(css ((pclass visited) (color "lime")))
Lastly, classes and pseudo-classes can be combined:
a.external:visited { color: blue; }
which is written as:
(css (a.external:visited (color "blue")))
or
(css ((pclass (class a external) visited) (color "blue")))
This selector, without the element type, can also be used:
.external:visited { color: blue; }
which is written as:
(css (.external:visited (color "blue")))
or
(css ((pclass (class external) visited) (color "blue")))
One may attach unique "identifiers" to HTML elements, using the id attribute. The value of an id attribute may be used as a selector as well.
To match the following paragraph tag:
<p id=z98y>Wide text</p>
the following style rule can be defined:
#z98y { letter-spacing: 0.3em; }
This would be written as:
(css ((id z98y) (letter-spacing "0.3em")))
(In principle, "(id z98y)" can also be written as the symbol "|#z98y|".)
Id's may also be combined with an element type in a selector:
h1#z98y {letter-spacing: 0.5em; }
written as:
(css ((id h1 z98y) (letter-spacing "0.5em")))
or
(css ((id h1 z98y) (letter-spacing "0.5em")))
CSS allows one to specify that a "style" applies only to selected elements, in a _context_. For example, if I want to color emphasized text red, but only within an h1 element, this can be written as:
h1 em { color: red; }
which, in the WebIt! embedding, is given as:
(css ((// h1 em) (color "red")))
The keyword "//" is used to suggest a similarity of a contextual specifier with a "path expression" (as in XPath/SXPath).
The "steps" in a contextual specifier can be an element type, class, pseudo-class, an id, or a combination of these.
To avoid duplicating style descriptions, selectors may be grouped together. Any of the above kinds of selectors may be grouped, as shown below, where a simple selector (an element type) and a contextual selector are grouped:
h1, h2 b, h2, em { color: red; }
The grouping "operator" is just a list:
(css ((h1 (// h2 b) (// h2 em)) (color "red")))