Tooling

Babel Plugin
v2

This plugin adds support for server-side rendering, for minification of styles and gives you a nicer debugging experience.

Usage

Install the babel-plugin first:

npm install --save-dev babel-plugin-styled-components

Then add it to your babel configuration like so:

{
  "plugins": ["babel-plugin-styled-components"]
}

Server-side rendering

Note

This option is turned off by default

By adding a unique identifier to every styled component this plugin avoids checksum mismatches due to different class generation on the client and on the server. If you do not use this plugin and try to server-side render styled-components React will complain.

You can enable it with the ssr option:

{
  "plugins": [
    ["babel-plugin-styled-components", {
      "ssr": true
    }]
  ]
}

Better debugging

This options adds the components' name and displayName to the class name attached to the DOM node. In your browser's DevTools you'll see: <button class="Button-asdf123 asdf123" /> instead of just <button class="asdf123" />.

This also adds support for showing your components' real name in the React DevTools. Consider writing a styled component that renders a button element, called MyButton. It will normally show up as <styled.button> for all of your components, but with this plugin they show <MyButton />.

This makes it easier to find your components and to figure out where they live in your app.

If you don't need this feature, you can disable it with the displayName option:

{
  "plugins": [
    ["babel-plugin-styled-components", {
      "displayName": false
    }]
  ]
}

Preprocessing

Note

This is experimental and we don't yet know of all limitations and bugs! Consider this non-production ready for now. ⚠️

This plugin preprocesses your styles with stylis and uses the no-parser.js entrypoint on styled-components. This effectively removes stylis from your runtime bundle and should slightly improve runtime performance and shrink your bundle size.

It automatically disables the minify option, since stylis already does some minification on your CSS.

You can enable preprocessing with the preprocess option:

{
  "plugins": [
    ["babel-plugin-styled-components", {
      "preprocess": true
    }]
  ]
}

Minification

Note

This option is turned on by default. If you experience mangled CSS results, turn it off and open an issue please.

This plugin minifies your styles in the tagged template literals, giving you big bundle size savings.

This operation may potentially break your styles in some rare cases, so we recommend to keep this option enabled in development if it's enabled in the production build.

You can disable minification with the minify option:

{
  "plugins": [
    ["babel-plugin-styled-components", {
      "minify": false
    }]
  ]
}

Template String Transpilation

We transpile styled-components tagged template literals down to a smaller representation than what Babel normally does, because styled-components template literals don't need to be 100% spec compliant.

Read more about Tagged Template Literals in our dedicated section explaining them.

You can use the transpileTemplateLiterals option to turn this feature off.

{
  "plugins": [
    ["babel-plugin-styled-components", {
      "transpileTemplateLiterals": false
    }]
  ]
}

Test Utilities

Jest Styled Components is a set of utilities for testing Styled Components with Jest. This package improves the snapshot testing experience and provides a brand new matcher to make expectations on the style rules.

Installation

yarn add --dev jest-styled-components

Snapshot Testing

When we are building a UI with Styled Components, we want to make sure the output doesn't change unexpectedly. Snapshot testing is an excellent way to test React components, and this package makes the experience even more delightful by adding the style to the snapshots.

Here's an example of a test:

import React from 'react'
import styled from 'styled-components'
import renderer from 'react-test-renderer'
import 'jest-styled-components'

const Button = styled.button`
  color: red;
`

test('it works', () => {
  const tree = renderer.create(<Button />).toJSON()
  expect(tree).toMatchSnapshot()
})

And here's an example of the resulting snapshot:

exports[`it works 1`] = `
.c0 {
  color: green;
}

<button
  className="c0"
/>
`;

For a real world demo, check out this website's repository.

toHaveStyleRule

If we only want to check whether a particular style has been appled to an element, we can use the toHaveStyleRule matcher. This function takes two required parameters, a property (string) and a value (string or RegExp), and an optional object to search for rules nested within an at-rule or to add modifiers to the class selector.

import React from 'react'
import styled from 'styled-components'
import renderer from 'react-test-renderer'
import 'jest-styled-components'

const Button = styled.button`
  color: red;
  @media (max-width: 640px) {
    &:hover {
      color: green;
    }
  }
`

test('it works', () => {
  const tree = renderer.create(<Button />).toJSON()
  expect(tree).toHaveStyleRule('color', 'red')
  expect(tree).toHaveStyleRule('color', 'green', {
    media: '(max-width: 640px)',
    modifier: ':hover',
  })
})

Stylelint

Lint your styled components with stylelint!

Installation

You need:

(npm install --save-dev
  stylelint
  stylelint-processor-styled-components
  stylelint-config-styled-components
  stylelint-config-standard)

Setup

Add a .stylelintrc file to the root of your project:

{
  "processors": ["stylelint-processor-styled-components"],
  "extends": [
    "stylelint-config-standard",
    "stylelint-config-styled-components"
  ],
  "syntax": "scss"
}
Note

Setting the syntax to scss is needed for nesting and interpolation support!

Then you need to run stylelint. Add a lint:css script to your package.json which runs stylelint with a glob to all of your styled components:

{
  "scripts": {
    "lint:css": "stylelint './src/**/*.js'"
  }
}
Note

The processor ignores javascript files that don't contain any styled-components, so don't worry about being too broad as long as you restrict it to javascript (or TypeScript).

Now you can lint your CSS by running the script! 🎉

npm run lint:css

Webpack

If you want to lint on build, rather than as a separate command, you can use the stylelint-custom-processor-loader for webpack.

stylelint-config-styled-components

When using this processor a couple of stylelint rules throw errors that cannot be prevented, like no-empty-source or no-missing-end-of-source-newline. There's also a couple rules which we need to enforce, like no-vendor-prefix rules. (styled-components automatically vendor prefixes your code, so you don't need to do it manually)

The stylelint-config-styled-components will automatically disable rules that cause conflicts.

Note

You can override rules defined in shared configs in your custom .stylelintrc.

Interpolation tagging

Sometimes stylelint can throw an error (e.g. CssSyntaxError) even though nothing is wrong with your CSS. This is often due to an interpolation, more specifically the fact that the processor doesn't know what you're interpolating.

A simplified example:

const something = 'background';

const Button = styled.div`
  ${something}: papayawhip;
`

When you have interpolations in your styles the processor can't know what they are, so it makes a good guess and replaces them with a syntactically equivalent placeholder value. Since stylelint is not a code flow analysis tool this doesn't cover all edge cases and the processor will get it wrong every now and then.

Interpolation tagging allows you to tell the processor what an interpolation is in case it guesses wrong; it can then replace the interpolation with a syntactically correct value based on your tag.

For example:

const something = 'background';

const Button = styled.div`
  // Tell the processor that "something" is a property
  ${/* sc-prop */ something}: papayawhip;
`

Now the processor knows that the something interpolation is a property, and it can replace the interpolation with a property for linting.

To tag an interpolation add a comment at either the start or the end of the interpolation. (${/* sc-tag */ foo} or ${bar /* sc-tag */}) Tags start with sc- and, if specified, a tag overrides the processors guess about what the interpolation is.

Tags

The full list of supported tags:

  • sc-block
  • sc-selector
  • sc-declaration
  • sc-property
  • sc-value
Note

If you are in doubt of the vocabulary you can refer to this CSS vocabulary list with examples.

For example, when you interpolate another styled component, what you really interpolate is its unique selector. Since the processor doesn't know that, you can tell it to replace it with a selector when linting:

const Wrapper = styled.div`
  ${/* sc-selector */ Button} {
    color: red;
  }
`;

You can also use shorthand tags to avoid cluttering the code. For example:

const Wrapper = styled.div`
  ${/* sc-sel */ Button} {
    color: red;
  }
`;

sc-custom

sc-custom is meant to be used as a last resort escape hatch. Prefer to use the standard tags if possible!

On top of the above standard tags the processor also has the sc-custom tag to allow you to cover more unique and uncommon edge cases. With the sc-custom tag you can decide yourself what the placeholder value will be.

For example:

// Switch between left and right based on language settings passed through via the theme
const rtlSwitch = props => props.theme.dir === 'rtl' ? 'left' : 'right';

const Button = styled.button`
  background: green;
  // Tell the processor to replace the interpolation with "left"
  // when linting
  margin-${/* sc-custom 'left' */ rtlSwitch}: 12.5px;
`;

Syntax notes

Turning rules off from within your JS/CSS

Turn off rules with stylelint-disable comments (see the stylelint documentation for all allowed syntax) both inside and outside of the tagged template literals.

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

// Disable stylelint from within the tagged template literal
const Wrapper = styled.div`
  /* stylelint-disable */
  background-color: 123;
`;

// Or from the JavaScript around the tagged template literal
/* stylelint-disable */
const Wrapper = styled.div`
  background-color: 123;
`;

Template literal style and indentation

In order to have stylelint correctly apply indentation rules the processor needs to do a bit of opinionated preprocessing on the styles, which results in us only officially supporting one indentation style. (the supported style is the "default" one as shown in all the documentation)

The important thing is that you put the closing backtick on the base level of indentation as follows:

Right

if (condition) {
  const Button = styled.button`
    color: red;
  `
}

Wrong

if (condition) {
  const Button = styled.button`
    color: red;
`
}
if (condition) {
  const Button = styled.button`
    color: red;`
}

It may be that other tagged template literal styles are coincidentally supported, but no issues will be handled regarding indentation unless the above style was used.

Continue on the next page

FAQs