Motivation

styled-components is the result of wondering how we could enhance CSS for styling React component systems. By focusing on a single use case we managed to optimize the experience for developers as well as the output for end users.

Apart from the improved experience for developers, styled-components provides:

You get all of these benefits while still writing the CSS you know and love, just bound to individual components.

Installation

Installing styled-components only takes a single command and you're ready to roll:

npm install --save styled-components

NOTE

It's highly recommended (but not required) to also use the Babel plugin. It offers many benefits like more legible class names, server-side rendering compatibility, smaller bundles, and more.

If you're not using a module bundler or package manager we also have a global ("UMD") build hosted on the unpkg CDN. Simply add the following <script> tag to the bottom of your HTML file:

<script src="https://unpkg.com/styled-components/dist/styled-components.min.js"></script>

Once you've added styled-components you will have access to the global window.styled variable.

const Component = window.styled.div`
  color: red;
`

NOTE

This style of usage requires the react CDN bundles and the react-is CDN bundle to be on the page as well (before the styled-components script.)

Getting Started

styled components utilises tagged template literals to style your components.

It removes the mapping between components and styles. This means that when you're defining your styles, you're actually creating a normal React component, that has your styles attached to it.

This example creates two simple components, a wrapper and a title, with some styles attached to it:

// Create a Title component that'll render an <h1> tag with some styles
const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`;

// Create a Wrapper component that'll render a
<section> tag with some styles

const Wrapper = styled.section`
  padding: 4em;
  background: papayawhip;
`;

// Use Title and Wrapper like any other React
component – except they're styled!

render(
  <Wrapper>
    <Title>
      Hello World!
    </Title>
  </Wrapper>
);
Hello World!

This is a live editor, so play around with the code to get a feel for what it's like to work with styled-components!

NOTE

The CSS rules are automatically vendor prefixed, styled-components takes care of that for you!

Adapting based on props

You can pass a function ("interpolations") to a styled component's template literal to adapt it based on its props.

This button component has a primary state that changes its color. When setting the primary prop to true, we are swapping out its background and text color.

const Button = styled.button`
  /* Adapt the colors based on primary prop */
  background: ${props => props.primary ?
"palevioletred" : "white"};
  color: ${props => props.primary ? "white" :
"palevioletred"};

  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
`;

render(
  <div>
    <Button>Normal</Button>
    <Button primary>Primary</Button>
  </div>
);
Extending styles

Quite frequently you might want to use a component, but change it slightly for a single case. Now, you could pass in an interpolated function and change them based on some props, but that's quite a lot of effort for overriding the styles once.

To easily make a new component that inherits the styling of another, just wrap it in the styled() constructor. Here we use the button from the last section and create a special one, extending it with some color-related styling:

// The Button from the last section without the
interpolations
const Button = styled.button`
  color: palevioletred;
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
`
;

// A new component based on Button, but with some
override styles
const TomatoButton = styled(Button)`
  color: tomato;
  border-color: tomato;
`;


render(
  <div>
    <Button>Normal Button</Button>
    <TomatoButton>Tomato Button</TomatoButton>
  </div>
);

We can see that the new TomatoButton still resembles Button, while we have only added two new rules.

In some cases you might want to change which tag or component a styled component renders. This is common when building a navigation bar for example, where there are a mix of anchor links and buttons but they should be styled identically.

For this situation, we have an escape hatch. You can use the "as" polymorphic prop to dynamically swap out the element that receives the styles you wrote:

const Button = styled.button`
  display: inline-block;
  color: palevioletred;
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
  display: block;
`;

const TomatoButton = styled(Button)`
  color: tomato;
  border-color: tomato;
`;

render(
  <div>
    <Button>Normal Button</Button>
    <Button as="a" href="/">Link with Button
styles
</Button>
    <TomatoButton as="a" href="/">Link with
Tomato Button styles</TomatoButton>
  </div>
);

This works perfectly fine with custom components too!

const Button = styled.button`
  display: inline-block;
  color: palevioletred;
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
  display: block;
`;

const ReversedButton = props => <Button
{...props}
children=
{props.children.split('').reverse()} />


render(
  <div>
    <Button>Normal Button</Button>
    <Button as={ReversedButton}>Custom Button
with Normal Button styles</Button>
  </div>
);

NOTE

If you are still on an older version than v4, you can use the .withComponent or .extend API's to achieve the same result as with the "as" prop, but note that this is discouraged as with v4 .extend was removed and .withComponent was marked as a candidate for future deprecation.