Show HN: ReactCSS – Inline Styles with Support for React, Redux and React Native
reactcss.comWhat happened to the separation of concerns between CSS and JS? In my experience most developers dont want anything to do with CSS. They want a designer who can code to do that.
IMO it makes it easier for devs that dislike CSS to make sweeping changes due to all of the relevant styles being in one place.
The React way is different and I was hesitant, but it is better. It combines the best parts of native app development with the best parts of web development, then improves on them. The old way of doing CSS was crazy and unmanageable because CSS was intended for documents. Cascading styles are useful for publications, but they are unwieldy for UI components. There aren't many native app designers clamoring for global cascading styles.
The React way of separating design concerns from logic is to build container components[1] that handle the logic and pass props down to simple components that just display the data they're given. I would expect designers to spend more time in presentational components and CSS modules[2] while developers would build container components. (I'm a one-man shop doing both.)
[1] https://medium.com/@dan_abramov/smart-and-dumb-components-7c...
> The old way of doing CSS was crazy and unmanageable.
That's a bit of a stretch though, we've had good success with using normal CSS files, included in each component with webpack CSS-loader[1]. CSS is displayed in head as needed, but without an all-JS approach like this
For that matter, it's not so hard to setup sass-loader with custom default locations... I'll usually have my own copy of bootstrap's variables.scss, a mixins.scss that points to bootstrap's... from there, I have a copy of bootstrap.scss included higher up pointing to the local mixins/variables, and the rest from the node_modules/bootstrap(-sass)/ path...
I can then, inside my component...
with the mycomponent-style.scssrequire('./mycomponent-style.scss') .... <div class="mycomponent">
And have all of bootstrap's variables/mixins to work with... I can update variables for those bits of bootstrap I want changed, components also update based on those values. It actually works really well, and it's not hard to setup.@import "variables"; @import "mixins"; .mycomponent { ... }I should really write a current article on using Bootstrap@4 from source... There's a little bit of boilerplate, but so worth it.
That said, I do appreciate the inline options, and feel that future React apps in particular should probably go in that direction. It really just depends on how you are working with.
Ultimately it depends on what your concerns are, and how you want to separate them.
I'm not just being silly either. Separation of technologies (e.g. HTML/CSS/JS) is just one of many ways of splitting things up. The component paradigm is essentially a fractal version of separating by feature. Ultimately it's an architectural choice and as such any best practices should be strictly scoped to the problems they're solving.
The reason why many of us in React-land are looking to bring everything related to a single component into one file, is maintainability and strict encapsulation. Some of this is to do with developer-experience (DX), i.e. adopt patterns that make our lives easier and ultimately minimise hard-to-fix bugs. But we're also trying to adopt patterns that benefit the user (i'll be the first to admit we're not there yet). To that end, a component architecture also makes it easier to let build tools automatically take care of the nasty problem of making sure users only download exactly what they need for what they've asked to do.
The component paradigm that react is built around is all about working with very small objects, where everything you need for that component is in one file. It's a fantastic model when you are working with a complex interface that has many components to it. It's a paradigm that needs to be managed and used carefully though, otherwise you'll end up with massive 2000 line files.
I never thought there was a separation between JS and CSS, that sounds a little outdated, to be honest. As a front-end developer, I would be expected to do JS and CSS.
Where I work, we're a small dev team of a few full stack developers and a designer. Our designer does the CSS, and the devs the JS. The separation works well enough for us. YMMV.
So anytime the designer makes a change to the structure of the application, where HTML element changes are required, do they send you a request so you can change it?
It seems odd to only allow the "designer" to manipulate properties of elements and not the elements themselves. If they are allowed to modify DOM elements then in the React world, that is manipulating JS. For us the important separation is at the component level, which includes everything that component needs to render and function (HTML, CSS, JS).
I was unclear about that part. The designer will edit the HTML also, which is outside of JS.
We are not using React.
I'd say CSS is part of a stack for a long time now.
The React ecosystem seems to be geared towards masking HTML/DOM/CSS behind Javascript/code, such as when developing mobile apps. I do not think "separation of concerns" is a priority.
(Not agreeing with this BTW, but there is a subset of developers who seem to think this is just great.)
I can go almost either way... I often find it more natural to include a (s)css file in my component's .js, and have webpack bring it in... then in the component's rendering set the className to a matching container in the scss. With scss, I can start with my variables/mixins include, and keep the more hierarchal stuff straight... It works pretty well, but I see the appeal of things like this library, aphrodite and the like.
I do exactly that too :-)
It's still separated, but they are near each other.
I personally like this way better, easier to find when need to fix something.
That bridge has already been crossed when they put the HTML into the JS. Any designer changing CSS is going to want access to the HTML, so they're already mucking in the JS anyways.
It's just a slightly different syntax for CSS but still is CSS.
This is slightly off-topic, but... this simple website is made of a single, static page without any kind of user interaction. Why does it load a 2.8 Mb javascript, and why is javascript needed to render the page at all?
First off, it's not compressed... that would probably bring it to 1/8 the size, I'm also assuming that the documentation as a project may well expand...
Usually React+Redux project min + gz will come in around 200-300KB for a relatively simple app... If you go with preact, and are really judicious in what you bring in, you can hit half that. For most people, if your initial send is under 500kb, it won't be noticed except some mobile connections.
YMMV of course, for comparison, angular apps tend to be about 50-80% bigger, and ng2 apps over twice the size. At least from my own experience and setting up a few boilerplate apps.
> Usually React+Redux project min + gz will come in around 200-300KB for a relatively simple app... If you go with preact, and are really judicious in what you bring in, you can hit half that.
What stuff are you bringing in? Preact is 3kb, Redux + bindings for Preact probably bring it around 10kb or less (compressed). Unless you mean images and stuff.
React. If it was a pretty complex and dynamic app it would be just a bit bigger.
The author either didn't do the best choice in writing his page, or has great plans for it.
Yes! The static version of the site is an in-between, with more complex documentation coming soon!
This looks like the build a typical webpack development config spits out (using its eval devtool [1]), could be that the author hasn't set up a production build yet.
[1] https://webpack.github.io/docs/configuration.html#devtool
I only see a ~800kb bundle.js, which could be smaller if minified, I think, but nothing strangely big.
The bundle is 2.8 Mb uncompressed, ~800Kb compressed.
Even if compressed and minified, that's still a huge amount of JS statements that the interpreter has to go through.
I'm getting about 2 seconds to DomContentLoaded on my iMac and a reasonably fast cable connection. Four seconds to visible content on my Nexus 5X on same connection.
This is the kind of crap that makes the web feel so lame and clunky on mobile (and on desktops too even sometimes).
For reference, it's not necessarily react or redux, or whatever else is in use... I've managed to get preact+redux in a 20k (gz) bundle for a standalone, usable component, flushing out an app may triple that size, but if you're judicious with your components, it's not too hard.
Then again, Immutable.js is about 15kb on it's own, and a few other heavy hitters and you'll hit 100kb (gz) load before much functionality. That said, I think a 500kb target for a web app isn't too bad, this does exceed that, but not sure if certain bits (image references, fonts, etc) are part of the actual JS bundle, which will bloat it out a lot.
lol, it IS react and the fact that you achieved 20k isn't thanks to react, but thanks to preact...
React has a lot more sanity checks in place, but that comes at a cost. For a component, it's too much of a price to pay... for a full-blown application, it's usually well worth it. For a component, 20kb is pushing it... for an application, generally 500k would be the limit in my mind. Which is pretty easily hit regardless of the framework, but too many applications include various libraries willy nilly....
Often times you will wind up with competing libraries that both get installed... You'll get all of lodash, and all of Ramda... you'll get all of jQuery, and a few other tools because you're bringing in one component. Working on larger applications with people less judicious as to what they bring in results in a lot of bloat... more so when it's easier to bring something in (thanks to webpack/babel), and while I appreciate that, it's a tool that's easy to abuse.
In the end, you can get react+redux in under 100kb, you can get a lot of the app boilerplate for a mid-sized app well under 200kb... I would compare this to angular, or ng2 that tend to be much bigger. In the end it's how you are building.
Beyond this, as I said, I didn't really look into the bundle... depending on configuration it could be including images, fonts and css. Which would mean it's really not that bad, though it should probably be using url-loader for a lot of the assets to break into separate downloads. Also, react-icons is much better when only needing a few icons from the libraries, they're also well normalized to mix/match in terms of size/position than the fonts tend to be.
Sorry, I was looking at the uncompressed size!
While 700 Kb is sort-of-acceptable in terms of data usage, the execution of 2.8 Mb of JS is quite taxing on the browser: on my 2010 MacBook Pro it takes 4-5 seconds to show the text on the page, even when bundle.js is cached...
I'm also getting a 2.8mb file, which the server is having trouble sending in a reasonable timeframe under the heavy load HN is putting it under right now.
Interesting, to me it came compressed.
I don't think that's off-topic in the slightest and have been asking this question myself for ages.
Cool library, any thoughts on https://github.com/rtsao/csjs
I found it to be a great middleman between CSS and JS, with full CSS support.
Is there any benefit to using this over CSS Modules in React?
React CSS Modules does not allow you to use props or state to style your component. Say you wanted to use a button <Button color="#aeee00" /> you could map the color prop directly to CSS.
There is nothing preventing you from using (React) CSS modules & state/props. Use the allowMultiple option if you need more than one classname (base classname + modifier).
But how does that work if this translates everything to traditional CSS?
You write CSS files and import them in your component. By using Webpack you would do something like this in your component:
The stylesheet import is just Webpack doing its thing, using css-loader. Example config: https://github.com/hph/kit/blob/master/webpack.config.jsimport CSSModules from 'react-css-modules'; import styles from './styles'; // This is a styles.css file in the same dir const Component = () => <p styleName="welcome">Hello, world!</p>; export default CSSModules(Component, styles);Sorry if I misunderstood your question.
Nice project!
We have a project like that one of our developers wrote except it will compile the classes back to a CSS stylesheet for you for performance and will unify identical styles to not have duplicates and save space https://github.com/Mosho1/react-style
One advantage to keep the style not in a CSS file is that you can handle dynamic value easily withing your component. Bringing back to a CSS file make you loss that capability.
So it translates everything back to CSS, is that how it handles hover and pseudo classes?
Yes, exactly - it also produces smaller file sizes and in our experience it's faster.
It's also nice to be able to use classes and integrate with CSS seamlessly when you need to.
Is it possible to use state or props in the CSS though? How does it handle that? Say I wanted the color of a title to be controlled via props, how would I do that with your solution?
This is very similar to https://github.com/Khan/aphrodite and https://github.com/rtsao/react-stylematic
One of the biggest differences between ReactCSS and other solutions is that all of the style merging is done in the style object and not in the HTML. This keeps the markup clean and puts all style and style logic in one place.
<span className={css(styles.blue, styles.small)}>
vs
<span style={ styles.button }>