48

What do you think are good ways to handle styling pseudo selectors with React inline styling? What are the gains and drawbacks?

Say you have a styles.js file for each React component. You style your component with that styles file. But then you want to do a hover effect on a button (or whatever).

One way is to have a global CSS file and handle styling pseudo selectors that way. Here, the class 'label-hover' comes from a global CSS file and styles.label comes from the components style file.

<ControlLabel style={styles.label} className='label-hover'>
    Email
</ControlLabel>

Another way is to style the components based on certain conditions (that might be triggered by state or whatever). Here, if hovered state is true, use styles.button and styles.buttonHover otherwise just use styles.button.

<section 
  style={(hovered !== true) ?
     {styles.button} : 
     {...styles.button, ...styles.buttonHover }>
</section>

Both approaches feels kind of hacky. If anyone has a better approach, I'd love to know. Thanks!

Vien Tang
  • 553
  • 1
  • 5
  • 11

2 Answers2

71

My advice to anyone wanting to do inline styling with React is to use Radium as well.

It supports :hover, :focus and :active pseudo-selectors with minimal effort on your part

import Radium from 'radium'

const style = {
  color: '#000000',
  ':hover': {
    color: '#ffffff'
  }
};

const MyComponent = () => {
  return (
    <section style={style}>
    </section>
  );
};

const MyStyledComponent = Radium(MyComponent);

Update 04/03/2018

This has been getting a few upvotes lately so I feel like I should update it as I've stopped using Radium. I'm not saying Radium isn't still good and great for doing psuedo selectors, just that it's not the only option.

There has been a large number of css-in-js libraries since Radium came out which are worth considering. My current pick of the bunch is emotion, but I encourage you to try a few out and find the one that fits you best.

  • emotion - ‍ The Next Generation of CSS-in-JS
  • fela - Universal, Dynamic & High-Performance Styling in JavaScript
  • styled-jss - Styled Components on top of JSS
  • react-jss - JSS integration for React
  • jss - JSS is a CSS authoring tool which uses JavaScript as a host language
  • rockey - Stressless CSS for components using JS. Write Component Based CSS with functional mixins.
  • styled-components - Universal, Dynamic & High-Performance Styling in JavaScript
  • aphrodite - It's inline styles, but they work! Also supports styling via CSS
  • csx - ϟ A CSS-in-JS solution for functional CSS in functional UI components
  • styled-jsx - Full CSS support for JSX without compromises
  • glam - crazy good css in your js
  • glamor - css in your javascript
  • glamorous - React component styling solved with an elegant API, small footprint, and great performance (via glamor)
  • styletron - ⚡️ Universal, high-performance JavaScript styles
  • radium - Set of tools to manage inline styles on React elements.
  • aesthetic - Aesthetic is a powerful React library for styling components, whether it be CSS-in-JS using objects, importing stylesheets, or simply referencing external class names.
  • j2c - CSS in JS library, tiny yet featureful

(Source)

Michael Peyper
  • 6,814
  • 2
  • 27
  • 44
  • I was trying to not use any additional dependencies but Radium looks like a good solution. Thanks for the suggestion. – Vien Tang May 01 '17 at 07:34
  • 3
    React, Redux and Radium... the 3 R's to easy web development ;) – Michael Peyper May 01 '17 at 09:16
  • Been playing around with Radium and it's so easy. Good suggestion – Vien Tang May 27 '17 at 21:15
  • I'm glad it's working out for you. If you feel this has answered your question, then please accept it to help other uses out when searching for similar issues. If you haven't already, voting up useful answers is also acceptable. Please see [this help article](https://stackoverflow.com/help/someone-answers) for more details. – Michael Peyper May 28 '17 at 03:46
  • @MichaelPeyper Thanks for this answer. I think you need to add a comma after `color: '#000000'`, otherwise it does not compile. – geochanto May 09 '19 at 00:48
  • It seems Radium doesn't support functional component with hooks – JillAndMe Aug 28 '19 at 04:03
  • It looks like [hook support for Radium](https://github.com/FormidableLabs/radium/pull/1027) may not be far away, but I'd be considering alternatives these days anyway. – Michael Peyper Aug 29 '19 at 03:22
  • @MichaelPeyper how to style like you did with Radium but using with emotion? – tasqyn Dec 24 '20 at 11:33
  • 1
    @tasqyn I suggest reading the emotion docs. They're pretty good. The introduction even has very similar examples to this https://emotion.sh/docs/introduction – Michael Peyper Jan 04 '21 at 21:59
  • Thanks, had a tough time installing Radium because of react peer dependency. Used `npm i raduim --force` – Cuado Dec 28 '21 at 15:36
0

Is there a reason you're not styling the pseudo selectors with your label-hover class like this? Or am I misunderstanding your question?

.label-hover {
   color: orange;
   opacity: 0.5;
}

.label-hover:hover {
   opacity: 1;
}

You can't style pseudo selectors with inline styling (CSS Pseudo-classes with inline styles), and I think using javascript to see if the element is hovered is an unnecessarily complicated and hackish way of doing it.

Community
  • 1
  • 1
  • Having both style={styles.label} and className='label-hover' attributes seems non-DRY so I was trying to decide between one. Looks like CSS wins since styling pseudo selectors with React inline styles looks to be non-trivial. Appreciate the link. – Vien Tang May 01 '17 at 07:40
  • 2
    Another great example would be using JS theme managers like material ui. Sometimes you need to get the color from there and thus you have to insert it via react – corlaez May 11 '18 at 16:09