Current | Inline Styles | 'Utility First' CSS | Garden CSS | Garden 'CSS in [CL]JS' | |
---|---|---|---|---|---|
Removes |
✗ |
✓ |
✗ |
✓ |
✓ |
Reverses CSS→DOM Dep |
✗ |
✓ |
✓ |
✗ |
✓ |
Composable |
✗ |
✓ |
✓ |
✗ |
✓ |
'Pruning' not Required |
✓ |
✓ |
✗ |
✓ |
✓ |
Styles as Data |
✗ |
✓ |
✗ |
✓ |
✓ |
Styles in Namespace |
✗ |
✓ |
✓ |
✓ |
✓ |
Styles near Component |
✗ |
✓ |
✓ |
✗ |
✓ |
Stateful Styling |
✗ |
✓ |
✓ |
✗ |
✓ |
Turn Off Default Styles |
✓ |
✗ |
✗ |
✓ |
✓ |
Modularity |
✗ |
✓ |
✗ |
✗ |
✓ |
Full Power of CSS |
✓ |
✗ |
✗ |
✓ |
✓ |
Performant |
✓ |
✗ |
✓ |
✓ |
✓ |
Score |
4/12 |
9/12 |
6/12 |
7/12 |
12/12 |
Percent |
33% |
75% |
50% |
58% |
100% |
Last active
February 11, 2021 22:08
-
-
Save superstructor/7ef7e5a80553e7abdee33bd73825da05 to your computer and use it in GitHub Desktop.
re-com-css
- Reversal of dependency of CSS-on-DOM to DOM-on-CSS ('utility first' inspired)
- Co-location of styling with CLJS (again, 'utility first' inspired which achieves this via class naming)
- Modularity between components and seperation of concerns (i.e. datepicker styles won't impact input-text styles)
- Re-usability of common styles
- Performance (e.g. in v-table, scrolling 1-million rows)
- way to turn off default styles - day8/re-com#51
- way to inject 'utility first' classes for stateful things; e.g. :parts {:next-year:hover ... :next-year:disabled...
- way to transform/replace styles without passing per-component instance args (aka theming, or 'changing default colours') - day8/re-com#123
E.g. https://tachyons.io/, https://tailwindcss.com/
Advantages:
- pre-made libraries
- composable
- reversal of CSS->DOM depenedency
- easy to implement
Disadvantages:
- not possible to run pruning tools to remove unused classes from CSS when using hiccup embedded in CLJS, tooling is built for the vanilla-JS world.
- readability can be poor.
- limits flexibility or power of CSS. E.g. https://www.npmjs.com/package/tailwindcss-grid even says
It's not really practical to expose all of the power of CSS Grid through utilities, but this plugin is a good example of using CSS Grid to replace a cell-only float or Flexbox grid.
- you end up using a mix of full CSS and 'utility first' anyway, aka 'utility last' is always the end game of 'utility first' then we come back to the same problem we are trying to solve.
- styles are not data
E.g.
(stylesheet/inject-garden-stylesheet!
[
[:.rc-datepicker-selected
:.rc-datepicker-selected:hover
{:background-color :#357ebd
:border-color :#3071a9
:color :#FFF}]])
Advantages:
- no longer shipping
re-com.css
as a seperate file - styles can be in the same namespace as code
- styles are data
- easy to turn off default styles
Disadvantages:
- styles are not truely co-located with components, can be a few hundred lines of CLJS seperation
- no modularity/seperation of concerns; Garden CSS is a global namespace
- DOM still depends on CSS (i.e. semantic classes)
E.g.
- https://github.com/dhleong/spade
- https://herb.roosta.sh/
- https://github.com/Jarzka/stylefy
- https://github.com/matthieu-beteille/cljs-css-modules
Advantages:
- no longer shipping
re-com.css
as a seperate file - styles can be in the same namespace as code
- styles are data
- co-location of styles with components
- composable
- reversal of CSS->DOM depenedency
- full power and expressiveness of CSS (via Garden)
- 'automatic' attachment of classnames to components
Spade:
(ns re-com.datepicker)
(defclass next-year-nav-style
[enabled?]
[:path
{:fill (if enabled? :#357ebd :#999)}]
[:&:hover
{:background-color :#357ebd
:cursor "pointer"}
[:path
{:fill (if enabled? :#fff :#999)}]])
(defn- next-year-nav
[& {:keys [display-month maximum disabled? parts]}]
(let [next-year-date-time (inc-year @display-month)
next-year-enabled? (if maximum (cljs-time/before? next-year-date-time maximum) true)]
(when (not disabled?)
[:<>
[line]
[box
:class (str "rc-datepicker-next-year " (next-year-nav-style next-year-enabled?))
...]])))
Herb:
Fail. Not possible to implement the box:hover
style on the svg/path child of the box. It does have ^{:pseudo {:hover {:fill ...
but this could only be applied as path:hover {:fill ...
(as we want to fill the path) NOT box:hover path {:fill ...
which limits the interactive area for the user's pointer.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment