If you've used React in a project before, or included third-party React modules, then you've probably come across the concept of React Inline Styles. This works pretty much as it sounds - CSS is added to elements via the style
attribute rather than a global CSS file:
var divStyle = {
color: 'white',
backgroundImage: 'url(' + imgUrl + ')',
WebkitTransition: 'all', // note the capital 'W' here
msTransition: 'all' // 'ms' is the only lowercase vendor prefix
};
ReactDOM.render(<div style={divStyle}>Hello World!</div>, mountNode);
(from the React docs)
Having used React in a few projects now, here's some thoughts on the good and bad points of using inline styles in this way.
Good
One of the underlying concepts of React is encapsulation - components are in control of rendering themselves and can update based on new state data. This means you can change your underlying data and tell the app that the state has changed, at which point every component will take care of updating itself and rerendering if it needs to - which is the key point, the components themselves know whether to update, you don't have to manually trigger stuff when the data changes.
Inline styles take the concept of encapsulation a bit further - now components not only know how and when to render themselves, but they also contain all the styles they'll need, so you can just drop them into a project and they will behave and look like you want. This is the central idea of Web Components, where you can define your own HTML tags and use them in projects; wouldn't it be great if to create a carousel you could just use a
tag like you would with or
? React's encapsulation allows defined components to be dropped into a React project in this fashion, so you can add your pre-defined component to the page, not worry about having to define its' behaviour, and then just style it to match the theme of your site.
Well, no
Unfortunately, this isn't really the case when using inline styles: CSS's core concept is that styles cascade (the C
of CSS), so that styles which are more specific override less specific styles. There are a number of rules about specificity in CSS, but essentially inline styles trump everything, so are always applied (yes, you could use !important
, but if you've got to that point then something has gone horribly, horribly wrong).
If you want to change how a component looks, which you will unless all of your sites are the same colour and size, you need to go and edit the styles defined in the component, rather than in a central CSS file. This defeats the point of having an encapsulated component if you have to edit it in every project rather than having it pick up your general site styles, then tweaking from further up in the project.
Updating the styles themselves isn't much fun either - they're defined in essentially JSON syntax, which is pretty picky; every value must be in quotes, and a lot of attributes are renamed (-webkit-transition
becomes WebkitTransition
, background-color
becomes backgroundColor
and so on). You won't have any nice CSS syntax highlighting - it's using Javascript! - and you'll be unable to use any nice post-processor features like mixins or Autoprefixer, so everything will have to be written out by hand including different vendor prefixes.
You'll also then have the problem of some styles being defined in a CSS file, and other scattered around your project in various Javascript files, which makes maintenance a real pain, especially when a new dev joins the project.
Why would you do this?!
Well, this clearly makes sense to some teams, otherwise it wouldn't exist. It probably works quite well at Facebook, where you have one, or only a few, monolithic project which all share the same style, and have hundreds of developers working on it. In this situation, you can't trust global styles - someone may have updated the CSS which breaks your component as you were making your component, so it makes sense to bake everything in at the component level. If, however, you're using components across a number of projects in the web component fashion, then using inline styles causes a lot more problems than it solves.
The Future
There's a lot of talk and work around CSS modules at the moment which take a similar approach to inline styles (import styles into your React component), but actually use CSS which addresses a number of the issues I raised above.