My Garden CSS has ascended | Tech.ToryAnderson.com

5 Likes

Hi,

Nice article! I just didn’t understand how the article function and the mount-style interect with each other.

On another topic, recently I bootstrap a ClojureScript website and when dealing with style, after some research we decided to follow with Emotion, which does something similar with what you are trying to do. It creates a style tag in the head as styles are defined. But it focus more on scoping these styles. But the integration is not transparent – for example, css properties must be camel-case, since it was done for JavaScript.

It would be nice to have something more clojure-like to use.

1 Like

I enjoyed your DIY attitude! This sounds like styled components in JS land, but without much of the baggage.

1 Like

Thanks for the feedback! I’ll update to clarify: article generates the css string that is the arg to mount-style.

For me this completes the functional Clojure-ness of CSS (thanks Garden).

I’ve been struggling with css in clojurescript adopting inline css. Yesterday I managed a nice workflow with Custom Elements (Web Components), so I’ll try to use the <style> as they will be scoped to the component. I’m thinking to adopt garden to use clojure syntax for css.

I strongly recommend Garden. It’s pretty sweet; I’ve been using it for years. What is it you’re adopting right now? Injected CSS at the [:header [:style]] or inline at the [:element {:style...}] level?

Like this… and I’m probably being judged because of it. Apparently it’s an heresy for web dev.

Not heresy at all; this is the way that many web app devs like it, such as with React.js. However, I dislike it because it undermines the purpose of the “cascade” and also conflates content with presentation. Note that if you are doing it that way, you probably don’t need Garden since [:div {:style {:background-color "#DFE"}}] works fine without Garden; reagent takes care of that for you.

Yes, this is why I wasn’t using until now, but as I said I’ll start working with custom-elements, so I’m planning to create structures like

(defn user-component []                                                            
  [:<>                                                                             
   [:style                                                                         
    "p {color: gray}"] ;; scoped style                                             
   [user-name]                                                                     
   [user-profile]])                                                                
(util/define-custom-element! "user-component" user-component)                      
                                                                                   
(defn view []                                                                      
  [:user-component])

and would be nice to avoid css as string, if I’m not wrong I can replace "p {color: gray}" with (css [:p {:color "gray"}]), right?

with inline styles you need to remember these go beneath the style element on a dom thing. [:p {:style {:color "gray"}}] (this is just how html works)

Hum, doing my first ClojureScript web project right now. Am a noob at HTML/CSS/JS/REACT.

I faced this issue really quickly. It seems what I want is scoped css just like this article describes: https://css-tricks.com/saving-the-day-with-scoped-css/ except it sounds like it was not implemented by browsers. So I’m hoping to find a ClojureScript implementation of it.

I’m using rum for example, and would want to be able to just do:

(rum/defc my-comp
  []
  (Style
    [:h1 {:color :red}
     :div {:width "10px"}]
  [:h1 "Hello"
    [:div "wtv"]]))

Something like that, and the styling would apply only within the scope of Style, or at least something which would let me do it within the scope of defc.

The best I found for now is using cljss. The issue here is it doesn’t cascade like you said, its just one step above using inline styles. But if I want the same style on many elements of the same type, like on all my divs, I need to keep re-using it over and over.

I’m surprised I haven’t found something like that already, and honestly, wonder if I am missing some important consideration for why no one did this, and why cljss works at the element level only.

1 Like

Apparently they moved from <style scoped> to shadow-dom. I recommend the following links, they might help as helped me.

1 Like

Hum, that’s interesting. Do you even need React anymore if you have shadow dom? Each component can just be a shadow dom, and you can just update its tree whenever no?

Or at least, React would seem less useful, since mutating a component’s tree seems less trouble than mutating the whole dom. So I feel if all your components were shadow dom they’d still be nicely encapsulated.

I guess React could still be used to have virtual shadow doms and diff the parts of the shadow dom tree for change and only re-render those.

I think it’s more up to framework devs to decide what makes sense to user. I used to use Polymer before using clojurescript and I think Vuejs also use web components. I didn’t like react because it changes the nature of html. I don’t mind using Reagent because it abstract the React specificity very well.

I’d be careful in using web components every where. The cljs community adopt React and if you decide to swim against the flow you could have little infra structure or help. I’m more concerned in being able to use public components regardless if they are defined in React, Vuejs, Polymer or vanilla web component.

Take a look at react view about web components https://reactjs.org/docs/web-components.html

So, I’ve used cljss some more, and it looks like it does pretty much everything I want. For example one can do:

(ns hello-world
  (:require [rum.core :as rum]
            [cljss.core :as css]
            [cljss.rum])
  (:require-macros [cljss.rum :as css]))

(css/defstyled hello-world-styled :div
  {"h1" {:color "red"}
   "p" {:color "blue"}
   "h2" {:color "green"}})

(rum/defc hello-world
  []
  (hello-world-styled
   {}
   "Hello World!"
   [:h1 "This will be red"]
   [:p "This will be blue"]
   [:h2 "This will be green"]))

(css/remove-styles!)
(rum/mount (hello-world) (js/document.getElementById "app"))

It also offers a defstyled for reagent and om if you prefer those over rum. And the defstyled is just a convenience, as it offers a defstyles macro as well which you can use in which case the above just becomes:

(ns hello-world
  (:require [rum.core :as rum]
            [cljss.core :as css]))

(css/defstyles hello-world-styles
  []
  {"h1" {:color "red"}
   "p" {:color "blue"}
   "h2" {:color "green"}})

(rum/defc hello-world
  []
  [:div {:class (hello-world-styles)}
   "Hello World!"
   [:h1 "This will be red"]
   [:p "This will be blue"]
   [:h2 "This will be green"]])

(css/remove-styles!)
(rum/mount (hello-world) (js/document.getElementById "app"))

So this is pretty much exactly what I wanted.

2 Likes

Hey All!

I’m new to clojureverse and just saw this thread.

I recently created a cljs wrapper for emotion which may be of interest to you:

and made a walkthrough of the API in devcards:
https://dvingo.github.io/cljs-emotion/#!/dv.cljs_emotion.devcards

feel free to try it out and provide any feedback :slight_smile:

1 Like

Very nice. I like how you’ve used devcards as a demonstration method; that’s new to me. I’m not familiar with emotion. From a brief look into your and its links, it looks like the most immediate business propositions are that it does automatic vendor prefixing, and has nice keyframe support. I’m sure this is a shallow perspective; what do you see as emotion’s main selling points?

I’m really liking devcards, plus it makes it super easy to publish with any static site app (like github pages).

The selling points for emotion are the same for any css-in-js libs.
I was using styled-components before emotion and only switched because emotion
supports object styles everywhere (including animations) and supports server side rendering (on node.js) without needing a babel plugin, which styled-components requires.

Max Stoiber, and Glen Maddern who created styled-components, have plenty of talks about the benefits of this approach on application architecture: