FAQs

Can I nest rules?

Yes: nesting is a feature intentionally ported from Sass. Used sparingly it's a great way to lighten your code by reducing the need to create explicit classes for every element.

It can also be used by parent components to define contextual constraints that aren't properly a concern of the affected children:

const EqualDivider = styled.div`
  display: flex;
  margin: 0.5rem;
  padding: 1rem;
  background: papayawhip;
  ${props => props.vertical && 'flex-direction: column;'}

  > * {
    flex: 1;

    &:not(:first-child) {
      ${props => props.vertical ? 'margin-top' : 'margin-left'}: 1rem;
    }
  }
`;

const Child = styled.div`
  padding: 0.25rem 0.5rem;
  background: palevioletred;
`;

render(
  <div>
  <EqualDivider>
    <Child>First</Child>
    <Child>Second</Child>
    <Child>Third</Child>
  </EqualDivider>
  <EqualDivider vertical>
    <Child>First</Child>
    <Child>Second</Child>
    <Child>Third</Child>
  </EqualDivider>
  </div>
);
First
Second
Third
First
Second
Third

It's also incredibly convenient to co-locate media queries, since we can see at a glance exactly how the component will respond at any resolution.

const ColorChanger = styled.section`
  background: papayawhip;
  color: palevioletred;

  @media(min-width: 768px) {
    background: mediumseagreen;
    color: papayawhip;
  }
`;

render(
  <ColorChanger href="#">
    <h2>Hello world!</h2>
  </ColorChanger>
);

Hello world!

When should I use styled()?

Behind the scenes

The styled() factory generates new component styles with a new class. The classnames are then passed to the React component via the className prop. Calling extend creates new component styles by extending the old one, and thus doesn't generate two classes for a single component. (styled() factory does that)

Which one should you use

We recommend to use .extend where possible for internal StyledComponents. Try to use the styled() factory however for external or cross-file components where it isn't clear what it's going to be when writing the wrapper StyledComponent.

Keep in mind that wrapping your own components with styled() is not recommended. It should always be attempted to only have StyledComponents and not wrap any wrappers and containers at a higher level. Otherwise your styling logic will be scattered across multiple files, and it will become tempting to use child selectors to target elements inside your containers. This of course increases the specificity of rules we generate, which can lead to more code and styled() wrappers which try to compensate for this up in your component hierarchy. Instead, you can keep your UI code clean by bundling your styling at the lowest level, and utilise themes, inheritance, mixins, props, and even "reverse selectors".

Also if you haven't read the section on Styling any components and extend yet, they contain more information and examples.

Can I use CSS frameworks?

Integrating an existing CSS framework with styled-components is really easy! You can use its existing class names alongside your components.

Consider you have an existing app with some CSS that have the classes: .small and .big. Try to swap out the .small class with .big in the example below:

const Button = styled.button.attrs({
  className: 'small',
})`
  background: black;
  color: white;
  cursor: pointer;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid black;
  border-radius: 3px;
`;

render(
  <div>
    <Button>Styled Components</Button>
    <Button>The new way to style components!</Button>
  </div>
);

Please do read about the attrs method to learn how arbitary props can be passed down to a styled component without wrapping it.

How can I override styles with higher specificity?

The way to override styles with a high specificity is to simply increase the specificity of your own styles. This could be done using !important, but that's error prone and generally not a good idea.

We recommend the following technique:

const MyStyledComponent = styled(AlreadyStyledComponent)`
  &&& {
    color: palevioletred;
    font-weight: bold;
  }
`;

Each & gets replaced with the generated class, so the injected CSS then looks like this:

.MyStyledComponent-asdf123.MyStyledComponent-asdf123.MyStyledComponent-asdf123 {
  color: palevioletred;
  font-weight: bold;
}

The repeated class bumps the specificity high enough to override the source order without being very tedious to write!

How can I override inline styles?

Inline styles will always take precedence over external CSS, so you cannot override it by simply increasing specificity.

There is a neat trick however, which is to use the style element-attr CSS Selector in conjunction with !important:

const MyStyledComponent = styled(InlineStyledComponent)`
  &[style] {
    font-size: 12px !important;
    color: blue !important;
  }
`;

Why do my DOM nodes have two classes?

Each node actually has two classes connected to it;

One is static per component, meaning each element of a styled component has this class. It hasn't any style attached to it. Instead, it's used to quickly identify which styled component a DOM objects belongs to or to make minor changes in the DevTools.

The other is dynamic, meaning it will be different for every element of your styled component with different props, based on what the interpolations result in.

For example, the styled component <Button /> would render with the same static class every time. If the styles are changed using interpolations, like <Button secondary />, then the dynamic class will be a different one, while the static class would remain the same.

When to use attrs?

You can pass in attributes to styled components using attrs, but it is not always sensible to do so.

The rule of thumb is to use attrs when you want every instance of a styled component to have that prop, and pass props directly when every instance needs a different one:

const PasswordInput = styled.input.attrs({
  // Every <PasswordInput /> should be type="password"
  type: 'password'
})``

// This specific one is hidden, so let's set aria-hidden
<PasswordInput aria-hidden="true" />

The same goes for props that can be inferred based on the "mode" of another prop. In this case you can set a property on attrs to a function that computes that prop based on other props.

I am a library author. Should I bundle styled-components with my library?

If you are a library author we recommend that you should not bundle styled-components module with your library. Instead, mark it as external dependency during your library build, move it from dependencies to devDependencies and include it in peerDependencies list in your package.json file:

  {
-   "dependencies" : {
+   "devDependencies" : {
      "styled-components": "^2.4.0"
    },
+   "peerDependencies" : {
+     "styled-components": "^2.4.0"
+   }
  }

Why am I getting a warning about several instances of module on the page?

If you are seeing a warning message in the console as the one below, you probably have several instances of styled-components module initialized on the page.

It looks like there are several instances of 'styled-components' initialized in this application.
This may cause dynamic styles not rendering properly, errors happening during rehydration process
and makes you application bigger without a good reason.

If you are using a building tool like Webpack, consider checking your bundle for duplication
of 'styled-components' module.

This may cause dynamic styles not working properly or even errors during rehydration if you are using server-side rendering.

Possible reasons

There are several common reasons for this to happen:

  • You have several applications that are using styled-components running on the same page (e.g., several entry points in Webpack are loaded on the same page)
  • You have another styled-components library somewhere in your dependencies
  • You have a monorepo structure for your project (e.g, lerna, yarn workspaces) and styled-components module is a dependency in more than one package (this one is more or less the same as the previous one)

Running multiple applications on one page

If you have several applications running on one page, consider using one styled-components module for all of them. If you are using Webpack, you can use CommonsChunkPlugin to create an explicit vendor chunk, that will contain styled-components module:

  module.exports = {
    entry: {
+     vendor: ['styled-components'],
      app1: './src/app.1.js',
      app2: './src/app.2.js',
    },
    plugins: [
+     new webpack.optimize.CommonsChunkPlugin({
+       name: "vendor",
+       minChunks: Infinity,
+     }),
    ]
  }

Duplicated module in node_modules

If you think that the issue is in duplicated styled-components module somewhere in your dependencies, there are several ways to check this. You can use npm ls styled-components, yarn list styled-components or find -L ./node_modules | grep /styled-components/package.json commands in your application folder.

If none of these commands identified the duplication, try analyzing your bundle for multiple instances of styled-components. You can just check your bundle source, or use a tool like source-map-explorer or webpack-bundle-analyzer.

If you identified that duplication is the issue that you are encountering there are several things you can try to solve it:

If you are using npm you can try running npm dedupe. This command searches the local dependencies and tries to simplify the structure by moving common dependencies further up the tree.

Note

Be aware that npm dedupe doesn't work well with symlinked folders (i.e., when you use npm link)

If you are using Webpack, you can change the way it will resolve styled-components module. You can overwrite the default order in which Webpack will look for your dependencies and make your application node_modules more prioritized than default node module resolution order:

  resolve: {
+   modules: [path.resolve(appFolder, 'node_modules'), 'node_modules'],
  }

Or you can alias styled-components specifically to make Webpack always resolve styled-components in one place:

  resolve: {
+   alias: {
+     'styled-components': path.resolve(appFolder, 'node_modules', 'styled-components'),
+   }
  }

Which browsers are supported?

All browsers that React supports are supported.

This means all major browsers including Internet Explorer 9.