Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Atomic Styles #126

Open
groundedsage opened this issue Dec 25, 2016 · 13 comments
Open

Atomic Styles #126

groundedsage opened this issue Dec 25, 2016 · 13 comments

Comments

@groundedsage
Copy link

I stumbled onto this project the other day and think it would be a perfect fit for the Garden ecosystem. It would be great to optionally have styles turned into atomic styles as a performance optimisation.

https://ryantsao.com/blog/virtual-css-with-styletron

My programming chops are still maturing but if there is any low hanging fruit that can bring this into being I am willing to have a crack at it.

@noprompt
Copy link
Owner

noprompt commented Jan 5, 2017

This was brought up in the garden slack channel on Clojurians. The v2.0.0 branch (see #123), once merged, will expose a CSS AST which can be manipulated using the stock Clojure library which means this kind of thing should be doable in a clean way. I'm still on the fence as to whether or not Garden should be responsible for doing any kind of heavy optimization though.

@WorldsEndless
Copy link
Collaborator

WorldsEndless commented Jan 5, 2017

If anyone can think of a way for garden to have add-ons or plugins of its own, heavy optimization would be one great (optional) feature, as would elaborate style cljs (e.g. #113)

@groundedsage
Copy link
Author

Yea that would be awesome. Garden would then essentially become the PostCSS of the Clojureverse

@groundedsage
Copy link
Author

Cross referencing
https://gist.github.com/rauhs/ac6349dd20f1799982a1906f9a59e7d6

@groundedsage
Copy link
Author

So Styletron is marketed as a low level API and other CSS in JS solutions seem to be either wrapped over it or planning to wrap over it. I'm just wondering whether it would be best to wrap it. Seems like it will be a lot easier now. https://twitter.com/swannodette/status/823897912514146304

What do people think? I'm prepared to put some serious time into something like this but I want my time to be spent on an official solution that integrates nicely with Garden.

@brancusi
Copy link

brancusi commented Feb 3, 2017

@groundedsage that would be really excellent!

@noprompt
Copy link
Owner

What's in #123 would allow this. I simply need help getting it over the finish line. I've been busy with work and family life and haven't been able to finish it up.

Perhaps I should schedule a hang out or something like that to get others involved. The slack channel and these GH threads seem like a pretty poor places to educate folks on the code and how to get involved.

@groundedsage
Copy link
Author

@noprompt yea a Google Hangout would be good. The format might need to be like a mini workshop or run through of everything and pointing out the key areas where you need help.

I've been busy as well.

@azizzaeny
Copy link

azizzaeny commented Mar 21, 2017

@groundedsage

i just see your gist... thats awesome... see my challanges section in boot-atomizer

ya agree garden to replace PostCSS

i think we have common problem...
trying to improve expressiveness design and Developer experiences

1.use atomic classNames and css-shorthand
2.use macros to generate something
3.use vector or single entry-maps for css-shorthad

in garden use vector

[.h1 {:font-weight :bold} ]

how about writing like this?

{:font-weight "bold"} 
; just
{:bold } 

; key-values?  
{:padding "10px"}
{:border "1px solid red"}

;auto generating clasess
[.bold {:font-weight "bold"}]

styletron still generating names for classnames, thats bring pros and cons
pros: smaller size
cons: reuse globally
see atomic css not generating others names use the sames

(defn component []
  [:div {:class "T(10px) P(1.6em) Translate(50%)"])

100% reuse..

@groundedsage
Copy link
Author

groundedsage commented Mar 21, 2017

All credit goes to https://gist.github.com/rauhs/ac6349dd20f1799982a1906f9a59e7d6
I'm just working to have it work for my specific use cases and work with Boot.

I personally prefer having a 1 to 1 mapping when using css as it makes it easier to translate and interpret the code. It does bulk out the components a lot and requires more typing. But I find it to be less of a load on the brain to remember the mappings of class names to styles. It also means no work needs to be done to maintain the external mapping of class names or keep up with the spec.

[:img {:class [(css {:width "5rem"
                                :height "5rem"
                                :margin-right "2rem"
                                :margin-top "1rem"})]

           :src "photos/meetup-logo.png"}] 

There is a lot of circumstances where CSS shorthand shouldn't be used. So I often opt for using longhand. It also helps with code readability again. https://csswizardry.com/2016/12/css-shorthand-syntax-considered-an-anti-pattern/

For the purpose of code-reuse. I generally just define my styles elsewhere and then reuse with a symbol. Like this here.

(def meetup-text [(css {:flex-direction "row"
                                          :flex-wrap "wrap"})])

Say I was going to use this with the component above as an example. Along with some normal styles from a traditional CSS file.

  [:img {:class ["normal-styles"
                              meetup-text
                             (css {:width "5rem"
                                      :height "5rem"
                                      :margin-right "2rem"
                                      :margin-top "1rem"})]
           :src "photos/meetup-logo.png"}] 

The only downside of this current implementation is that it is a macro. Meaning I can't use say brand-color inside the (css ....) I could define these as mentioned above but I may want to use the brand-color for various things such as background-color, border-color, font-color etc etc. I also can't use any clojure or garden functions inside the macro so I can't do something like (lighten brand-color 20)

@groundedsage
Copy link
Author

groundedsage commented Mar 22, 2017

Not sure how to actually format the code like normal clojure code in here...

Other additional considerations.

  • It would be cool to get all the above the fold content easily and inject that into the head.
  • Optimising the rendering could be done as well by ensuring all the layout styles are at the top of the CSS output.
  • Since garden is in CLJS it may be possible to make the atomic styles like Styletron super dynamic and even work without using React?
  • The styles can easily be injected into the head for making AMP (if people are making AMP sites). Which restricts the inline styles on head to 50kb??

@azizzaeny
Copy link

i think your approach is also good...
we can compose those maps by making it outide of component...

(def small (css {:width "5rem"}]))
[:img {:class small }]

use specs like gamma :

(def spec {
   :smaller (css {:width "5rem"})
   :shadow (css {...))

[:img {:class (:smaller spec)]

or better instead calling css every component make single api and call onces

(def spec-tree {
   :smaller {:width "5rem"}
   :shadow {...}})

[:img {:class (:smaller spec-tree)]

; and render it 
(->
  (css spec-tree)
  (append-to-head) ; AMP styles OR PWA initial render offline
  (render-dom))

theming is done by spec macro api..

shorthands is anti pattern everywhere for those who write css
even atomic css say it...

but we are using macros to generate string of string clj-string -> clj-string -> (process) -> css stuf
postcss-shorthand is generating css directly
my plan in atomizer

size(20,5/2) 

expanded to

w(20) h(5/2)

not direct css
ya it is still poblem bring bloated but trade off simplicity...

instead clojure data strcuture, composing simple string is cool too...
we can type it with close eyes... ☺️

(defn component []
  (let [space "P(1.6em)"
        move  "T(10px) Translate(50%)"]
    [:div {:class (str space move)}]))

@azizzaeny
Copy link

@groundedsage Use clj or cljs to format clojure(script)

  ``clj 
   ...
  ``

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants