styled
This is the default export.
This is a low-level factory we use to create the styled.tagname
helper methods.
Arguments | Description |
---|---|
| Either a valid react component or a tagname like |
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.
TaggedTemplateLiteral
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.
StyledComponent
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.
"as"
polymorphic prop 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.
ThemeProvider
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 (or function returning an object) that will be injected as |
Simple usage:
I'm mediumseagreen!
Adding to or replacing an outer theme using nested ThemeProvider
:
I'm mediumseagreen with a white background!I'm mediumseagreen with a black background!
css
prop 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)
This functionality was removed in v6.1 due to lack of usage and unnecessary bloat for other consumers. More info
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.
If you're using a higher version than v6, you do not need to install @types/styled-components
.
Instead, you can directly import the CSSProp
in your project like this:
import {} from 'react' import type { CSSProp } from 'styled-components' declare module 'react' { interface Attributes { css?: CSSProp | undefined } }
createGlobalStyle
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 |
---|---|
| 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<{ $whiteColor?: boolean; }>` 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<{ $whiteColor?: boolean; }>` 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>
css
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 |
---|---|
| 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' interface ComponentProps { $complex?: boolean; $whiteColor?: boolean; } const complexMixin = css<ComponentProps>` color: ${props => (props.$whiteColor ? 'white' : 'black')}; ` const StyledComp = styled.div<ComponentProps>` /* 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.
keyframes
A helper method to create keyframes for animations.
Arguments | Description |
---|---|
| 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' interface AnimationProps { $animationLength: number; } const pulse = keyframes` 0% { opacity: 0; } 100% { opacity: 1; } ` const animation = props => css<AnimationProps>` ${pulse} ${props.$animationLength} infinite alternate; ` const PulseButton = styled.button<AnimationProps>` animation: ${animation}; `
You can learn more about using animations with styled-components in the Animations section.
StyleSheetManager
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, removed in v6) | Opts the given subtree out of adding legacy CSS properties for rendered components. |
enableVendorPrefixes (v6+) | Opts the given subtree into 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 is intended for legacy browsers, you may want to enable vendor prefixing for your styles:
If you inspect me, there are 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!
isStyledComponent
A utility to help identify styled components.
Arguments | Description |
---|---|
| 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: royalblue; ${TargetedComponent} { color: tomato; } `
withTheme
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 |
---|---|
| Any valid React component that can handle a |
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.
useTheme
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.
ThemeConsumer
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.
find
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
findAll
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
enzymeFind
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 provides TypeScript definitions which empowers the editing experience in IDEs and increases type safety for TypeScript projects.
For older versions of styled-components, there are community definitions available via the @types/styled-components
NPM package.
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:
import 'styled-components/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 };
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) => !['customColor'].includes(prop), })<{ customColor: string }>` color: ${(props) => props.customColor}; `;
className
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}; `;
.extend
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 |
---|---|
| 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.
injectGlobal
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 |
---|---|
| 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.
"innerRef"
propThe "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: #BF4F74; 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()} /> ) } }
.withComponent
The withComponent
API was replaced by "as"
prop in styled-components v4, and fully-removed in v6.
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 |
---|---|
| 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.