Published on

How to use Styled Components in React

Overview

A blog post on using Styled Components in our React Applications.

Using Styled Components in React

There are many ways to style components in React like using inline CSS, importing CSS files, TailwindCSS, etc. But I find styled components fascinating as it gives extra powers to our CSS by adding logic to it among other things. It lets us write CSS in JavsScript files.

Let's see how to use styled-components in our React apps.

We can add styled-components to our project by using the following command from the terminal.

npm install styled-components --save

Creating a styled component

Let us create a very basic component that returns a simple button.

import React from 'react'

export default function App() {
  return (
    <div>
      <button>Button</button>
    </div>
  )
}

Now let's style it using the style components.

import React from 'react'
import styles from 'styled-components'

const Button = styles.button`
  background-color: blue;
  text: white;
  padding: 10px 20px;
  background-color: blue;
  color: white;
  font-size: 16px;
  padding: 10px 20px;
  border-radius: 5px;
  cursor: pointer;
  }
  `

export default function App() {
  return (
    <div>
      <Button>Button</Button>
    </div>
  )
}

This outputs the following on the screen:

styled component

We imported the style component library at the top and we basically created a component with the styles attached to it. We have used ES6’s tagged template literals here to style the components.

Extending the styled component

Styled components also give us the option to extend the existing styles from the previously made components. Suppose we want to create a new button with a different style. We can simply extend the style of the previous button and add new additional styles.

import React from 'react'
import styles from 'styled-components'

const Button = styles.button`
  background-color: blue;
  text: white;
  padding: 10px 20px;
  background-color: blue;
  color: white;
  font-size: 16px;
  padding: 10px 20px;
  border-radius: 5px;
  cursor: pointer;
  }
  `

const NewButton = styled(Button)`
  background-color: lightcyan;
  color: black;
`

const NewNewButton = styled(NewButton)`
  &:hover {
    background-color: greenyellow;
    color: blue;
  }
`

export default function App() {
  return (
    <div>
      <Button>Button</Button>
    </div>
  )
}

The above code outputs the following on the screen. We have extended the style two times with very little effort and created new components i.e NewButton and NewNewButton

extending-styles

Adapting styles based on Props

To make our components behave conditionally we can pass props to them. This would help us in the conditional styling of our styled components.

Let’s see in the example below:

import React from 'react';
import styled from "styled-components";

const Button = styled.button`
  background-color: blue;
  color: white;
  font-size: 16px;
  padding: 10px 20px;
  border-radius: 5px;
  cursor: pointer;
  transition: all 0.2s ease-in-out;
`;

const NewButton = styled(Button)`
  background-color: lightcyan;
  color: ${props => props.$primary ? "grey" : "#BF4F74"};
  `;

const NewNewButton = styled(NewButton)`
 &:hover {
    background-color: greenyellow;
    color: blue;
  }`

export default function App() {
  return (
    <div className="App">
      <Button>Hello</Button>
      <NewButton $primary>New Button </NewButton>
			<NewNewButton>New New Button</NewNewButton>
    </div>
  );
}

We have added conditional styling to the styled component and passed the “$primary” as a parameter to the component in the main App return. Also, notice how the third button i.e. NewNewButton has the text color inherited from the NewButton component. It is due to extending the style of NewButton to NewNewButton.

Using CSS variables

We use CSS variables in our project so that it becomes easy to change the style in our entire project. Styled components also support CSS variables which is very important in handling styling across our app easily.

First, we need to declare CSS variables in our index.css or styles.css file in our src folder.

:root{
--primary-text: #8F00FF
}

We then import the styles.css/index.css file in our file at the top

import './index.css';

After the CSS file import, we can use CSS variables in our styled component just like any other attribute.

import "./styles.css";
import styled from "styled-components";

const Button = styled.button`
  background-color: var(--primary-bg);
  color: white;
  font-size: 16px;
  padding: 10px 20px;
  border-radius: 5px;
  cursor: pointer;
  transition: all 0.2s ease-in-out;
  `;

Adding Themes to our App

Adding themes to our websites and apps is important and a bare minimum expectation from developers nowadays. I like websites and apps that provide dark mode options.

Styled Components provides theme support via ThemeProvider wrapper which itself works by using the React’s Context API under the hood.

First, we need to import ThemeProvider from the styled-components. Then we need to wrap our main app component with the ThemeProvider and theme attribute.

// App.js
import React, { useState } from 'react';
import './App.css';
import { ThemeProvider } from 'styled-components';
import Container from './Container';

const baseTheme = {
  background: 'grey',
  color: 'yellow',
};
const darkTheme = {
  background: 'black',
  color: 'white',
};

export default function App() {
  const [theme, setTheme] = useState('light'); // Start with 'light' theme

  const themes = {
    light: baseTheme,
    dark: darkTheme,
  };

  return (
    <ThemeProvider theme={themes[theme]}>
      <Container theme={theme} setTheme={setTheme} />
    </ThemeProvider>
  );
}

We are wrapping the Container component with the ThemeProvider and passing the theme and setTheme as props to the inner child. Let us see the Container component.

// Container.js
import styled from 'styled-components';

const Wrapper = styled.div`
  background: ${props => props.theme.background};
  color: ${props => props.theme.color};

`

export default function Container({theme,setTheme}) {
  const themeHandler = () => {
    if (theme === 'light') {
      setTheme('dark');
    } else {
      setTheme('light');
    }
  };

  return (
    <Wrapper>
      <p>This is a sample paragraph</p>
      <button onClick={themeHandler}>Click Me</button>
    </Wrapper>
  );
}

Nesting is a powerful feature in Styled Components that allows you to write cleaner and more organized CSS for your React components. It mirrors the hierarchy of your component structure, making your styles more intuitive and easier to manage. With nesting, you can define child elements' styles within the parent component's style block. This encapsulation helps prevent class name clashes and promotes modularity. To nest styles, you can directly reference child elements and apply styles as if you were writing regular CSS. This is particularly useful for pseudo-selectors, media queries, and hover effects.

Nesting Styles in Styled Components

I find nesting css styles for our React Component as an important feature that allows us to write clean and more organized css. It makes our styling more intuitive and easier to manage. Nesting styles are simple and we can also define things like pseudo-selectors, media queries, hover effects, etc.

import styled from 'styled-components';

const Button = styled.button`
  background-color: #3498db;
  color: #ffffff;
  padding: 10px 20px;
  border: none;
  cursor: pointer;

  &:hover {
    background-color: #2980b9;
  }

  @media (max-width: 768px) {
    font-size: 14px;
  }
`;

// Usage in a component
const MyComponent = () => {
  return (
    <div>
      <Button>Click Me</Button>
    </div>
  );
};

Wrapping Up

I hope you understood how to use Styled Components in React Applications. For Official documentation and more advanced usage you can visit official documentation https://styled-components.com/ . Do let me know what you think. Thank you for reading!