garden

GusWill 2021-01-07T02:23:23.002800Z

Hi! First post here! 🙂 So, I'm just getting started with the CSS-in-clojure approach and I was wondering if there's any way to namespace/scope my css with garden.

GusWill 2021-01-07T02:25:12.003700Z

I found one lib that seems to do what I need (https://github.com/roosta/herb), but it also seems like it generates css in js.

GusWill 2021-01-07T02:26:02.004400Z

I was wondering if there was an approach for "classic", static, good ol backend rendered css.

noprompt 2021-01-07T15:29:41.004900Z

Do you have a sketch/example of what you’re thinking about?

GusWill 2021-01-07T15:32:43.005900Z

@noprompt thanks for replying. After I posted my question I found a few libs that do mostly what I want: https://github.com/JeromeDane/garden-css-modules, https://github.com/matthieu-beteille/cljs-css-modules, https://github.com/Jarzka/stylefy.

GusWill 2021-01-07T15:33:10.006400Z

I have to investigate further, but the problem is that they seem to be focused on cljs.

GusWill 2021-01-07T15:34:06.007300Z

I'm looking for something that implements something like this: https://glenmaddern.com/articles/css-modules but not is JS, just a plain CSS file. Makes sense?

GusWill 2021-01-07T15:36:24.008700Z

Those libs contain a runtime that does the CSS injection, etc. I'd prefer not to pay the JS performance price because the project where I want to introduce it is mostly classic server-rendered html.

GusWill 2021-01-07T15:37:40.010700Z

I might be talking nonsense since, my css knowledge is very limited. It that is the case, my apologies.

noprompt 2021-01-07T15:38:25.011800Z

Are you using something like Hiccup?

GusWill 2021-01-07T15:38:45.012700Z

In the end my real problem is: our css is a real mess and, after working with React's scoped styles, I'd like that, but for a plain back-end rendered site.

GusWill 2021-01-07T15:38:49.012900Z

Yes, hiccup.

GusWill 2021-01-07T15:38:57.013300Z

The old-school one.

noprompt 2021-01-07T15:39:46.014200Z

It seems like you essentially want a unique name that you don’t have to maintain but, at the same time, be able to refer to it with a nice name, yes?

GusWill 2021-01-07T15:40:36.014800Z

Yes. Essentially, namespaces for our "components".

GusWill 2021-01-07T15:41:07.015400Z

Right now we have a hot mess of 200kb of CSS that we have no idea which parts can be deleted and which parts are connected to what.

GusWill 2021-01-07T15:42:52.016500Z

I'd like to refactor everything to use something like Garden, but with that feature you just described.

noprompt 2021-01-07T15:43:35.017500Z

If it’s safe to assume things are compiled together then you could use gensym for making unique names.

(let [normal (gensym ".normal__")]
  [normal {:font-weight "normal"}])
;; =>
[.normal__49244 {:font-weight "normal"}]

noprompt 2021-01-07T15:45:27.019100Z

Or a similar idea if you want to include something like namespace or something else to easily identify where the thing came from.

GusWill 2021-01-07T15:46:55.019500Z

Hadn't thought of that. That makes perfect sense, thanks!

noprompt 2021-01-07T15:49:02.020600Z

(let [css-munge (fn [s]
                  (clojure.string/replace s #"\." "$"))
      make-name (fn [prefix ns]
                  (gensym (str prefix "__" (css-munge (ns-name ns)) "__")))]
  (make-name ".normal" *ns*))
;; =>
.normal__scratch__49273

noprompt 2021-01-07T15:49:17.021Z

Just kinda messing around with the idea.

GusWill 2021-01-07T15:50:01.022200Z

Yeah, that's almost exactly what I was thinking, including the ns

noprompt 2021-01-07T15:50:18.022700Z

Then you can (def normal (make-name ".normal" *ns*)) or something and use that in your styles.

GusWill 2021-01-07T15:50:24.022900Z

But you're quicker 😀

noprompt 2021-01-07T15:50:29.023100Z

LOL

noprompt 2021-01-07T15:50:52.023700Z

I always have a REPL open :)

noprompt 2021-01-07T15:51:09.024200Z

Well almost always 😄

GusWill 2021-01-07T15:51:22.024400Z

Is this a conventional use case? Are there any gotchas that my noob css mind can't think of?

noprompt 2021-01-07T15:52:35.026200Z

I can’t think of any. As long as you’re generating a valid CSS identifier you’re good.

GusWill 2021-01-07T15:52:38.026300Z

Yeah, sometimes it's better to test things out in the repl than to try to find libs that solve my problem!

GusWill 2021-01-07T15:53:13.027300Z

Awesome! Thanks man, really appreciate your help!

noprompt 2021-01-07T15:53:23.027700Z

Not a problem.

GusWill 2021-01-07T15:55:47.029700Z

BTW, most of the libs I just linked provide a robust make-name function that I can just copy and paste.

noprompt 2021-01-07T15:56:15.030200Z

I think the only draw back I can see to this approach is for the HTML/Hiccup side of things.

GusWill 2021-01-07T15:56:18.030300Z

If anyone goes down this road in the future

GusWill 2021-01-07T15:56:26.030600Z

wdym?

noprompt 2021-01-07T15:57:15.031700Z

Well you couldn’t use [:h1 {:class scratch/normal}] because you’d wind up with <h1 class=".normal__45545"></h1>

noprompt 2021-01-07T15:58:15.032500Z

You could generate the name without the . however for the identifier and then use the garden.selectors namespace for everything else.

noprompt 2021-01-07T16:01:25.033300Z

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

(def normal
  (gensym "normal__"))

(def $normal
  (css.$/selector (str "." normal)))

GusWill 2021-01-07T16:02:49.034100Z

Makes sense. I'd have to come up with some kind of mapping between them.

noprompt 2021-01-07T16:04:25.034700Z

If styles were XML…

noprompt 2021-01-07T16:05:55.035500Z

One of these days I’m gonna get back to the front end.

GusWill 2021-01-07T16:08:29.035600Z

My 200kb hot mess would be more like 2Mb hot mess 😂

😆 1