Compiled

[Deprecated] styled

Deprecated
We no longer recommend using styled prop in new code, and we support this only to make migration from styled-components possible. Please use css or cssMap instead.

If you use the recommended UI Styling Standard ESLint plugin, this will be enforced for you.

Create a component that styles a JSX element which comes with built-in behavior such as ref and as prop support.

import { styled } from '@compiled/react';

export const ColoredText = styled.span({
  color: '#ff5630',
});
/* styled-obj.ts generated by @compiled/babel-plugin v0.32.2 */
import { forwardRef } from 'react';
import { ax, ix, CC, CS } from '@compiled/react/runtime';
const _ = '._syaz18rw{color:#ff5630}';
export const ColoredText = forwardRef(({ as: C = 'span', style: __cmpls, ...__cmplp }, __cmplr) => {
  return (
    <CC>
      <CS>{[_]}</CS>
      <C
        {...__cmplp}
        style={__cmpls}
        ref={__cmplr}
        className={ax(['_syaz18rw', __cmplp.className])}
      />
    </CC>
  );
});
if (process.env.NODE_ENV !== 'production') {
  ColoredText.displayName = 'ColoredText';
}
Assemble
<ColoredText>Assemble</ColoredText>

Tagged template expressions
Tagged template expressions are supported but using object styles is preferred. See the no-styled-tagged-template-expression ESLint rule in the UI Styling Standard for more details.

Dynamic declarations

Change a CSS declaration at runtime, powered by CSS variables.

Any props that are valid HTML attributes will be passed down to the underlying DOM element - otherwise they will be ignored.

This example shows that behavior - inspect the example using dev tools and you'll see the primary prop has not been passed through.

import { styled } from '@compiled/react';

export const EmphasisText = styled.span({
  color: (props) => (props.primary ? '#00B8D9' : '#36B37E'),
  textTransform: 'uppercase',
  fontWeight: 600,
});
/* styled-dynamic-decl.ts generated by @compiled/babel-plugin v0.32.2 */
import { forwardRef } from 'react';
import { ax, ix, CC, CS } from '@compiled/react/runtime';
const _4 = '._syazuhq2{color:#36b37e}';
const _3 = '._syazxdf1{color:#00b8d9}';
const _2 = '._k48pni7l{font-weight:600}';
const _ = '._1p1dangw{text-transform:uppercase}';
export const EmphasisText = forwardRef(
  ({ as: C = 'span', style: __cmpls, ...__cmplp }, __cmplr) => {
    const { primary, ...__cmpldp } = __cmplp;
    return (
      <CC>
        <CS>{[_, _2, _3, _4]}</CS>
        <C
          {...__cmpldp}
          style={__cmpls}
          ref={__cmplr}
          className={ax([
            '_1p1dangw _k48pni7l',
            __cmplp.primary ? '_syazxdf1' : '_syazuhq2',
            __cmplp.className,
          ])}
        />
      </CC>
    );
  }
);
if (process.env.NODE_ENV !== 'production') {
  EmphasisText.displayName = 'EmphasisText';
}
Make up
<EmphasisText primary>Make up</EmphasisText>

Remember
Styles are all pre-calculated at compile time, no cost is paid at runtime to check if the prop is a valid HTML attribute.

Transient props

Use a prop name prefixed with $ and even if it's a valid HTML attribute it won't be passed down to the DOM element.

This example shows that color is passed down to the DOM element, but $color is not.

import { styled } from '@compiled/react';

export const TransientProps = styled.span({
  color: (props) => props.$color,
  backgroundColor: (props) => props.color,
});
/* styled-transient-props.ts generated by @compiled/babel-plugin v0.32.2 */
import { forwardRef } from 'react';
import { ax, ix, CC, CS } from '@compiled/react/runtime';
const _2 = '._bfhk1cj8{background-color:var(--_xexnhp)}';
const _ = '._syaz1hv1{color:var(--_1vblj09)}';
export const TransientProps = forwardRef(
  ({ as: C = 'span', style: __cmpls, ...__cmplp }, __cmplr) => {
    const { $color, ...__cmpldp } = __cmplp;
    return (
      <CC>
        <CS>{[_, _2]}</CS>
        <C
          {...__cmpldp}
          style={{
            ...__cmpls,
            '--_1vblj09': ix(__cmplp.$color),
            '--_xexnhp': ix(__cmplp.color),
          }}
          ref={__cmplr}
          className={ax(['_syaz1hv1 _bfhk1cj8', __cmplp.className])}
        />
      </CC>
    );
  }
);
if (process.env.NODE_ENV !== 'production') {
  TransientProps.displayName = 'TransientProps';
}
Collate
<TransientProps $color="red" color="black">Collate</TransientProps>

The as prop

The as prop is useful when wanting to change the markup during runtime to something else, such as from a <h1> element to a <span>.

import { styled } from '@compiled/react';

export const Heading = styled.h1({
  fontWeight: 500,
  margin: 0,
  fontSize: '48px',
});
/* styled-as-prop.ts generated by @compiled/babel-plugin v0.32.2 */
import { forwardRef } from 'react';
import { ax, ix, CC, CS } from '@compiled/react/runtime';
const _6 = '._1wybckbl{font-size:3pc}';
const _5 = '._18u0idpf{margin-left:0}';
const _4 = '._otyridpf{margin-bottom:0}';
const _3 = '._2hwxidpf{margin-right:0}';
const _2 = '._19pkidpf{margin-top:0}';
const _ = '._k48pbfng{font-weight:500}';
export const Heading = forwardRef(({ as: C = 'h1', style: __cmpls, ...__cmplp }, __cmplr) => {
  return (
    <CC>
      <CS>{[_, _2, _3, _4, _5, _6]}</CS>
      <C
        {...__cmplp}
        style={__cmpls}
        ref={__cmplr}
        className={ax([
          '_k48pbfng _19pkidpf _2hwxidpf _otyridpf _18u0idpf _1wybckbl',
          __cmplp.className,
        ])}
      />
    </CC>
  );
});
if (process.env.NODE_ENV !== 'production') {
  Heading.displayName = 'Heading';
}
Marshal
<Heading as="span">Marshal</Heading>

Composing components

Wrapping an already defined component enables you to pass styles to it. Here the BlueText styles take precedence over RedText.

import { styled } from '@compiled/react';

const RedText = styled.span({
  color: 'red',
});

export const BlueText = styled(RedText)({
  color: 'blue',
});
/* styled-composition.ts generated by @compiled/babel-plugin v0.32.2 */
import { forwardRef } from 'react';
import { ax, ix, CC, CS } from '@compiled/react/runtime';
const _2 = '._syaz13q2{color:blue}';
const _ = '._syaz5scu{color:red}';
const RedText = forwardRef(({ as: C = 'span', style: __cmpls, ...__cmplp }, __cmplr) => {
  return (
    <CC>
      <CS>{[_]}</CS>
      <C
        {...__cmplp}
        style={__cmpls}
        ref={__cmplr}
        className={ax(['_syaz5scu', __cmplp.className])}
      />
    </CC>
  );
});
if (process.env.NODE_ENV !== 'production') {
  RedText.displayName = 'RedText';
}
export const BlueText = forwardRef(({ as: C = RedText, style: __cmpls, ...__cmplp }, __cmplr) => {
  return (
    <CC>
      <CS>{[_2]}</CS>
      <C
        {...__cmplp}
        style={__cmpls}
        ref={__cmplr}
        className={ax(['_syaz13q2', __cmplp.className])}
      />
    </CC>
  );
});
if (process.env.NODE_ENV !== 'production') {
  BlueText.displayName = 'BlueText';
}
This text is blue
<BlueText>This text is blue</BlueText>

Custom components
When composing custom components make sure to set its className and style props otherwise styles will not be applied correctly.

TypeScript

Type support comes out of the box, so you'll have a great time using Compiled with TypeScript. Any interpolation will have access to the props defined in the tagged template generic.

import { styled } from '@compiled/react';

const BigIfTrue = styled.div<{ big: true }>({
  fontSize: props => props.big ? 100 : 10
});

<BigIfTrue />
 ^^^^^^^^^ Property 'big' is missing in type [..]

Inherited types
Typing of composed components are inherited, which means their props will be available on the styled component as well.

Suggest changes to this page ➚