[css] React.js inline style best practices

Comparing to writing your styles in a CSS file, React's style attribute has the following advantages:

  1. The ability to use the tools javascript as a programming language provides to control the style of your elements. This includes embedding variables, using conditions, and passing styles to a child component.
  2. A "component" approach. No more separation of HTML, JS, and CSS code wrote for the component. Component's code is consolidated and written in one place.

However, the React's style attribute comes with a few drawbacks - you can't

  1. Can't use media queries
  2. Can't use pseudo-selectors,
  3. less efficient compared to CSS classes.

Using CSS in JS, you can get all the advantages of a style tag, without those drawbacks. As of today, there are a few popular well-supported CSS in js-libraries, including Emotion, Styled-Components, and Radium. Those libraries are to CSS kind of what React is to HTML. They allow you to write your CSS and control your CSS in your JS code.

let's compare how our code will look for styling a simple element. We'll style a "hello world" div so it shows big on desktop and smaller on mobile.

Using the style attribute

return (
   <div style={{fontSize:24}} className="hello-world">
      Hello world
   </div>
)

Since media query is not possible in a style tag, we'll have to add a className to the element and add a css rule.

@media screen and (max-width: 700px){
   .hello-world {
      font-size: 16px; 
   }
}

Using Emotion's 10 CSS tag

return (
   <div
      css={{
         fontSize: 24, 
         [CSS_CONSTS.MOBILE_MAX_MEDIA_QUERY]:{
            fontSize: 16 
         }
      }
   >
      Hello world
   </div>
)

Emotion also supports template strings as well as styled-components. So if you prefer you can write:

return (
   <Box>
      Hello world
   </Box>
)

const Box = styled.div`
   font-size: 24px; 
   ${CSS_CONSTS.MOBILE_MAX_MEDIA_QUERY}{
      font-size: 16px; 
   }
`

Behind the hoods "CSS in JS" uses CSS classes. Emotion specifically built with performance in mind and uses caching. Compared to React style attributes CSS in JS will provide better performance.

###Best Practices

Here are a few best practices I recommend:

  1. If you want to style your elements inline, or in your JS, use a CSS-in-js library, don't use a style attribute.

Should I be aiming to do all styling this way, and have no styles at all specified in my CSS file?

  1. If you use a css-in-js solution there is no need to write styles in CSS files. Writing your CSS in JS is superior as you can use all the tools a programming language as JS provides.

should I avoid inline styles completely?

  1. Structuring your style code in JS is pretty similar to structuring your code in general. For example:
  • recognize styles that repeat, and write them in one place. There are two ways to do this in Emotion:
// option 1 - Write common styles in CONSTANT variables
// styles.js
export const COMMON_STYLES = {
   BUTTON: css`
      background-color: blue; 
      color: white; 
      :hover {
         background-color: dark-blue; 
      }
   `
}

// SomeButton.js
const SomeButton = (props) => {
   ...
   return (
      <button
         css={COMMON_STYLES.BUTTON}
         ...
      >
         Click Me
      </button>
   )
}

// Option 2 - Write your common styles in a dedicated component 

const Button = styled.button`
   background-color: blue; 
   color: white; 
   :hover {
      background-color: dark-blue; 
   }   
`

const SomeButton = (props) => {
   ...
   return (
      <Button ...> 
         Click me
      </Button>
   )
}

  • React coding pattern is of encapsulated components - HTML and JS that controls a component is written in one file. That is where your css/style code to style that component belongs.

  • When necessary, add a styling prop to your component. This way you can reuse code and style written in a child component, and customize it to your specific needs by the parent component.

const Button = styled.button([COMMON_STYLES.BUTTON, props=>props.stl])

const SmallButton = (props)=>(
   <Button 
      ...
      stl={css`font-size: 12px`}
   >
      Click me if you can see me
   </Button>
)

const BigButton = (props) => (
   <Button
      ...
      stl={css`font-size: 30px;`}
   >
      Click me
   </Button>
)

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to reactjs

Error: Node Sass version 5.0.0 is incompatible with ^4.0.0 TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type undefined raised when starting react app Template not provided using create-react-app How to resolve the error on 'react-native start' Element implicitly has an 'any' type because expression of type 'string' can't be used to index Invalid hook call. Hooks can only be called inside of the body of a function component How to style components using makeStyles and still have lifecycle methods in Material UI? React Hook "useState" is called in function "app" which is neither a React function component or a custom React Hook function How to fix missing dependency warning when using useEffect React Hook? Unable to load script.Make sure you are either running a Metro server or that your bundle 'index.android.bundle' is packaged correctly for release

Examples related to inline-styles

React.js inline style best practices Using CSS :before and :after pseudo-elements with inline CSS? CSS Pseudo-classes with inline styles How to write a:hover in inline CSS?