How to Pass className to Styled-Components in React

How to Pass className to Styled-Components in React

In this article, we discuss how to use className with styled-components. Styled-components is a CSS in JS library, which allows you to write CSS styles in ES6 template literals. If you are not familiar with styled-components, you can learn the basics here.

I am a fan of styled components majorly because:

  • I don't have to worry about style leaking
  • Dynamic styling based on props passed to components
  • and the best part of it all is I don't have to maintain multiple CSS files

But the need to pass classNames occasionally arises, which we will see just now. We are going to look at styling a badge component based on the className given to it, as shown below;

MacBook Pro 14_ - 2.png

First, install styled-components in your project,

npm install styled-components

Next, create a Badge component with dynamic props attached to it. We can do so using the attrs object. It takes a function that receives props from the component.

The most common use case of attrs is when every instance of a styled component needs to have that prop. Here is a simple example to understand how it works;

export const TextInput = styled.input.attrs(() => ({
  type: 'text'
})`
/* existing styling... */
`

<TextInput placeholder='Enter name' />

So each time an instance of TextInput gets invoked, you don't have to specify the type. You can also pass dynamic props, as we will see in our <Badge /> component

import styled from "styled-components";

export const Badge = styled.div.attrs((props) => ({
  className: props.className
}))`
  width: fit-content;
  padding: 2px 10px;
  border-radius: 16px;
  display: grid;
  place-items: center;
  font-size: 14px;
`

So now we can write regular CSS with classNames inside our <Badge /> component;

export const Badge = styled.div.attrs((props) => ({
  className: props.className
}))`
/* ...existing styles */

  &.react {
    background-color: #f2fbdc;
    color: #a7c957;
  }

  &.styled-components {
    background-color: #f9f5ff;
    color: #6941c6;
   } 

  &.web-dev {
    background-color: #fdf2fa;
    color: #c11574;
  }
`;

Inside App.js we can use our <Badge /> component,

import { Badge, BadgeWrapper } from "./App.styles";

export default function App() {
  return (
      ...
      <BadgeWrapper>
        <Badge className="react">React</Badge>
        <Badge className="styled-components">Styled-components</Badge>
      </BadgeWrapper>
    </Wrapper>
  );
}

And that's it. We can also specify static props that will act as our default className in case an instance of our component does not have a className specified.

export const Badge = styled.div.attrs((props) => ({
  className: props.className || "default"
}))`
  width: fit-content;
  padding: 2px 10px;
  border-radius: 16px;
  display: grid;
  place-items: center;
  font-size: 14px;

&.default {
    background-color: #eef4ff;
    color: #3538cd;
  }

&.react {
    background-color: #f2fbdc;
    color: #a7c957;
  }

/* ...existing styles */
`

So the <Badge /> component will render with the default className,

<BadgeWrapper>
        <Badge className="react">React</Badge>
        <Badge className="styled-components">Styled-components</Badge>
        <Badge>Web development</Badge>
</BadgeWrapper>

You can also access the complete code of this tutorial, with styling, here