DEV Community

Cover image for How to style React components using CSS
collegewap
collegewap

Posted on • Originally published at codingdeft.com

How to style React components using CSS

You might have come across different ways to style React components.
In this article, we will discuss the most popular ways to do it and the advantages and disadvantages of using them.

Inline Styling

If you want to add a style quickly, you can make use of the style prop to pass the styles to the element as shown below:

import React from "react"

const InlineStyle = () => {
  return (
    <div>
      <button
        style={{
          backgroundColor: "#0ea5e9",
          border: "none",
          color: "white",
          borderRadius: "0.5rem",
          padding: "0.5rem 1rem",
          cursor: "pointer",
        }}
      >
        Hover Me
      </button>
      <p
        style={{
          color: "green",
          background: "lightGreen",
          padding: "0.5rem 1rem",
        }}
      >
        Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ea ab
        exercitationem soluta, consequatur obcaecati suscipit numquam dolorem,
        dignissimos quas nobis error repellat minus sed accusamus placeat, rerum
        illum magnam aspernatur?
      </p>
    </div>
  )
}

export default InlineStyle
Enter fullscreen mode Exit fullscreen mode

As you could see, we have to pass the styles in a JavaScript object to the style prop.
You can see a demo of using inline styles here.

Advantages

  • With inline styles, we do not want to create a separate css file and switch between the css and the component file while applying styles.

Disadvantages

  • As you may have seen in the demo, nothing happens when you hover over the button.
    This is because, with inline styles, you will not be able to add pseudo selectors like :hover,:focus etc.

  • This requires you to write css in the js format, which many people who are used to writing css in a traditional way may not like.

  • We cannot reuse the styles, or use any selectors, which makes the code lengthy and unmaintainable.

In-Page Styles

In Page styles are nothing but inline styles extracted to a separate JavaScript object:

import React from "react"

const InPageStyle = () => {
  return (
    <div>
      <button style={styles.button}>Hover Me</button>
      <p style={styles.paragraph}>
        Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ea ab
        exercitationem soluta, consequatur obcaecati suscipit numquam dolorem,
        dignissimos quas nobis error repellat minus sed accusamus placeat, rerum
        illum magnam aspernatur?
      </p>
    </div>
  )
}

const styles = {
  button: {
    backgroundColor: "#0ea5e9",
    border: "none",
    color: "white",
    borderRadius: "0.5rem",
    padding: "0.5rem 1rem",
    cursor: "pointer",
  },
  paragraph: {
    color: "green",
    background: "lightGreen",
    padding: "0.5rem 1rem",
  },
}

export default InPageStyle
Enter fullscreen mode Exit fullscreen mode

The advantage of using styles this way is you can reuse the styles within the component.
If you place it in a common file and export the styles, then you can use it throughout the application.

Global styles

Global styles are the traditional way of having a css file containing all the styles related to the entire application.

To make use of global styles, create a css file called global.css as shown below:

.button {
  background-color: #0ea5e9;
  border: none;
  color: white;
  border-radius: 0.5rem;
  padding: 0.5rem 1rem;
  cursor: pointer;
}

.button:hover {
  background-color: rgb(37, 99, 235);
}
.paragraph {
  color: green;
  background: lightGreen;
  padding: 0.5rem 1rem;
}
Enter fullscreen mode Exit fullscreen mode

Now include the global.css in the topmost component in your project:

import React from "react"
import "./global.css"

const GlobalStyle = () => {
  return (
    <div>
      <button className="button">Hover Me</button>
      <p className="paragraph">
        Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ea ab
        exercitationem soluta, consequatur obcaecati suscipit numquam dolorem,
        dignissimos quas nobis error repellat minus sed accusamus placeat, rerum
        illum magnam aspernatur?
      </p>
      <button className="button">Hover Me</button>
    </div>
  )
}

export default GlobalStyle
Enter fullscreen mode Exit fullscreen mode

Advantages

  • Unlike inline styles, we can have different types of selectors to share the styling between components.
  • Since style is separated into a different file, it helps in having a cleaner code.

Disadvantages

  • Since all the styles are stored in a single css file, if multiple people are working on the project, then it might result in both code conflict and styling conflicts.

Create react app comes with default index.css, which is an example of global css styling.

You can see a demo of the global css here.

CSS Modules

CSS Modules is a way to have separate css styles for each module.
Let's separate the buttons and paragraphs into different components.

import React from "react"
import styles from "./ButtonOne.module.css" // Import css modules stylesheet as styles

const ButtonOne = () => {
  return (
    <div>
      <button className={styles.button}>Hover Me</button>
    </div>
  )
}

export default ButtonOne
Enter fullscreen mode Exit fullscreen mode
import React from "react"
import styles from "./ButtonTwo.module.css" // Import css modules stylesheet as styles

const ButtonTwo = () => {
  return (
    <div>
      <button className={styles.button}>Hover Me</button>
    </div>
  )
}

export default ButtonTwo
Enter fullscreen mode Exit fullscreen mode
import React from "react"
import styles from "./Paragraph.module.css" // Import css modules stylesheet as styles

const Paragraph = () => {
  return (
    <div>
      <p className={styles.paragraph}>
        Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ea ab
        exercitationem soluta, consequatur obcaecati suscipit numquam dolorem,
        dignissimos quas nobis error repellat minus sed accusamus placeat, rerum
        illum magnam aspernatur?
      </p>
    </div>
  )
}

export default Paragraph
Enter fullscreen mode Exit fullscreen mode

Now let's add the styles for all the 3 components:

.button {
  background-color: #0ea5e9;
  border: none;
  color: white;
  border-radius: 0.5rem;
  padding: 0.5rem 1rem;
  cursor: pointer;
}

.button:hover {
  background-color: rgb(37, 99, 235);
}
Enter fullscreen mode Exit fullscreen mode
.button {
  background-color: rgb(239, 68, 68);
  border: none;
  color: white;
  border-radius: 0.5rem;
  padding: 0.5rem 1rem;
  cursor: pointer;
}

.button:hover {
  background-color: rgb(185, 28, 28);
}
Enter fullscreen mode Exit fullscreen mode
.paragraph {
  color: green;
  background: lightGreen;
  padding: 0.5rem 1rem;
}
Enter fullscreen mode Exit fullscreen mode

Finally, let's include all the components in our app:

import React from "react"
import ButtonOne from "./ButtonOne"
import ButtonTwo from "./ButtonTwo"
import Paragraph from "./Paragraph"

const CssModules = () => {
  return (
    <div>
      <ButtonOne />
      <Paragraph />
      <ButtonTwo />
    </div>
  )
}

export default CssModules
Enter fullscreen mode Exit fullscreen mode

If you inspect the demo page and see, you will observe that the classes are named in the format <ComponentName>_<ClassName>_<RandomString>.
This is done to avoid any conflicts between the css modules.

css modules

Advantages

  • Since each module has a separate css file, multiple developers can work in parallel without css or merge conflicts.

Disadvantages

  • There can be code duplication if the same style is used across the modules (which can be solved by pushing the common styles to a global stylesheet).

So far we have seen methods supported in react by default. Now we will see some third-party libraries, which help in styling the app.

Styled Components

Styled Components helps in defining the styles of a component by passing the actual css using template literals (back ticks), as shown below:

const Button = styled.button`
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 11rem;
  background: transparent;
  color: white;
  border: 2px solid white;
`
Enter fullscreen mode Exit fullscreen mode

Now we just need to include the Button component wherever it is needed.

To make use of styled components, we need to install it first (you may use npm i styled-components if you prefer to.):

yarn add styled-components
Enter fullscreen mode Exit fullscreen mode

Consider the following code:

import React from "react"
import styled, { css } from "styled-components"

const Button = styled.button`
  background: transparent;
  border-radius: 3px;
  border: 2px solid palevioletred;
  color: palevioletred;
  margin: 0.5em 1em;
  padding: 0.25em 1em;
  cursor: pointer;

  ${props =>
    props.primary &&
    css`
      background: palevioletred;
      color: white;
    `}
`

const Paragraph = styled.p`
  color: green;
  background: lightGreen;
  padding: 0.5rem 1rem;
`

const StyledComponents = () => {
  return (
    <div>
      <Button>Normal Button</Button>
      <Paragraph>
        Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ea ab
        exercitationem soluta, consequatur obcaecati suscipit numquam dolorem,
        dignissimos quas nobis error repellat minus sed accusamus placeat, rerum
        illum magnam aspernatur?
      </Paragraph>
      <Button primary>Primary Button</Button>
    </div>
  )
}

export default StyledComponents
Enter fullscreen mode Exit fullscreen mode

Styled Component can receive props and then apply different styles if that prop matches some condition.
Like in our case, we are changing the color and the background of the button, if the prop primary is set to true.

A demo of the above code can be found here.

We can also extend an existing style as shown below:

const Button = styled.button`
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 11rem;
  background: transparent;
  color: white;
  border: 2px solid white;
`
const EnhancedButton = styled(Button)`
  :hover {
    color: red;
  }
`
Enter fullscreen mode Exit fullscreen mode

The EnhancedButton will get all the styles from the Button component and the styles defined by itself.

Emotion

Emotion is alternative to styled-components.
We can install emotion in React by running the following command:

yarn add @emotion/react
Enter fullscreen mode Exit fullscreen mode

Now we can use emotion in our app:

/** @jsxRuntime classic */
// this comment tells babel to convert jsx to calls to a function called jsx instead of React.createElement
/** @jsx jsx */
import { css, jsx } from "@emotion/react"

const color = "white"

const Emotion = () => {
  return (
    <div>
      <button
        css={css`
          margin: 0.5em 1em;
          padding: 0.25em 1em;
          cursor: pointer;
          background-color: hotpink;
          font-size: 24px;
          border-radius: 4px;
          border: none;
          &:hover {
            color: ${color};
          }
        `}
      >
        Hover Me
      </button>
      <p
        css={css`
          color: green;
          background: lightGreen;
          padding: 0.5rem 1rem;
        `}
      >
        Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ea ab
        exercitationem soluta, consequatur obcaecati suscipit numquam dolorem,
        dignissimos quas nobis error repellat minus sed accusamus placeat, rerum
        illum magnam aspernatur?
      </p>
    </div>
  )
}

export default Emotion
Enter fullscreen mode Exit fullscreen mode

If you see, it is a bit similar to styled components, which uses the backtick syntax.

In fact, there is a package called @emotion/styled,
which helps in writing css in styled-component way!

The demo for the above code can be found here.

SASS support

If you wish to use SCSS in your app, then you can do so by installing node-sass:

yarn add node-sass@4.14.1
Enter fullscreen mode Exit fullscreen mode

Now create file named styles.scss with the following content:

$myColor: purple;

h2 {
  color: $myColor;
}
Enter fullscreen mode Exit fullscreen mode

Then use it in the component by importing it:

import React from "react"
import "./styles.scss"

const Sass = () => {
  return (
    <div>
      <h2>Styling using SASS</h2>
    </div>
  )
}

export default Sass
Enter fullscreen mode Exit fullscreen mode

Other libraries

There are other libraries as well like tailwind, and component libraries like Semantic UI, React Bootstrap, Ant Design, Chakra UI, BluePrint, Material UI, etc., which you can try out.

Source code and Demo

You can view the complete source code here and a demo here.

Top comments (0)