Inline styles with React - thoughts?


#1

Hopefully this won’t start a big argument (as is par for the course on here lately) :wink: But I’m just wondering how people feel about this kind of structure:

Thing = React.createClass({
  render() {
    return <div>
      <SomeThing style={{
        zIndex: 1,
        width: '200px',
        height: '100px'
      }} />
    </div>
  }
});

…compared with what I usually do, which is set up this structure:

EditModal
├── EditModal.jsx
└── EditModal.scss

And in EditModal's render method, I put a “root class”:

render() {
  return <div className="edit-modal">
  </div>
}

Then in EditModal.scss:

.edit-modal {
  .some-class-only-used-by-edit-modal {
  }

  .another-class {
  }
}

Thoughts? Good? Bad? Advantages/disadvantages? I can see that it might be nice bundling it that tightly so it’s all in one place, but then you miss out on using SCSS which can be obviously really useful and powerful.


How do you name your components?
#2

We can do this quite easily with Vue.js already, so I’m sure it must be possible with React, even with a pre-processor.
See https://github.com/vuejs/vue-webpack-meteor-example/blob/master/.client/app/app.vue


#3

I have no idea why you would inline styles like that and duplicate your CSS everywhere. This practice was shunned years ago before the Web 2.0 era.

Why is this idea gaining traction online all of a sudden? What is there to gain that I’m not seeing.


#4

relevant recent post Are you writing CSS in your JSX files?

I can see that it might be nice bundling it that tightly so it’s all in one place, but then you miss out on using SCSS which can be obviously really useful and powerful.

I find manipulating styles with plain JS much more useful+powerful than SCSS


#5

Interesting. Maybe it’s time to give it a try and see how it works out.


#6

some love it, some hate it. best way to find out is just to put together a demo yourself and play around with it. I’ve found it to be a breath of fresh air compared to maintaining a separate SCSS file, but there’s no arguing that it’s definitely a bit weird compared to the norm


#7

This seems like a ton of work for not much benefit. And if you write a lot of CSS with your apps, it could get a bit crazy. I could see this being useful if you use Bootstrap and only add a few custom styles, but this seems like a nightmare at scale (especially if you have elements with hover states, transforms, lots of different fonts, etc.). Your render function could just end up being hundreds of lines on just one page.


#8

Yeah, I agree with you on that point. I don’t know how the heck I’d handle hover/active states, CSS animations, transitions, etc… it could get messy. I’d probably divide it up, and maybe have some CSS in SCSS files (for global layout stuff, or things that appear sporadically throughout the app), and use inline styles in JSX for component styling.

I don’t know yet. Still processing all this.


#9

I don’t think you should use inline styles. There are some significant limitations to writing CSS that way (e.g. hover states, pseudo elements, etc…). Currently, the best solution I’ve found is CSSModules. You write your styles in regular CSS/SCSS/whatever and then merge them into your component. This way you get the benefits of writing in plain CSS but can also make styles component specific. Here is a very simple example of how it works https://github.com/ryanswapp/react-starter-template/tree/master/app/components/App/screens/Public/About

Essentially, any time you define a class as “className” you are referencing global CSS. When you define a class as “styleName” you are referencing the specific CSS that you’re merging into the component. I think this approach works great! Let me know if you have questions.


#10

Won’t you have to declare what .container is for every single component?


#11

Inline CSS is definitely going to raise the dogma eyebrows. However, if it makes life more simple I would go with it!

I’ve been using in React Native for about 6 months and it’s been great! Currently i’m building a new web app exclusively with inline styles for ‘components’ and global CSS for the rest (resets, typography), and also for styles that needs a hover, active class (as this is tricky at the moment with inline).

You can also do some tricky stuff with JS logic and extend :smile:

Although keep it in an obj literal so it’s easy to maintain. Trailing commas are almost a must. Style variables can be imported too.

import Colors from 'styles/variables'

Thing = React.createClass({
  render() {
    return <div>
      <SomeThing style={styles.thing} />
    </div>
  }
});

const styles = {
  thing: {
    zIndex: 1,
    width: 200,
    height: 100,
    color: Colors.brand,
  },
  foo: {
    ...
  },
  bar: {
    ...
  }
};

#12

Cool. Thanks a bunch for the input, @ryanswapp and @SkinnyGeek1010! Certainly there’s no right or wrong, but there are things to consider on both sides. I’ve definitely run into situations where I’ve thought, “it would make more sense to just inline this style in the component.” But there are many other cases where it makes absolutely no sense. I think ultimately, maybe a combination of both could work out well.


#13

I still don’t quite see the right when using inline styles. I just see that it can be done, but not really why it should be done. Also: Do you repeat your CSS throughout different components as inline rules?

Using Ryan’s example, is .container repeated everywhere?


#14

Things like this can get tedious in CSS:

.some-item {
  color: #ff0;
}

.another-thing {
  background: #0f0;
}

If those are used on a React component, I might just slap them inline instead to save the hassle of jumping out of the JSX file just to go look at or change the color.


#15

There’s no free lunch but it can work around a lot of the CSS issues. Currently it works best to use both inline and normal CSS when you need to cascade.

Pros

  • No cascading issues (never have to use important)
  • Easy to make portable components with no style clashing
  • Easy to maintain as the CSS for a widget is right there
  • No cascading issues
  • No cascading issues

Cons

  • No support for pseudo elements (hover, etc…) though there are hacks
  • Can’t cascade (normally not an issue)
  • Slightly more verbose
  • Hard to use something like ‘auto prefixer’
  • Need to use CS practices to keep DRY

I’ve found so far most items don’t get duplicated because you can use variables and mixings (though vars take you far). Most styling for a component tends to be specific for that… and breaking things down into component helps do that (eg instead of adding a well input class just make an Input component.

Using a CSS style sheet for things that need to cascade will help too… mainly typography.

Still it’s not a perfect fit for every app.


#16

Inline styles with reactive helpers are awesome. They bypass the CSS parsing system, and allow you to give your application GPU optimized animations with a minimum of hassle. Works on mobile too.

Check out ckcc.meteor.com for some examples.

ctrl+cmd+n toggles navbars
ctrl+cmd+s toggles searchbar
ctrl+cmd+q toggles fullscreen

There are quite a few other keyboard mappings you can tinker with, but most of them are experimental. L and R might be worth looking at. Oh, and layout changes as your resize the window from phone to thunderbolt monitor size. That’s managed by inline styles also.

Oh, and the theming page… it uses inline styles for the most part as well.
http://ckcc.meteor.com/theming

tl;dr - They’re great for color and location properties, and for creating programmatically controlled layout and theming. Not so great for making consistently themed widgets. For that, we still use classes and less/scss and cascading styles.

I very much hope that the inline style performance is as good with React as it is with Blaze. There doesn’t seem to be any reason it shouldn’t be as performant; and we’ll very likely be using this strategy extensively when we migrate to React.


#17

For instance take this forum app for example.

The Header component would have a height, width, logo styles and would take a color variable. Still dry. The title and categories would likely be separate components as well. The headline might be re-used from a global style but an inline override can adjust it for this use.

The 16/16 blue box in the corner would be another component and it’s styling isn’t repeated anywhere else (again perhaps typography as a base).

The flag, edit, etc… icons would be one icon component that each would get inline padding, font-size, etc…

It’s best to experiment in one component for while to see if it works for you and your team.

Using Ryan’s example, is .container repeated everywhere?

It really depends on what container does. In React Native it’s just a wrapper (by convention) to adjust flexbox to stretch properly. In this case every use is prob. different.

In the bootstrap context having container being a component makes more sense. instead of <div className="container"> you can make it a component <Container>. This ends up being more readable too :smiley:


#18

Before anyone shits on inline styles lets make a distinction

There are STYLEs and there is STATE

inline styles are perfect for UI state that can be expressed as Style.

Check out this talk: https://www.youtube.com/watch?v=ERB1TJBn32c


#19

We don’t really have a choice but to write inline styles in in React Native lol, though there’s the StyleSheet object which helps makes styles more reusable.


#20

Yep! That’s what got me started using them… you’re kind of forced to make it work.

Also RN is what turned me on to React as I didn’t ‘get it’ before trying it :laughing: