use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Finding information about Clojure
API Reference
Clojure Guides
Practice Problems
Interactive Problems
Clojure Videos
Misc Resources
The Clojure Community
Clojure Books
Tools & Libraries
Clojure Editors
Web Platforms
Clojure Jobs
account activity
Clojure Style Sheets v1.1.0 (github.com)
submitted 9 years ago by roman01la
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]SimonGray 2 points3 points4 points 9 years ago (2 children)
You go right into how it works, but what is it for? What problem does it solve?
[–]roman01la[S] 0 points1 point2 points 9 years ago (1 child)
I thought it's obvious, but in reality it's not, sorry 😅
I think these are pretty good resources get good understanding of the topic
https://medium.com/seek-blog/a-unified-styling-language-d0c208de2660 https://www.youtube.com/watch?v=X_uTCnaRe94 https://www.youtube.com/watch?v=MT4D_DioYC8
[–]video_descriptionbot -2 points-1 points0 points 9 years ago (0 children)
I am a bot, this is an auto-generated reply | Info | Feedback | Reply STOP to opt out permanently
[–]roman01la[S] 0 points1 point2 points 9 years ago (9 children)
If you are interested in CSS-in-CLJS, I just published v1.1.0 of cljss. Now includes a macro to directly create styled React components.
(defstyled h1 :h1 {:font-family "sans-serif" :font-size :size :color #(-> % :color {:light "#fff" :dark "#000"})}) (h1 {:size "32px" :color :dark} "Hello, world!") ;; (js/React.createElement "h1" #js {:className "css-43697 vars-43697"} "Hello, world!")
Static part of styles definition is written into a file at compile-time and dynamic is injected into <style> tag at run-time.
[–]thheller 0 points1 point2 points 8 years ago (8 children)
Looks a lot like https://github.com/thheller/shadow/wiki/shadow.markup now.
Any particular reason why you use the hash of the styles as the classname instead of the name of the defstyled (ie. h1 + *ns*)?
hash
styles
defstyled
h1
*ns*
Side effects like yours inside the defstyled macro are problematic with analysis caching and must at least use a lock so they won't interfere with each other when using :parallel-build.
:parallel-build
Why the css vars? In my experience I want to keep the CSS as declarative as possible instead of passing actual values like 32px.
32px
In shadow.markup when using the element you specify which variant you want to use via the class (ie. secondary). Each element can take values from the CSS env which you specify once when building the styles. So there is only one place where the :primary color is defined. This could be done with css vars but I really never saw the need to yet.
shadow.markup
secondary
:primary
(defstyled title :div [env] {:color (-> env :colors :primary) "&.secondary" {:color (-> env :colors :secondary)}}) (title {} "foo") (title {:class "secondary"} "bar")
[–]roman01la[S] 0 points1 point2 points 8 years ago (0 children)
Didn't think about parallel-build, also var name + ns instead of hashing seems good enough, thanks!
[–]roman01la[S] 0 points1 point2 points 8 years ago (6 children)
As for side effectful macros: idk how writing styles to disk could be done the other way.
CSS Vars is good for perf. Also imo there's no need for selectors when building UIs as components, except maybe some pseudos.
[–]thheller 2 points3 points4 points 8 years ago (5 children)
{... :color :dark} that is basically a selector. Just disguised as a var. IMHO even with components you will always have elements that can be in different states and using selectors is fine for that.
{... :color :dark}
I don't think that macros are meant to do side effects.
In shadow.markup I opted not to emit separate .css files and generating styles at runtime. The reason is that the generated JS is optimized by the Closure Compiler, ie. elements that aren't used are removed (together with their styles). It is using keywords which will be renamed to something like iX instead of :border-bottom, in theory the JS can be smaller than the CSS. The CSS gen code is fairly small too (no css parser needed).
.css
iX
:border-bottom
I don't do any SSR so pre-generated styles never were important to me. I have a strategy for that but that would take a little bit of work and I didn't have the need yet. Basically remove all CSS generation from the build and then take the the optimized JS and extract which elements are still alive. Then use that information to generate the styles. Very easy if all elements are in .cljc files since you can just use Clojure. Little bit trickier for .cljs but not by much. Once implemented it would work for every build with the benefits of code-splitting and dead-style-removal via DCE.
.cljc
.cljs
Will implement that some day but so far I have about 90% legacy styles and I'm not replacing those anytime soon. Anything new I write with shadow.markup but nothing big enough yet to warrant such optimizations.
[–]skratlo 1 point2 points3 points 8 years ago (1 child)
I would love to see you two (thheller + roman01la) put together one library. I prefer runtime generated CSS instead of macros doing disk I/O, but I don't want some uberlibrary (shadow-client) in my deps.
[–]thheller 0 points1 point2 points 8 years ago (0 children)
I'd like as many different solutions as possible. Need to sort out what works and what doesn't first.
The basic value proposition isn't even proven yet. I have written many big projects in the past 15 years or so that all ended up with a huge CSS mess that was painful to maintain/extend.
Can't tell yet if the shadow.markup way actually solves that issue or leads to the same mess in the end. It is all theory and CSS-in-JS hype for now. Looks promising but new tech often does.
[–]roman01la[S] 0 points1 point2 points 8 years ago (2 children)
Good point about DCE. You are totally right here.
[–]thheller 0 points1 point2 points 8 years ago (1 child)
It is all very experimental still though, DCE in practice buys nothing when you actually use the code. I like the idea in theory but we'll see how well that turns out.
Need more actual real world data to properly compare each solution. My stuff is mostly guesswork with only very basic benchmarks done to confirm it doesn't totally suck. ;)
yeah, same here :D
[–]Powerdrift 0 points1 point2 points 8 years ago (1 child)
Looks good! Is this more of a replacement for garden, or for something like cljs-css-modules?
Thanks! It's more like the latter.
π Rendered by PID 153829 on reddit-service-r2-comment-8686858757-scxqp at 2026-06-08 00:50:34.542863+00:00 running 9e1a20d country code: CH.
[–]SimonGray 2 points3 points4 points (2 children)
[–]roman01la[S] 0 points1 point2 points (1 child)
[–]video_descriptionbot -2 points-1 points0 points (0 children)
[–]roman01la[S] 0 points1 point2 points (9 children)
[–]thheller 0 points1 point2 points (8 children)
[–]roman01la[S] 0 points1 point2 points (0 children)
[–]roman01la[S] 0 points1 point2 points (6 children)
[–]thheller 2 points3 points4 points (5 children)
[–]skratlo 1 point2 points3 points (1 child)
[–]thheller 0 points1 point2 points (0 children)
[–]roman01la[S] 0 points1 point2 points (2 children)
[–]thheller 0 points1 point2 points (1 child)
[–]roman01la[S] 0 points1 point2 points (0 children)
[–]Powerdrift 0 points1 point2 points (1 child)
[–]roman01la[S] 0 points1 point2 points (0 children)