This is the default export. This is a low-level factory we use to create the styled.tagname helper methods.
Arguments | Description |
---|---|
1. component / tagname | Either a valid react component or a tagname like 'div'. |
Returns a function that accepts a tagged template literal and turns it into a StyledComponent.
You can see this method being introduced in the Getting started section.
This is what you pass into your styled calls – a tagged template literal. This is an ES6 language feature. You can learn more about them in the Tagged Template Literals section.
Inputs | Description |
---|---|
Rule | Any CSS rules (string) |
Interpolation | This can either be a string or a function. Strings are combined with the rules as-is. Functions will receive the styled component's props as the first and only argument. |
Read more about how to adapt styling based on props in the Adapting based on props section.
The properties that are passed into an interpolated function get attached a special property, theme, which is injected by a higher level ThemeProvider component. Check the section on Theming for more information on this.
✨ Magic
You can also return objects from interpolations or input objects directly, and they'll be treated as inline styles. However this is highly discouraged, as the CSS syntax has support for pseudo selectors, media queries, nesting, etc., which the object syntax doesn't.
A styled React component. This is returned when you call styled.tagname or styled(Component) with styles.
This component can take any prop. It passes it on to the HTML node if it's a valid attribute, otherwise it only passes it into interpolated functions. (see Tagged Template Literal)
You can pass an arbitrary classname to a styled component without problem and it will be applied next to the styles defined by the styled call. (e.g. <MyStyledComp className="bootstrap__btn" />)
This is a chainable method that attaches some props to a styled component. The first and only argument is an object that will be merged into the rest of the component's props. The attrs object accepts the following values:
Values | Description |
---|---|
Prop Value | These can be of any type, except functions. They'll stay static and will be merged into the existing component props. |
Prop Factory | A function that receives the props that are passed into the component and computes a value, that is then going to be merged into the existing component props. |
Returns another StyledComponent.
Learn more about this constructor in the Attaching Additional Props section.
This is a method that creates a new StyledComponent with a different tag or component applied to it, but all the same rules of the one it's called on.
Arguments | Description |
---|---|
1. component / tagname | Either a valid react component or a tagname like `'div'`. |
Returns a new StyledComponent with the new tag / component being applied when it's used.
As of styled-components v4 the withComponent API is now a candidate for deprecation. In all likelihood, you probably want to use the new "as" prop to simply switch what element/component being rendered since the withComponent API is destructive toward styles if the lowest-wrapped component is a StyledComponent.
If you want to keep all the styling you've applied to a component but just switch out what's being ultimately rendered (be it a different HTML tag or a different custom component), you can use the "as" prop to do this at runtime.
This sort of thing is very useful in use cases like a navigation bar where some of the items should be links and some just buttons, but all be styled the same way.
If you choose to wrap another component with the styled() HOC that also accepts an "as" prop, use "forwardedAs" to pass along the desired prop to the wrapped component.
If you want to prevent props meant to be consumed by styled components from being passed to the underlying React node or rendered to the DOM element, you can prefix the prop name with a dollar sign ($), turning it into a transient prop.
In this example, $draggable isn't rendered to the DOM like draggable is.
Drag me!
This is a more dynamic, granular filtering mechanism than transient props. It's handy in situations where multiple higher-order components are being composed together and happen to share the same prop name.shouldForwardProp works much like the predicate callback of Array.filter. A prop that fails the test isn't passed down to underlying components, just like a transient prop.
Keep in mind that, as in this example, other chainable methods should always be executed after .withConfig.
Drag Me!
Optionally, shouldForwardProp can take a second parameter that provides access to the default validator function. This function can be used as a fallback, and of course, it also works like a predicate, filtering based on known HTML attributes.
A helper component for theming. Injects the theme into all styled components anywhere beneath it in the component tree, via the context API. Check the section on Theming.
Props | Description |
---|---|
theme | An object that will be injected as theme into all interpolations in styled components beneath the provider. |
I'm mediumseagreen!
Sometimes you don't want to create an extra component just to apply a bit of styling. The css prop is a convenient way to iterate on your components without settling on fixed component boundaries yet. It works on both normal HTML tags as well as components, and supports everything any styled component supports, including adapting based on props, theming and custom components.
To enable support for the css prop you have to use the Babel plugin.
<div css={` background: papayawhip; color: ${props => props.theme.colors.text}; `} /> <Button css="padding: 0.5em 1em;" />
Under the hood, the Babel plugin turns any element with a css prop into a styled component. For example, the above code becomes:
import styled from 'styled-components'; const StyledDiv = styled.div` background: papayawhip; color: ${props => props.theme.colors.text}; ` const StyledButton = styled(Button)` padding: 0.5em 1em; ` <StyledDiv /> <StyledButton />
Note that you don't even have to add the import, the Babel plugin does that automatically! (unless you're using the Babel macro, see below)
You can use the Babel macro to make this work in create-react-app. Unfortunately, Babel macros only run when imported so the import can not be added automatically. The above code works perfectly if you add the import to the macro manually:
import styled from 'styled-components/macro' <div css={` background: papayawhip; color: ${props => props.theme.colors.text}; `} /> <Button css="padding: 0.5em 1em;" />
To prevent TypeScript errors on the css prop on arbitrary elements, install @types/styled-components and add the following import once in your project:
import {} from 'styled-components/cssprop'
See https://github.com/DefinitelyTyped/DefinitelyTyped/issues/31245#issuecomment-446011384 for more information.
A helper function to generate a special StyledComponent that handles global styles. Normally, styled components are automatically scoped to a local CSS class and therefore isolated from other components. In the case of createGlobalStyle, this limitation is removed and things like CSS resets or base stylesheets can be applied.
Arguments | Description |
---|---|
1. TaggedTemplateLiteral | A tagged template literal with your CSS and interpolations. |
Returns a StyledComponent that does not accept children. Place it at the top of your React tree and the global styles will be injected when the component is "rendered".
import { createGlobalStyle } from 'styled-components' const GlobalStyle = createGlobalStyle` body { color: ${props => (props.whiteColor ? 'white' : 'black')}; } ` // later in your app <React.Fragment> <GlobalStyle whiteColor /> <Navigation /> {/* example of other top-level stuff */} </React.Fragment>
Since the GlobalStyle component is a StyledComponent, that means it also has access to theming from the <ThemeProvider> component if provided.
import { createGlobalStyle, ThemeProvider } from 'styled-components' const GlobalStyle = createGlobalStyle` body { color: ${props => (props.whiteColor ? 'white' : 'black')}; font-family: ${props => props.theme.fontFamily}; } ` // later in your app <ThemeProvider theme={{ fontFamily: 'Helvetica Neue' }}> <React.Fragment> <Navigation /> {/* example of other top-level stuff */} <GlobalStyle whiteColor /> </React.Fragment> </ThemeProvider>
A helper function to generate CSS from a template literal with interpolations. You need to use this if you return a template literal with functions inside an interpolation due to how tagged template literals work in JavaScript.
If you're interpolating a string you do not need to use this, only if you're interpolating a function.
Arguments | Description |
---|---|
1. TaggedTemplateLiteral | A tagged template literal with your CSS and interpolations. |
Returns an array of interpolations, which is a flattened data structure that you can pass as an interpolation itself.
import styled, { css } from 'styled-components' const complexMixin = css` color: ${props => (props.whiteColor ? 'white' : 'black')}; ` const StyledComp = styled.div` /* This is an example of a nested interpolation */ ${props => (props.complex ? complexMixin : 'color: blue;')}; `
If you leave off the css your function will be toString()ed and you'll not get the results you expected.
A helper method to create keyframes for animations.
Arguments | Description |
---|---|
1. TaggedTemplateLiteral | A tagged template literal with your keyframes inside. |
Returns a Keyframes model, to be used in your animation declarations. You can use the getName() API on the returned model if you wish to obtain the generated animation name.
In styled-components v3 and below, the keyframes helper directly returned the animation name instead of an object with the getName method.
import styled, { keyframes } from 'styled-components' const fadeIn = keyframes` 0% { opacity: 0; } 100% { opacity: 1; } ` const FadeInButton = styled.button` animation: 1s ${fadeIn} ease-out; `
If you are composing your style rule as a partial, make sure to use the css helper.
import styled, { css, keyframes } from 'styled-components' const pulse = keyframes` 0% { opacity: 0; } 100% { opacity: 1; } ` const animation = props => css` ${pulse} ${props.animationLength} infinite alternate; ` const PulseButton = styled.button` animation: ${animation}; `
You can learn more about using animations with styled-components in the Animations section.
A helper component for modifying how your styles are processed. For a given subtree involving styled-components, you can customize various behaviors like how the CSS runtime processor (stylis) handles styles via userland plugins and option overrides.
Props | Description |
---|---|
disableCSSOMInjection (v5+) | Switches to the slower text node-based CSS injection system for adding styles to the DOM. Useful for integrating with third party tools that haven't been upgraded to consume styles from the CSSOM APIs. |
disableVendorPrefixes (v5+) | Opts the given subtree out of adding legacy CSS properties for rendered components. |
sheet | Thar be dragons ahead. Create and provide your own StyleSheet if necessary for advanced SSR scenarios. |
stylisPlugins (v5+) | An array of plugins to be run by stylis during compilation. Check out what's available on npm. |
target | Thar be dragons ahead. Provide an alternate DOM node to inject styles info. |
For example if your app runs only in modern browsers, you may want to disable vendor prefixing for your styles:
If you inspect me, there are no vendor prefixes for the flexbox style.
Another example would be enabling right-to-left translation for your styles via the userland stylis-plugin-rtl plugin:
My border is now on the right!
A utility to help identify styled components.
Arguments | Description |
---|---|
1. Function | Any function expected to possibly be a styled component or React component wrapped in a styled component |
Returns true if the passed function is a valid styled components-wrapped component class. It can be useful for determining if a component needs to be wrapped such that it can be used as a component selector:
import React from 'react' import styled, { isStyledComponent } from 'styled-components' import MaybeStyledComponent from './somewhere-else' let TargetedComponent = isStyledComponent(MaybeStyledComponent) ? MaybeStyledComponent : styled(MaybeStyledComponent)`` const ParentComponent = styled.div` color: cornflowerblue; ${TargetedComponent} { color: tomato; } `
This is a higher order component factory to get the current theme from a ThemeProvider and pass it to your component as a theme prop.
Arguments | Description |
---|---|
1. Component | Any valid React component that can handle a theme prop. |
Returns the passed component inside a wrapper (higher order component). The passed component will receive a theme prop with the current theme object.
import { withTheme } from 'styled-components' class MyComponent extends React.Component { render() { console.log('Current theme: ', this.props.theme) // ... } } export default withTheme(MyComponent)
All styled components automatically receive the theme as a prop, so this is only necessary if you wish to access the theme for other reasons.
This is a custom hook to get the current theme from a ThemeProvider.
import { useTheme } from 'styled-components' function MyComponent() { const theme = useTheme() console.log('Current theme: ', theme) // ... }
All styled components automatically receive the theme as a prop, so this is only necessary if you wish to access the theme for other reasons.
This is the "consumer" component created by React.createContext as the companion component to ThemeProvider. It uses the render prop pattern to allow for dynamic access to the theme during rendering.
It passes the current theme (based on a ThemeProvider higher in your component tree) as an argument to the child function. From this function, you may return further JSX or nothing.
import { ThemeConsumer } from 'styled-components' export default class MyComponent extends React.Component { render() { return ( <ThemeConsumer> {theme => <div>The theme color is {theme.color}.</div>} </ThemeConsumer> ) } }
All styled components automatically receive the theme as a prop, so this is only necessary if you wish to access the theme for other reasons.
A convenience method to find a single instance of a styled component's rendered DOM node within a given DOM root.
import styled from 'styled-components' import { find } from 'styled-components/test-utils' const Foo = styled.div` color: red; ` /** * Somewhere in your app: * * ReactDOM.render( * <main> * <Foo /> * </main>, document.body * ); */ // retrieves the first instance of "Foo" in the body (querySelector under the hood) find(document.body, Foo) // HTMLDivElement | null
A convenience method to find all instances of a styled component's rendered DOM node within a given DOM root.
import styled from 'styled-components' import { findAll } from 'styled-components/test-utils' const Foo = styled.div` color: ${props => props.color}; ` /** * Somewhere in your app: * * ReactDOM.render( * <main> * <Foo color="red" /> * <Foo color="green" /> * </main>, document.body * ); */ // retrieves a NodeList of instances of "Foo" in the body (querySelectorAll under the hood) findAll(document.body, Foo) // NodeList<HTMLDivElement> | null
A convenience method for finding instances of a particular styled component within an enzyme wrapper.
import { mount } from 'enzyme' import styled from 'styled-components' import { enzymeFind } from 'styled-components/test-utils' const Foo = styled.div` color: red; ` const wrapper = mount( <div> <Foo>bar</Foo> </div> ) enzymeFind(wrapper, Foo)
Within a styled component, we support all of CSS plus nesting. Since we generate an actual stylesheet and not inline styles, whatever works in CSS works in styled-components!
Hello World!
Ampersands (&) get replaced by our generated, unique classname for that styled component, making it easy to have complex logic.
styled-components has first-class Flow support to help you find typing errors while using our public API.
To use Flow with the public api of styled-components we recommend that you use the library definition in flow-typed. To install it you can use the flow-typed cli or download it manually from the git repository and store it in a flow-typed/ folder in the same directory with your flowconfig.
npm i -g flow-typed # if you do not already have flow-typed flow-typed install styled-components@<version>
If you are on npm >= 5.2 you could simply use npx
You should add the following lines to your .flowconfig, if you run into Flow errors, coming from the styled-components package in your node_modules directory.
[ignore] .*/node_modules/styled-components/.*
styled-components has community-organized TypeScript definitions on DefinitelyTyped which powers the editing experience in IDEs and can provide types for TypeScript projects. To install them, run:
# Web npm install --save-dev @types/styled-components # React Native npm install --save-dev @types/styled-components @types/styled-components-react-native
React Native only: If your tsconfig assigns types then you will need to add "styled-components-react-native" there. For example:
"types": ["jest", "styled-components-react-native"],
Now that Babel 7 is out and the TypeScript preset is available, it's now possible to use the styled-components babel plugin in conjunction with TypeScript.
Before you can effectively start to use TypeScript you will have to do a little bit of configuration.
TypeScript definitions for styled-components can be extended by using declaration merging since version v4.1.4 of the definitions.
So the first step is creating a declarations file. Let's name it styled.d.ts for example.
// import original module declarations import 'styled-components'; // and extend them! declare module 'styled-components' { export interface DefaultTheme { borderRadius: string; colors: { main: string; secondary: string; }; } }
React-Native:
declare module 'styled-components/native' { export interface DefaultTheme { borderRadius: string; colors: { main: string; secondary: string; }; } }
DefaultTheme is being used as an interface of props.theme out of the box. By default the interface DefaultTheme is empty so that's why we need to extend it.
Now we can create a theme just by using the DefaultTheme declared at the step above.
// my-theme.ts import { DefaultTheme } from 'styled-components'; const myTheme: DefaultTheme = { borderRadius: '5px', colors: { main: 'cyan', secondary: 'magenta', }, }; export { myTheme };
React-Native:
// styled-components.ts import * as styledComponents from "styled-components/native"; import ThemeInterface from "./theme"; const { default: styled, css, ThemeProvider } = styledComponents as styledComponents.ReactNativeThemedStyledComponentsModule<ThemeInterface>; export { css, ThemeProvider }; export default styled;
That's it! We're able to use styled-components just by using any original import.
import styled, { createGlobalStyle, css } from 'styled-components'; // theme is now fully typed export const MyComponent = styled.div` color: ${props => props.theme.colors.main}; `; // theme is also fully typed export MyGlobalStyle = createGlobalStyle` body { background-color: ${props => props.theme.colors.secondary}; } `; // and this theme is fully typed as well export cssHelper = css` border: 1px solid ${props => props.theme.borderRadius}; `;
If you are adapting the styles based on props, and those props are not part of the base tag / component props, you can tell TypeScript what those extra custom props are, with type arguments like this (TypeScript v2.9+ is required):
import styled from 'styled-components'; import Header from './Header'; interface TitleProps { readonly isActive: boolean; } const Title = styled.h1<TitleProps>` color: ${(props) => (props.isActive ? props.theme.colors.main : props.theme.colors.secondary)}; `;
Note: if you style a standard tag (like <h1> in above example), styled-components will not pass the custom props (to avoid the Unknown Prop Warning).
However, it will pass all of them to a custom React component:
import styled from 'styled-components'; import Header from './Header'; const NewHeader = styled(Header)<{ customColor: string }>` color: ${(props) => props.customColor}; `; // Header will also receive props.customColor
If the customColor property should not be transferred to the Header component, you can leverage transient props, by prefixing it with a dollar sign ($):
import styled from 'styled-components'; import Header from './Header'; const NewHeader2 = styled(Header)<{ $customColor: string }>` color: ${(props) => props.$customColor}; `; // Header does NOT receive props.$customColor
Depending on your use case, you can achieve a similar result by extracting the custom props yourself:
import styled from 'styled-components'; import Header, { Props as HeaderProps } from './Header'; const NewHeader3 = styled(({ customColor, ...rest }: { customColor: string } & HeaderProps) => <Header {...rest} />)` color: ${(props) => props.customColor}; `;
Or using shouldForwardProp:
import styled from 'styled-components'; import Header from './Header'; const NewHeader4 = styled(Header).withConfig({ shouldForwardProp: (prop, defaultValidatorFn) => !['customColor'].includes(prop), })<{ customColor: string }>` color: ${(props) => props.customColor}; `;
When defining a component you will need to mark className as optional in your Props interface:
interface LogoProps { /* This prop is optional, since TypeScript won't know that it's passed by the wrapper */ className?: string; } class Logo extends React.Component<LogoProps, {}> { render() { return <div className={this.props.className}>Logo</div>; } } const LogoStyled = styled(Logo)` font-family: 'Helvetica'; font-weight: bold; font-size: 1.8rem; `;
To use function components and have typechecking for the props you'll need to define the component alongside with its type. This is not special to styled-components, this is just how React works:
interface BoxProps { theme?: ThemeInterface; borders?: boolean; className?: string; } const Box: React.FunctionComponent<BoxProps> = (props) => <div className={props.className}>{props.children}</div>; const StyledBox = styled(Box)` padding: ${(props) => props.theme.lateralPadding}; `;
The .extend API was removed in styled-components v4. Use styled(StyledComponent) instead. For more information, see: https://github.com/styled-components/styled-components/issues/1546
This is a method that creates a new StyledComponent and extends its rules.
Arguments | Description |
---|---|
1. TaggedTemplateLiteral | A tagged template literal with your CSS and interpolations. |
import styled from 'styled-components' const Component = styled.div` color: red; ` const Component2 = Component.extend` background: white; color: blue; `
Returns a new StyledComponent with the new rules merged into the ones of the component this method was called on.
The injectGlobal API was removed and replaced by createGlobalStyle in styled-components v4.
A helper method to write global CSS. It does not return a component, but adds the styles to the stylesheet directly.
Arguments | Description |
---|---|
1. TaggedTemplateLiteral | A tagged template literal with your global styles inside. |
import { injectGlobal } from 'styled-components' injectGlobal` @font-face { font-family: "Operator Mono"; src: url("../fonts/Operator-Mono.ttf"); } body { margin: 0; } `
We do not encourage the use of this. Try to use it once per app at most, if you must, contained in a single file. This is an escape hatch. Only use it for the rare @font-face definition or body styling.
The "innerRef" prop was removed in styled-components v4 in favor of the React 16 forwardRef API. Just use the normal ref prop instead.
Passing a ref prop to a styled component will give you an instance of the StyledComponent wrapper, but not to the underlying DOM node. This is due to how refs work. It's not possible to call DOM methods, like focus, on our wrappers directly.
To get a ref to the actual, wrapped DOM node, pass the callback to the innerRef prop instead.
We don't support string refs (i.e. innerRef="node"), since they're already deprecated in React.
This example uses innerRef to save a ref to the styled input and focuses it once the user hovers over it.
const Input = styled.input` padding: 0.5em; margin: 0.5em; color: palevioletred; background: papayawhip; border: none; border-radius: 3px; ` class Form extends React.Component { render() { return ( <Input placeholder="Hover here..." innerRef={x => { this.input = x }} onMouseEnter={() => this.input.focus()} /> ) } }