Selectors - JeremS/cljss-core GitHub Wiki

simple selectors

String or keywords are used for simple selectors:

[:div.class1.class2 ...]
=> "div.class1.class2 {...}"

["div.class1.class2" ...]
=> "div.class1.class2 {...}"

combining selectors

Css provide 4 ways to combine selectors

  • the descendant combinator, spaced selectors in css, Sequential (vector/list/lasyseq) of selectors in cljss
[[:div :a] ...] => "div a { ... }"
  • the children combinator, > character in css, :> or ">" between selectors in cljss
[:div :> :p ...] => "div > p { ... }"
  • the siblings combinator, + character in css, :+ or "+" between selectors in cljss
[[:div :+ :p] ...] => "div + p { ... }"
  • the general siblings combinator, ~ character in css, "~" between selectors in cljss
[:div "~" :a ...] => "div ~ a { ... }"

We can of course combine them:

[[:section :div :> :p :+ :a :span] ...] => "section div > p + a span { ... }"

We can also use sets to represent list of selectors have the same properties:

[[:.class1 #{:ul :ol} :> :li] ...] => ".class1 ul > li, .class1 ol > li"

Note that you need to enclose your combined selectors in a 'sequential' since the first element of a rule is considered the selector, the being rest property declarations. Thus:

; Not what we want...
[:div :> :p :border [:1px :solid :black]]
;=> "div {>: p; border: 1px solid black;}"

; Better
[:div :> :p] :border [:1px :solid :black](/JeremS/cljss-core/wiki/:div-:>-:p]-:border-[:1px-:solid-:black)
"div > p { border: 1px solid black;}"

pseudos & attribute selectors

Pseudo classes, pseudo elements and attribute selectors are implemented as functions that you can use to enrich a selector. The pseudo class will appear as a suffix to the selector parameter:

[(hover :a) ... ]
[(first-letter :p) ... ]
[(-> [:ul :> :li] hover (nth-child :even)) ... ]
[(-> :a (att-sel "href=\"http://...\"")) ...]

generates:

a:hover {
  ...
}
p::first-letter {
  ...
}
ul > li:hover:nth-child(even) {
  ...
}
a[href="http://..."] {
  ...
}

Parent selector

The selector & is inspired by its namesake in sass, stylus...

However its semantics are different in cljss. As of now, inside nested rules, cljss combines a parent selector with its child when the selector & is not used. When it is, it just replaces the selector & with the selector of the parent rule.

  • When we don't use '&', here is the behaviour in sass:
 section {
 ...
   div { ... }
 }

generates:

section { ... }
section div { ... }

Here the selectors "section" and "div" are combined in "section div" for the second rule. The same is true for cljss:

 [:section ...
   [:div ...]]
   => "section {...} section div {}"
  • at first look cljss behaves like sass when '&' is used:
a {...
  &:hover { ... }}

generates:

a { ... }
a:hover {...}

and

[:a ...
  [(-> & hover) ...]]
=> "a {}
    a:hover { ... }"
  • it becomes different when sets are involved in sass:
section { ...
  & , div {...}
}

generates:

section {...}
section,
section div { ... }

while with cljss:

[:section ...
  [#{& :div} ...]]

generates:

section {...}
section, div { ... }