
State of React and CSS - cjr
https://voice.kadira.io/state-of-react-and-css-501d179443d3#.fwn72ng1r
======
madeofpalk
I find it very hard to understand what these CSS-in-JS libraries are for, and
how anyone can be happy with them. They're all extremely leaky abstractions
for what's mostly a 'solved problem' \- how do I style something.

What's wrong with just "plain old CSS" with whatsoever pre processor you
choose? If you're working in a larger project and what to completely
modularise your styles, throw in CSS Modules.

I think this over complicated approach by overloading the style attribute, and
then figuring out how to do :hover is just too much snd is partly what others
point to and laugh when they talk about "JS Fatigue"

Edit: Look, I love React. We just build a reasonably large site with it using
some fairly novel and modern approaches to how to make a website. I have
absolutely zero sympathy for this self-imposed JS Fatigue that was all the
hotness 3 months ago. But using a convoluted system like Radium is just
begging for the JS Fatigue crew to point and laugh at you.

~~~
madeofpalk
On a bit more of a positive note, I highly encourage people to check out CSS
Modules. It introduces name mangling to CSS so you get 'locally' scoped CSS
classes which you use by 'importing' them in your view component.

It's 'compatible' with any preprocessor, because it's working on the CSS
itself. I think the cool thing about CSS Modules is that it makes BEM obsolete
- that naming pattern is now essentially enforce at 'compile-time'.

Check out this article for more info [http://glenmaddern.com/articles/css-
modules](http://glenmaddern.com/articles/css-modules)

~~~
cnp
I was using Radium for a while, but switched to CSS-Modules and never looked
back once. Its so much nicer, and you get to keep everything that CSS already
has, including a sane _readable_ dom and the ability to inspect elements (not
possible with inline-styles when your output is all `style={...huge giant
mess...}`). On top of that you still get to use your favorite CSS preprocessor
if thats your thing. There's no comparison IMO. CSS Modules fix the scoping
issues, and `composes: otherStyle` fixes the rest.

~~~
exogen
AFAIK Radium actually no longer generates inline `style={...}` attributes but
`<style>`s at the appropriate places instead.

------
simonw
"Frontend developers don’t usually worry too much about CSS"

"Core developers build some core JavaScript tools/libraries and focus on non-
UI stuff. CSS is something they don’t need to worry about."

If you work professionally with frontend code, you damn well better have a
deep understanding of CSS. The fact that so many developers who work with
browsers don't have this is a major contributing factor to the terrible
bloated state of so many modern websites and applications.

Learn your tools, people!

~~~
collyw
I already know Java, Perl, Python, HTML, enough JavaScript to get things done.
Linux server setup, AWS, Rackspace, Relational Databases, enough NoSQL to know
its worth leaving until a problem demands it. I also know Git, Django, tons of
Django related packages, Eclipse....

I only want to move the button a few pixels to the right. And now I don't know
enough tools?

~~~
visarga
> I only want to move the button a few pixels to the right.

On mobile or on desktop? At what resolution/pixel density? Does this button
need to be placed differently when the phone orientation changes? CSS is weird
because it tries to solve a lot of problems, not just placing things a few
pixels to the right. For that you can use absolute positioning with each
element, if you want that level of control, and it's simple.

------
spankalee
All these abstractions over CSS seem way to complicated and many way to far
from the browser to me.

With Shadow DOM style scoping, CSS custom properties and @apply mixins all
coming very soon, most of the problems of composable, reusable styling, and
even theming, will have great native solutions.

I'd like to see more focus on reusable polyfills than trying to divert around
CSS. Polymer supports all three of those now, but they're pretty tightly
integrated so other frameworks can't use them so easily yet.

------
acjohnson55
I've never worked on a team where the front-end developers don't have to worry
about CSS. Everywhere I've worked, designs produce assets and redlined mocks,
and it's up to front-end devs to figure out how to execute the design. I've
never worked with a designer I've known to have an in-depth understanding of
CSS. So, from my perspective, embedding CSS in the logic makes a lot of sense.

------
fuzionmonkey
A very comprehensive list of CSS-in-JS libraries with code examples is
maintained here: [https://github.com/MicheleBertoli/css-in-
js](https://github.com/MicheleBertoli/css-in-js) for folks who are interested.

My personal favorite:
[https://github.com/rtsao/csjs](https://github.com/rtsao/csjs)

------
bung
Sort of tangential, I'm curious about your internal process with this kind of
workflow. After you have a new design approved the next milestone is just
"here's the app"?

We like to have our junior guys build the "HTML": HTML, LESS/SASS (BEM/SMACSS
concepts), JS, Responsive, and cross-browser tested, which we can then review
and approve and build the project.

For those of you doing this kind of workflow, building CSS while building
components, you just review it all together once the whole thing is done?
Which is not a risk as everything is "scoped" or "componentized"?

(We do mostly websites not apps, if it matters.)

------
rvdm
Another great article! The Kadira team is on fire.

I have been working on a descent sized React.js commerce platform. While I was
able to get past writing HTML tags that should be as simple as

<div>Product</div>

using this instead

React.createElement(

    
    
      'div'
    
      {},
    
      'Product'
    

);

I could justify this overhead in development time and effort because of
React's obvious advantages ( Universal rendering!! ).

However when I started adding in styles using Radium I found myself more
frustrated than delighted. There are a lot of situations where writing styles
in javascript becomes very inelegant very quickly. While basic CSS is far from
perfect, I genuinely felt like I took a step back with Radium and reverted
back to the legacy CSS stylesheets I had from our previous iteration.

I do have to note the version of Radium I was using inlined all the styles, I
do like the new approach Radium is using a lot better, however I'll likely end
up converting my legacy CSS to CSS modules, which has my winning vote for the
moment as well.

Thank you for opening up the conversation here. All things considered I'm
still not sure if CSS modules are really the holy grail. Curious to see what
the future will bring for CSS + JS.

------
renke1
Personally, I am using CSS Modules with Less as preprocessor, mostly because
of constants, color functions and the occasional mixin.

I resort to inline styles and sometimes Radium when I deal with highly dynamic
styles, usually sizing and positioning for things like popups.

While I like inline styles in general, the editor support is a bit lacking
compared to working with Less files.

------
acbabis
> Frontend developers don’t usually worry too much about CSS. They mostly care
> about the application’s functionality and the layout of the app.

Whether or not frontend developers do a lot of CSS depends on the skills of
the team. Companies prefer to hire candidates with design knowledge _and_
coding knowledge, but a lot of the time those end up being separate roles. I'm
a frontend developer and I write a lot of CSS.

What the author calls a "UI Designer", I would call a "UI Developer".

~~~
enraged_camel
To me, a UI Designer is someone who is mostly concerned with look & feel and
aesthetics, whereas a UI Developer is concerned with behavior and
interactions. The former focuses on CSS, colors and graphics whereas the
latter focuses on JavaScript. There is obviously overlap but the two roles
tend to be very distinct.

------
abritinthebay
There's yet to be a CSS-in-JS library that is

* loads the styles before the content or markup

* as fast or faster than CSS

* able to have the power of modularized CSS preprocessors for reducing complex styles

* worth the effort.

I'm not against the _idea_ but practically every single instance it comes up
it feels like programmers who don't get CSS trying to write something in what
they DO understand that handles CSS so they don't have to.

That's fine, and useful, but lets not pretend it's _better_.

~~~
fuzionmonkey
This is simply not true. Many CSS-in-JS libraries support build or render-time
extraction of CSS, which takes care of your first criterion.

Many CSS-in-JS libraries also handle style modularization, often in ways
arguably better than CSS preprocessors. There's a lot of variety here.

I'm not sure what you mean by "faster than CSS". CSS can be fast or slow,
depending on how the CSS is written.

You should take a look at: [https://github.com/MicheleBertoli/css-in-
js](https://github.com/MicheleBertoli/css-in-js)

~~~
abritinthebay
> build or render-time extraction of CSS

Render-time is waaaay too late. The ship has sailed at that point: so no, that
doesn't take care of your first point.

> Many CSS-in-JS libraries also handle style modularization, often in ways
> arguably better than CSS preprocessors.

I've yet to see one that comes even close to SASS - not even the same game let
alone the same league - so agree to disagree here.

> You should take a look at: [https://github.com/MicheleBertoli/css-in-
> js](https://github.com/MicheleBertoli/css-in-js)

I have - all it shows is that css-in-js is not a realistic competition for
sensible modular CSS via something like SASS (CSS Modules, etc, good
patterns).

~~~
tobz
Can you explain your rationale on the first point WRT render time being
"waaaay too late"?

If your app is rendered via JS, having the CSS loaded at runtime should not
matter: there's no markup to affect (repaint) and the CSS will be available
before your React/etc components are rendered up.

~~~
abritinthebay
> if your app is rendered by JS

only if it's pure browser-side only. Which is fine I guess - at that point
you've given up on rendering performance anyhow generally (especially in
initial paint).

~~~
izym
How about server-side rendering?

~~~
abritinthebay
Well that that point it's slower to paint with CSS-in-JS because the browser
won't have the CSS until the very last thing (after asset load, after initial
paint, after content load, then after script execution).

Now you _could_ extract the CSS with a build step... but at that point you've
admitted the solution is poor (and/or you're not good at CSS) and are just
mitigating it by producing _real_ CSS by automation.

That's fine, but it's no replacement for general good practice or domain
knowledge.

~~~
izym
Do you have any proof that it's slower or is it just an assumption?

------
kuon
My problem with CSS-in-JS is that I have big part of my app which is not react
based.

So I have to style slim/erb templates and react components in a coherent and
manageable way.

The current thing I use is reasonable css from rscss.io but I still have a
feeling of "disconnection" between templates/components and css.

------
stevepotter
For me, using css classes in a css file has worked fine for reusable
components. For isolation, the root element of the component has a class name
like class="supermenu". What are the disadvantages of this as opposed to the
intricate toolchains being popularized along with React?

~~~
Kiro
Say you have .supermenu .button. What happens if a global .button class enters
the picture? The root class is good for preventing leaks but offers no
protection.

~~~
stevepotter
Good point. How about .supermenu-button?

~~~
tlrobinson
This is basically what the BEM (block, element, modifier) convention is.

BTW, CSS modules essentially automate and enforce BEM. Each component's CSS
file can have a ".button" class that doesn't conflict with any other ".button"
on the page because they're automatically name-mangled
([https://en.wikipedia.org/wiki/Name_mangling](https://en.wikipedia.org/wiki/Name_mangling)).
Then in your React code you do something like

    
    
        import styles from "./supermenu.css"
    
        SuperMenu = ({}) =>
          <div className={styles.supermenu}>
            <button className={styles.button}>Foo</button>
          </div>
    

Or use something like react-css-modules to make it a little less verbose:
[https://github.com/gajus/react-css-modules](https://github.com/gajus/react-
css-modules)

I'm not totally sold on this approach though. You lose some of the benefits of
CSS, like theming.

------
gsmethells
What happened to division of labor? Progressive enhancement? Mixing CSS into
JS is just muddying the water.

------
TheAceOfHearts
I think we're still in the heavy exploration phase with styles. It reminds me
of the explosion of flux frameworks until we finally settled on redux. I'm
really hopeful that React will just pick a winner, and the community will
stand behind em. In the react-future repo they also have some interesting
ideas for taking on layout, which might be an exciting change.

In any case, I think CSS modules are still lacking. I've been using css
modules for the last few months, and although I love using em, it still feels
like it has a long way to go. With that said, I do think that CSS modules are
probably the best general-purpose solution that we have so far (i.e. they work
for the largest number of scenarios).

My first problem with css modules was the lack of value types. This is really
important for stuff like colors, where you wanna declare a single color value
and use it in multiple attributes (background-color, border-color, border-top-
color, etc). To tackle that they eventually added module values [0]. Yay!
Except that it doesn't work for attributes with commas (i.e. shadows), nor
does it perform any kind of validation on the values, so typos are very likely
to pass unnoticed. :( And it doesn't play well with other PostCSS plugins.

The second problem is that they don't provide a easy / simple way to tackle
stuff like theming or one-off tweaks. I'm not a fan of Polymer, but that's one
of the few things that I think they've gotten right. Check out the paper-tabs
element [1]. They allow you to pass a css variables (--paper-tabs-selection-
bar-color), but in case you don't pass any variable it'll use the fallback
(--paper-yellow-a100).

These aren't insurmountable issues, and you can totally work around em, but
I'd hardly consider em ideal.

I'll note one thing that I absolute LOVE about css modules and css module
values: dependencies are explicit! You import specific values from different
files, so it's very easy to see from what file each value come from. It's the
same thing with composed classes. This is actually one of my bigger issues
with Polymer: HTML imports just pollute your environment with all their junk.
You import a file without any clue of what just got pulled in! If you're
looking at a file with a handful of imports, good luck tracing where
everything came from. It makes reading Polymer code very unpleasant. On top of
that, Polymer decided to go with mixins as their composition strategy, which
is also difficult to trace... Even after the React community tried em out
something similar and eventually decided to move towards using higher order
components.

Going beyond that, our style strategies are all really hard to share with
others. If you want people to be able to use your components, you end up
falling back to global css.

React Native's Stylesheet class seems to be one of the better options for
inline styles (or more specifically, React Native Web's version). However,
it's only good for app styles. If you have a website, it's probably not a good
choice: it doesn't have any way to reset browser styles, nor does it allow you
to target plain elements. I had wanted to use React Native Web's Stylesheet
class for a website that was using React without any client-side JS (only
server-side rendering), but once I realized I'd have to pull in even more
tools to style other stuff, I dropped that idea.

I'll also note that React Native Web's Stylesheet class can be problematic in
certain apps. For example, if you receive pre-compiled HTML fragments from the
server and your only way of targeting those elements is to use nested
selectors. Normally you'd have styles that look like this: .FooBar nav h1,
.FooBar nav h2, etc. But that's not doable at the moment.

Hopefully this doesn't come off as a negative rant, because I'm actually
REALLY excited to see so much experimenting and progress being made in this
area. I have nothing but the utmost respect for all the awesome developers
that are trying out ideas left and right.

[0] [https://github.com/css-modules/postcss-modules-
values](https://github.com/css-modules/postcss-modules-values)

[1] [https://github.com/PolymerElements/paper-
tabs/blob/master/pa...](https://github.com/PolymerElements/paper-
tabs/blob/master/paper-tabs.html#L169)

