Hacker News new | past | comments | ask | show | jobs | submit login
ReactCSS – Bringing Classes to Inline Styles (reactcss.com)
118 points by casesandberg on July 3, 2015 | hide | past | favorite | 80 comments



Webpack's css-loader is made pretty much for the same goals, but it has some differences. https://github.com/webpack/css-loader

One difference between the two is that css-loader allows you to use normal css files with classes and selectors, while ReactCSS inlines all properties.

For example, with css-loader, you can use much of your old toolchain for css. You can use sass, less, or newer tools like postcss, but you still get the benefit of local styles.

Here is a nice articles that touches on css-loader and postcss: https://medium.com/@olegafx/frontend-welcome-to-the-future-9...


First, this isn't really anything to do with webpack or css-loader; it's an idea which just happens to be supported by, among other things, css-loader. (Also has a browserify plugin.)

Second, I find this idea to be conceptually very interesting, especially compared to the inline styles people are playing with. It works with the existing CSS tooling, knowledge, frameworks, browser optimisations, etc we already have. There's no real workarounds, edge cases, weird hacks, whatever. It's normal CSS, but scoped to your component, which makes reusing components across a project or between projects MUCH easier.

It's not a magic bullet; you have to be smart still about organising your CSS. But it's really quite clever. I'm using it on a decently large project right now; too soon to tell how it'll work out but it's been good so far.


For anyone experimenting with inline styles, there are a couple of things you'll still need a stylesheet for.

Inline styles can't modify psuedo-elements or psuedo-styles. You'll need to define styles for :before, :focus, :active, etc. in a stylesheet. These selectors are really important if you want to make appealing forms, e.g. http://blog.circleci.com/adaptive-placeholders/

Vendor prefixes are difficult to do with inline styles. If you're using a map to represent your styles, you can't define multiple values for the same key. For example, if you wanted to use flexbox, you'd need "display: flex" and "display: -webkit-flex". Solving that with inline styles is going to get messy. It's much easier to use less's auto-prefixer plugin to do that for you.

You need a stylesheet to define keyframe animations.

There's probably more I've missed, but those were the problems I ran into when I experimented with inline styles. In the end, the vender prefixes problem made me move all of my styles to a stylesheet. The good news is that the problem could probably be solved by applying a runtime equivalent of less's auto-prefixer.


While you can't modify pseudo elements or pseudo classes, you can replicate them using actual elements and conditional logic. I've seen React examples that do just that.


Good point.

This is why I think there is a place for a hybrid of javascript styles which are processed by build tools to generate style sheets.

https://github.com/teal-lang is an interesting approach


Impressive, but to me, as a front-end developper that has been breathing CSS for the best part of my adult life, this solve an issue that shouldn't be an issue.

Yes, you can end up with unmanageable CSS. Yes, it is very easy to end up with a website that is hell to maintain if you have no idea what you are doing.

The real solution is to hire someone who is an expert at managing CSS in enormous websites.

You don't see people saying "Oh? OOP programming? That's too hard! Write all your code with this insert unconventional project instead!".

That being said, this project is impressive, and I love that people are working toward making CSS better.


> You don't see people saying "Oh? OOP programming? That's too hard!

Actually we do. OOP makes a lot of things hard to implement and maintain. That's why functional programming of front-end matters and new approached emerge (reactjs/virtual-dom + immutable data).


Of course, anybody is able to manage a problem, but our jobs as engineers should be to fix the problem. And indeed, there is a lot that is problematic about CSS, just as there is a lot that is problematic about writing concurrent code in old versions of Java.

You can deal with it if you're careful and don't let anybody touch the code, but you've solved nothing and as an engineer, that should make you feel bad.


I'm not sure that this really solves the problem better than keeping your less files next to your jsx files for component specific styles and relying on css classes, hierarchy or properties as it stands.

I've gone down the path of doing similar things to this, and in the end I find it's more complex than simply using less (or scss)... While I appreciate the effort actually inheriting styles in/out of react components, based on parent/child relationships is a lot harder to manage when dealing with your react components directly imho.


Are you able to elaborate on what practical issues you ran into?


Mainly centers around inheritance, or applying the same styles to multiple controls... it's much easier in CSS using classes, or hierarchies than it is directly in the controls... you'll usually wind up with some common js style files, and have to import/use them for reuse... and it just gets a bit weird, even compared to say bootstraps variables file.


I'm a fan of technologies that let me hire people who aren't best-in-world and still produce decent maintainable code.


I'm more of a fan of hiring people that can make the best-in-world out of out-dated hard to use, barely documented technologies. To me, that's what is encountered the most.


Can someone explain or lead me to a reason that this is a good idea? I understand that React is solving a problem, but I don't see how inlining your css like so contributes or improves the solution that React brings.


See the seminal presentation on the subject. https://speakerdeck.com/vjeux/react-css-in-js


css tends to be used with global name spacing

this becomes very quickly hard to manage

the core idea is to do what react did in js (global namespace => components) but for css

that being said i believe stuff like https://github.com/css-modules/css-modules will be a more correct solution (you can also use scss to precompile eg)


I understand the idea but I still think the BEM methodology is better than this approach.


I disagree. Using something like ReactCSS, all the code related to a component is in the same file. I don't have to switch between HTML, JS, and CSS files just to edit some small part of my app.


I'm not sure that trying to keep everything in one file is necessarily a great argument. Optimizing for not having to open files doesn't seem like the best thing to optimize for. Even many of the react+inline styles examples include putting variables and other patterns into external files. Language (i18n) strings could be another external dependency. Data model, controllers, and routing are other good examples. (Rarely (if ever) have I seen an MVC framework that doesn't separate things into separate files.)


It's more conceptual than keeping everything in one file. I want to be able to see everything related to a component without looking at anything else, and to be able to easily change its styling in the same way I change its structure or behavior (at least with React). You can technically do this by creating a separate CSS file for every component, but the problem is your CSS has no context about your component, and so you end up doing all kinds of shuffling with classes to get things to display the way you want them to. This is a much more elegant solution, in my opinion.


BEM is a clever naming strategy to deal with the problems of a medium-to-large CSS codebase. Why put up with it in the first place?


Component-orientation and both exist to mend the problems of global CSS. If you use BEM in React you will usually have a one-to-one relationship between BEM component classes and React components. RaisedButton component has a .RaisedButton class, Icon has .Icon, etc.


We do this Imho this is just "better" management of the same problem


what happened to a clear division between js and css? In my experience many developers want nothing to do with css, they want a designer who can code to handle that


I think the React philosophy on this is that JS and CSS (and HTML) separate technologies, not concerns.

For very simple layouts, CSS is good enough, and it perhaps makes sense to split out the css into a separate file, so long as it's pretty clear what each class does, and the classes are pretty much all global so that changing a property of a class will do exactly what you intend (make the font size of all page titles on the site bigger), and not have unintended consequences on other components you weren't aware of, or thinking about.

For web apps built from many complex components, the flat, global nature of CSS becomes very clumsy indeed. The power and flexibility you need to manage styles of these components quickly outgrows the power of CSS.

You start having to rely on splitting the css into files that contain only styles applying to each component, so that the structure is manageable and you can find things and make changes easily. So why not just drop those styles right into the component file where they're referenced anyway? What concerns are you separating by keeping the css out in a separate file?

You also start having to rely on build-time tools like SASS and LESS to introduce the necessary features to handle complexity in a large, component-structured codebase: variables, scope, mixins, etc. All these things are trivial features of JS, so why not just use JS to put in the styles directly instead of doing it with css propped up by a complex tool-chain? What are you gaining by doing so, other than having the CSS in a separate file? And, again, why is this a good thing?

CSS is just a technology for applying styles to your markup. For many apps, it's in inferior technology to JS for doing this, particularly when using a framework like React.


In many cases that division doesn't exist. Part of the beauty of React, as far as I'm concerned, is that it allows us to think about things on the page in terms of components, rather than as separate blocks of html, and javascript.

It does make sense to bring css into the mix as well, as css can have functional effects. If you have a React component, for example, which explicitly toggles whether items are displayed or not, it makes sense to tie the toggling of the css display property directly into the component, rather than factoring it out into a separate stylesheet and creating an additional dependency.

Note that I'm not suggesting that all styling should be done this way - I think that would be disastrous - but that there is merit in composing the html, css and javascript together.


Exactly. It's still a separation of concerns, just a different set of concerns. Organizing my code by feature/component is so much easier on my brain than organizing it by file extension.

You can mess this up, of course. We are really good at making things more complex than they ought to be, especially while the ideas are fresh in our head. We just need to keep that in mind to :)


Is it not just making things more complicated to put some CSS separate and some at the component level? Sounds like a nightmare for a designer who comes in to the game that didn't design the app.

I'm not saying breaking CSS into separate files is a perfect solution (this is what I do), but at least it allows you to have everything in one place so anyone can pick up and customize.

I work with some pretty complicated enterprise CMS systems and they are already terrible complex. Last thing I want to do is start spreading CSS all over the app.


I have been doing web apps and websites for a long time, and when I first saw this, it looked so wrong but felt so right.

Inline styles were impossible to maintain. Even if these (reactCSS) are rendered inline, it's easy to maintain, easy to follow, easy to change.

Javascript used to refer to making things move around and handling click/hover events (javascript was the DOM language). Now it's the entire application.

what am I trying to say...? it seems wrong, but try it out and see if your concerns don't just go away.


I feel like this has happened because the people who are creating these solutions are used to working with excellent and experienced team mates, who have a solid understanding of JS and CSS and are happy to work with both (and waste time learning the latest build-systems etc).

I can see it getting verrry messy in wider circles - and I bet we'll go through a whole slew of bizarre process workarounds and frameworks until we end up with a solution that is suspiciously like "clear division between JS and CSS"!


I'd suggest there is still a clear distinction. The big difference is that the CSS defined per-component instead of globally.


If your experience is that designers do all the CSS and no JS, then feel free to continue using that approach. Some of us either have good designers who adhere to Atomic Design and know some JS, and some of us have to translate mock-ups into HTML/CSS.


Maybe we should start calling this something besides inline styles, because of the huge negative connotation it carries. It's more like component-ized styles or something. This is a pretty interesting concept though. I've noticed that in really large and interactive web apps sass becomes super unwieldy, and many styles just aren't re-usable.


Look at the source. It's quite literally inline styles.


Sure that's the final result, but like mmatants said, it's the opposite of how inline styles were used back in the day. They were static then, and repetitive, the idea here is to programmatically create inline styles for web pages that have become increasingly dynamic and complex.


I think what vlunkr is trying to say is that perhaps we shouldn't be as contemptuous of inline style information as the design community has been over the past 10 years.


isn't it more like multilines style?


Generated styles?

And great point - these new inline/generated styles are the opposite of what they meant 10 years ago (copy-pasta hacks). Now they are even more powerful than regular CSS, instead.


Easier, maybe. But they're actually less powerful; inline styles support a strict subset of what regular CSS supports. (eg, no support for pseudo elements, as others have mentioned)


Not to mention you lose the ability to live edit classes of elements all at once in the dev tools -- pretty hand for tweaking layouts of prototypes.


How does this compare to something like Radium? I have been looking for a clean way to work with styling in React and was planning to use Radium, then I noticed this.


I'm also very interested in the answer to this. (http://projects.formidablelabs.com/radium/)


Hey, you put CSS in my JavaScript!

Surely this could be done in a smarter way, using one of the many CSS preprocessors to replace the variable mapping done by `classes()`?

After all, the `render()` template just needs to reference variables!


I think you might want to try https://github.com/css-modules/css-modules


I'm not a big fan, to be honest. I've read a few posts about the idea, but I'm just not convinced. I'm very happy with SASS, especially with frameworks like Foundation, Bootstrap, and Skeleton. If you follow the advice and best practices outlined by those framework authors, then I don't think CSS needs such a huge paradigm shift. And then there's PostCSS, which I haven't really explored yet, but seems really promising.


This is a very elegant and magical solution. My problem is with the react community's position on maintaining css in JS rather than in css files.

I'd much prefer to see the problems that the JS managed css solves handled during the build phase of the life cycle.


What is your practical issue with it? I know it feels wrong at first, and by default performance may not be as good, but it makes sense to colocate the trio: one component into one file.

If you already use a methodology like BEM or SUIT, this is just a natural extension of that.


The problem is you break the cascading part of CSS. So if you include someone else's react components, you have to do any modifications to the styling either in some config file they provide you, or by extending the component and modifying it there.

I know one of the larger motivations for managing styles directly in the react components was to solve a desire to have namespaces in CSS. Maybe there are other benefits that I am unaware of which would support handling styling directly in the react component.

But if you only partially implement your app / site in React, you have further complicated an already dense set of develop/styling abstractions. You will now have to think of your styling in terms of pre-instantiated app & post-instantiated app.

If you fully implement your app in React, you will most likely want to do away with traditional css all together with the exception of some base css libraries. CSS without cascades seems like a strange place to be.


Yeah, if you go the inline styles route, the "cascading" and "sheets" part disappear (to some extent, anyway - you still need some global styles). This isn't a bad thing, though. Good CSS architectures usually avoid the cascade as much as possible. Imagine you have an Avatar inside a Header:

    class Header extends React.Component {
      render() {
        return (
          <div className="Header">
            <Logo />
            <Avatar />
          </div>
        );
      }
     }
You want the Avatar to be floated to the right, so you do:

.Header .Avatar { float: right; }

Unfortunately, this breaks encapsulation. It's basically monkey-patching and makes your components less portable. It causes a lot of problems in larger apps that aren't apparent until down the line.

So you could use BEM:

    <div className="Header">
      <Logo />
      <Avatar className="Header__Avatar" />
    </div>
This prevents many of the problems with global selectors, specificity, and encapsulation, but it gets repetitive and is a little ugly once things get more complicated. It's still pretty bug-prone. Another way to do it is:

    const styles = {
      base: {
        // ...
      },
      avatar: {
        float: 'right'
      }
    };

    <div style={styles.base}>
      <Logo />
      <Avatar style={styles.avatar} />
    </div>
Which is how Radium and React Style do it. In this case, it might be <Avatar is="avatar" /> but it's the same idea. Specificity, modularity, namespacing, indeterminism, etc., are almost all fixed. Plus you now have the ability to dynamically compute values, import constants and functions, get values statically from CSS, and apply modifiers like `Header--loggedOut` by doing {this.props.isLoggedOut && styles.loggedOut}.


I prefer to colocate into 1 folder. index.jsx, index[.css,.styl,.scss, etc.]

Just like my JS requires different JS files, my CSS imports various files too. The preprocessor turns that into 1 css file (or n, if you want).


Right, so it's more based on "what feels right"? (I don't mean that in a bad way - sorry - am genuinely curious.) Note that you can import files in JS too. If you want to turn it into n files, then there's webpack's code splitting, which makes even more sense here.


More that I don't have to force everything into a single file. I think it's more flexible that way. Let's say one day I work static files into my build process I could chuck them into the same folder where they're relevant to the component.


Thing is, your one component might share styles with half the other components.

Then having a proper separation of code and style with class names to bind the two becomes your only sane option at scale.


Components sharing styles is the same as functions sharing constants, so there isn't a fundamental difference here. One benefit of sharing constants is that you can use, eg, TypeScript to compile-time check that all of the constants are defined, making it much easier to remove unused styles.


    import theme from 'styles/theme';


I've been indirectly using React via Reagent in Clojurescript and I've been enjoying expressing logic in Clojure syntax, with dom structure in Hiccup's syntax.

I've been wishing for a nice way to incorporate CSS into that as well. I'm starting to feel like using 3 different languages.. HTML/JS/CSS to achieve a single effect is a bit unwieldy, though I've done it for years.

I haven't yet seen story in JS or Clojure for bringing CSS into the actual programming yet that I'm ready to adopt.. but this is interesting.


<Icon is="Icon" />

<span is="span" />

<CodeSmell is="Stinky" />

Besides, you kinda lose all the advantages of using javascript to style, which is complex computations and co.


    <div is="dialog">
      <h1 is="title">
        { this.props.title }
      </h1>
      <div is="actions">
        <Button is="Cancel" label="Cancel" />
        <Button is="Accept" label="Accept" />
      </div>
    </div>
Seems more expressive to me than <div className="dialog">. I understand the point though; the example provided on the homepage is very contrived. Few people are going to do something like <span is="span">. (Well, I could be wrong.)


> Besides, you kinda lose all the advantages of using javascript to style, which is complex computations and co.

No, you dont' loose it. You can still script the "is" attribute, also you can escape to regular className in case of advanced cases. So this is a 80-20 solution.


here's a great video about inlining css with react.

Colin Megill - Inline Styles are About to Kill CSS https://www.youtube.com/watch?v=NoaxsCi13yQ


Thoughts on https://github.com/pluralsight/react-styleable ?

A higher-order React Component that:

- Makes defining and using css styles in React Components consistent.

- Makes your styles portable with your reusable components.

- Makes overriding styles easy and predictable.

Uses CSS modules.


Regardless as to what this project is trying to achieve, I appreciate that the site is using all inline styles and is surely using this project to have made it easier!


I've never seen any builder that outputs js to that[1]. Does anyone know what he's using?

[1][ https://raw.githubusercontent.com/casesandberg/reactcss/gh-p... ]



webpack


Though the styling of the website looks similar, this is not a facebook project.

I think the main reasons to want a component to do some styling are:

- so the consumer doesn't have to include separate CSS elsewhere to get default appearance

- and so that stuff that is an implementation detail can be relatively hidden (as with the shadow dom) and can expose what it makes sense to expose.

So the ideal styling approach lets a component properly render itself, yet also lets it be customizable with regular CSS.


This is pretty cool. For now, I'm going to stick to regular CSS files, but when that becomes unmanageable it will be nice to have styles combined with react components. Some would argue that this is edging near "inline styles" and "one should never inline CSS." But this package definitely has practical value. Talk about "rethinking best practices?!" Nice work!


I believe in the future, js may replace css, perhaps even html. Javascript is the future.


barfs violently

In all seriousness, I could see a future where the browser is just another user environment. Desktop OS (Linuxes, Mac OSX, Windows), mobile OS (Android, iOS, Windows), and the browser (Firefox, Google Chrome, Safari, IE/Edge).

We compile things against it (there's a standard library/API/ABI), it has a screen that users interact with.

At the risk of sounding more irrationally exuberant than the parent, the browser is an OS in itself. Yes I realize that "OS" and "browser" are actual terms that have narrowly defined definitions, however the sentiment is the same.

It's just another client for our code/binaries to run on and in actuality what's running our code is irrelevant.

I'm intentionally avoiding calling it a platform, though.


I really can't imagine a circumstance in which this would be a good idea (as opposed to refactoring your CSS such that it's well namespaced).


The way CSS in React should be is not to be.


Elaborate?


CSS in JS is not an inherently bad idea, but I haven't seen a good implementation, much less one as good as a CSS preprocessor. CSS done in React abandons all that's powerful about CSS in order to do glorified inline styles.

Look at the example. Imagine that being one of dozens or hundreds of components in an app. Then imagine trying to re-style the app from a flat-looking interface to whatever's trendy next. I'd much rather do that with a LESS file than muck through however many JS files that would take with this.


You're missing the idea here. The idea is that the front-end engineers don't have to deal with styles anymore.

They can just take a <Tab><Item/><Item/><Item/></Tab> and expect those components to be designed inside of the components themselves.

This is var more similar to how iOS handles design. You have your own custom views with their own style defined, obviously on some you can override them, but usually they are defined inside the class itself.

It makes sense for Web to take this route, given how hard it is to design on the web compared to iOS. At least for me :)


I suppose I look at things differently, because I use the BEM/SUIT methodology. There is already a logical one-to-one mapping between most BEM components and React components, so the effort required to change everything would be roughly the same.

The point of using inline styles isn't to be hip: it fixes most problems caused by specificity wars, global selectors, monkey patching, code bloat, dead code, and indeterminism. I agree that there is yet to be an implementation that is perfect, but there are some very smart minds working on this problem at the moment.


My issue is that the problems you listed are solvable if you write good CSS.

I mean, specificity wars... isn't that one of the first things we learn to avoid when writing stylesheets?


Right. So long as you follow sound architectural practices and be careful to not override global selectors, you will achieve most of the benefits of inline styles. https://github.com/postcss/postcss-bem-linter is a godsend.

However:

* Your components will still be spread out among separate files. Button.js, Button.scss. Icon.js, Icon.scss. Just like it doesn't make sense to separate inherently coupled HTML and JS, it doesn't make sense to separate inherently coupled HTML/JS and CSS.

* You have to use two separate programming languages unless your app is simple.

* SASS and LESS can be really problematic. They have ambiguous syntax and are non-standard. There's 9,001 ways to import in LESS. They look like programming languages, but they differ in confusing, bug-prone ways. SASS and LESS's variable resolution are different and confusing. And math is whitespace-sensitive. Yes, whitespace-sensitive math.

* Another build step.

* No easy way to get values statically from CSS files. Instead you have to use comments like "IMPORTANT: keep this value in sync with Button.js!". And if you forget, you will have a difficult-to-debug problem.


Sure: CSS is better managed and maintained and more easily understood by future maintainers outside of React and JavaScript, i.e., more cheaply and with less risk. And there are plenty of sugars for making it even better, e.g., SCSS, LESS.


Maybe this would make more sense for Native?


Do inline CSS styles impact performance ?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: