garden

Alex 2019-09-14T03:12:59.003900Z

Hi there, if I start out with something like

(ns some-file.css
  (:refer-clojure :exclude [> not])
  (:require
   [garden.selectors :as g :refer [& first-child > not ]]))

[:div.incomplete-actions {:margin-bottom "-1.5rem"}]
how can I get to
div.incomplete-actions {
  margin-bottom: -1.5rem;
}

div.incomplete-actions > div.incomplete-action:not(:last-child) {
  margin-bottom: 0;
}

noprompt 2019-09-14T04:28:14.005400Z

(require '[garden.core :as css])
(require '[garden.selectors :as $])

(css/css
 [($/> ($/div :.incomplete-actions)
       ($/div :.incomplete-action ($/not $/last-child)))
  {:margin-bottom 0}])
;; =>
;; div.incomplete-actions > div.incomplete-action:not(:last-child) {
;;   margin-bottom: 0;
;; }

noprompt 2019-09-14T04:30:23.005700Z

@rahx1t ☝️

Alex 2019-09-14T04:31:03.006500Z

That's very nice, thank you @noprompt! I was trying to use [:div... in combination with those. Would you say the selectors are more powerful?

noprompt 2019-09-14T04:31:32.007200Z

I would say that they are for this kind of thing.

noprompt 2019-09-14T04:32:17.008Z

Because you can def that selector.

Alex 2019-09-14T04:32:52.008200Z

Great, thanks a ton!

noprompt 2019-09-14T04:32:53.008400Z

(def $last-incomplete-action
  ($/> ($/div :.incomplete-actions)
       ($/div :.incomplete-action ($/not $/last-child))))

noprompt 2019-09-14T04:33:44.009400Z

I haven’t used this in a while but I remember when I was doing a lot of CSS with Garden I did this sort of thing frequently and it gave me a ton of control.

noprompt 2019-09-14T04:35:15.010400Z

Selectors are “sticky” too so you can then do something like.

(css/css
 [($last-incomplete-action $/hover)
  {:background "green"}])
;; =>
;; div.incomplete-actions > div.incomplete-action:not(:last-child):hover {
;;   background: green;
;; }

noprompt 2019-09-14T04:37:47.012800Z

Basically, you can use them either as a value or a function. As a value they end up being rendered as is. If you invoke them they accept other selectors as arguments and glue them together and give you an instance of the same kind of value/function thing.

Alex 2019-09-14T04:38:10.013200Z

Cool, I will focus on learning these selector patterns a bit better. at first glance, they are a lot more intuitive than what I was trying to do

Alex 2019-09-14T04:38:23.013500Z

That's awesome. They seem very composable

noprompt 2019-09-14T04:38:50.014Z

Yeah. Its borderline abusive. 🙂

noprompt 2019-09-14T04:39:18.014600Z

But I thought the idea was a lot of fun.

noprompt 2019-09-14T04:40:39.016Z

I tried to make them work like they do in CSS. You have operators like >, +, etc. that work with the prefix notation e.g. (+ s1 s2). The others simply concatenate.

Alex 2019-09-14T04:44:24.017Z

Is there a way to achieve what I had asked above without using the $/div selector? I think it's the "stickiness" you mentioned that is the differentiating factor

noprompt 2019-09-14T05:44:54.017700Z

@rahx1t I don’t think so but I can’t remember.