The CSS problem

Hi everyone,

I was searching the forum for what people do CSS-wise, and found mainly material over two years old.

Today, what is your preferred (or at least habitual) way of expressing styles?

Some backstory: I was thinking generally about how CSS works, and how, for a lack of a better word, cumbersome it is. With ClojureScript, when we make an SPA (or PWA, or whatever), I believe we have other options. …To tell you the truth, I am leaning towards inline styles rather than even having a stylesheet. But I wanted to hear from all y’allz, and maybe there is some brilliant approach which I haven’t considered.

I’ve been using Garden for years, it offers both server-side and client-side CSS rendering and I highly recommend it:


Thanks, outrovurt. I think I would prefer Garden overall (though I’m curious what the alternatives are), but I am a bit dismayed that it hasn’t had a commit in four years.

Tailwind CSS is superb. It takes a functional approach to CSS which gets around specificity problems. It has tooling to optimise your output CSS so it’s minimal. There’s great editor support and documentation.


I prefer this approach. class-based approach is good but many times really unnecessary, especially with custom widgets.

Since I know you tried shadow-css I’m curious to know what you feel was cumbersome about it? Yes, the build process is not ideal but once setup it works pretty seamless.

As for CSS in generall nowadays I use shadow-css of course, previously I used a tailwind setup similar to this one, and before that I used SASS via node-sass, and even longer before that I just concatenated some manual CSS files together. That was indeed the most cumbersome of them all, but still worked fine.

Inline Styles work to some extent, that is why shadow-css encourages them for truly “dynamic” uses but they quickly hit limits for stuff you just can’t express with them. Pseudo-selectors or Media Queries being the most common ones.

1 Like

I would argue that css allows too much to be done and people should restrict its use to styling only and simple layouts

More powerful features like pseudo-selectors and media queries are better controlled programmatically, rather than through css.

1 Like

I like using girouette for a Clojure-focused approach similar to tailwind.

Another vote for Garden, it’s the best way to manage CSS imo.

I am a bit dismayed that it hasn’t had a commit in four years.

I see this kind of comment a lot in various places, my teams have been using garden for longer than 4 years, essentially without issue. It just works. Things don’t have to be changing to be good.

Interestingly, there is some discussion about updates and pushing a new release ongoing (Release request, to prevent repeated shadowed-var warnings in the REPL · Issue #197 · noprompt/garden · GitHub), but even that is just to silence some warnings in tooling that is much younger than garden itself. :slight_smile:

I’ve enjoyed garden anytime I’ve used it, being able to manipulate declarations as dynamically as any other forms is great, but always return to static CSS files for a specific reason: code autocomplete, hinting, links to MDN reference alongside the ide language servers are unbeatable. I’ve found it just plain less enjoyable to grind out styles without the helping hand. Anyone worked around this, have workflows to share?


Oh, I don’t find shadow-css cumbersome; but I was reading the Tailwind CSS docs, and all the limitations and rules that if you do x then you can’t do y, and it felt to me to be very tightly coupled (if I’m using that term correctly)—like you had to know it through and through in order not to make a mistake, because so many things depended on other things. Add to that that it does have edge cases (bugs), and it does evolve, which means I have to keep my mental model up-to-date. All this feels just too complex.

And it’ts not Tailwind’s fault. There is something about the way we are all using CSS which makes me think, There has to be a better way.

As far as shadow-css, I think it is an elegant solution and I think I’ll continue using it.

In fact my “dismay” about its not being committed-to in four years is all about that warning you mention :slight_smile: . On the whole I agree though, that if a project hasn’t had commits in a long time it certainly does not indicate something bad about that project.

1 Like

These are good points. My related workflow here is to do experiments, live, in chrome devtools (which has the best hinting I’ve seen) and then to encode the winning combinations in garden where they’re efficiently expressed (and able to be normalized in terms of variables and media queries and such)

Not trying to hard sell you or anything (:

+1 for plain Tailwind. Works great. I often use the standalone executable which makes it so you don’t have to bring NPM into your project if you’re not already using it.

1 Like

We still use TailwindCSS. Copying and adapting components from TailwindUI saves an incredible amount of time.

Check out the ui lib I’m using - Native Components. The colors are deliberately ugly but are pretty easy to theme.

React Native/React is nice because styles are objects not strings and there are additional ways customise a page like with inbuilt object based Stylesheets. Tailwind gives you all the easy stuff but certain effects are hard to do period - ie animations and transitions. Plus, it’s Sass based so it’s slow as S#%^. Garden is ok. I agree with @kees about the tooling - probably easier to write css.

The main problem with web dev is to be able to write the code to see what that code is doing straight away. That’s the pain point and I don’t think anyone has solved it yet in a good way.

Using plain objects as styles is actually worse that using strings for everything but very simple styles. There are two problems with this approach:

  1. CSS rules are ordered, with later declarations taking precedence over earlier ones. Objects of course are unordered.
  2. When you need to include multiple CSS declarations with the same property name, which is perfectly valid in CSS, you can’t do that using objects since they only permit unique keys.

Now when you don’t need either of these, using objects is fine, but I’ve run into this problem too many times with React. Another thing I’ve found is that in an attempt to be clever, React rewrites styles declarations, and doesn’t bother to give you any way to override this behaviour. I once spent hours debugging an issue of this nature concerning borders.

well don’t try to be clever then. like i said before, css is too powerful and people should just not use it for certain things - for example, inheritence, or just be extremely careful with it.

when you rely on a framework, you have know the rules of the framework and the css. what if the framework changes? what if you switch to a different framework?

css is hard enough without everything else crudding it. I don’t think there’s anything controversial about saying, “you should style the component in the place where you use it” - which is inlining.

what if you want to develope for desktop? yoga? mobile? what if tailwind versions are not maintained between those platforms?

i’m pretty sure tailwind advocates just don’t know flexbox. people should just learn flexblox. It’s really easy to just say… I’ve had success with X. I want to hear about the failures.

1 Like

Like all software css breaks down into two sometimes competing categories imo:

Composability and performance.

Css proper offers a host of adhoc mangled awful tools for composability and your better off letting clojure handle it. Just inline what can be inlined using a good clojure to css tool.

Shadow-css is sort of an example of this. There are also other css in js solutions.

Once you actually have a perf issue, you can look at why and maybe use more raw css tools. Hell maybe ai will do it for you…

Thanks everyone,

I find myself now in favour of two approaches. One, to use Tailwind via shadow-css. Two, to inline styles using Garden. (Maybe a combination of the two.)

As to why I don’t want to use Tailwind directly, I can’t offer a good argument for why not, but it’s rather like I want to dip my toes into the pool of what Tailwind provides, but not to get in too deep with it.

And a note on the topic of inlining styles, I think @zcaudate captured my thoughts exactly:

I would argue that css allows too much to be done and people should restrict its use to styling only and simple layouts

More powerful features like pseudo-selectors and media queries are better controlled programmatically, rather than through css.

Thanks again!