Magic Styled Components

Reduce the boilerplate of your Styled Components.

Automatic Theming

xstyled's exposes a styled utilities similar to the one you have in styled-components or Emotion with a small addition, the Automatic Theming.

Automatic Theming allows you to specify theme value as CSS value.

import styled from '@xstyled/...' const Button = styled.button` border-radius: md; font-weight: semibold; transition: default; background-color: emerald-500; color: #fff; @media (min-width: md) { font-size: lg; } `

Here's how the example above works:

  • md is replaced by theme.radii.md
  • semibold is replaced by theme.fontWeights.semibold
  • default is replaced by theme.transitions.default
  • emerald-500 is replaced by theme.colors['emerald-500']
  • #fff is replaced by theme.colors['#fff'], that is not defined, so it uses #fff as value
  • @media (min-width: md) is replaced by @media (min-width: ${theme.screens.lg})
  • lg is replaced by theme.fontSizes.lg

Use another component

The as prop let you replace the component originally defined:

import styled from '@xstyled/...' const Button = styled.button` border-radius: md; font-weight: semibold; transition: default; background-color: emerald-500; color: #fff; @media (min-width: md) { font-size: lg; } ` function App() { return ( <Button as="a" href="https://smooth-doc.com"> Smooth DOC </Button> ) }

Use theme getters

Automatic Theming is nice but sometime you need to read a value directly. For composing properties like box-shadow that contains colors and dimensions.

For that purpose, xstyled exports a th utility that let you get values from theme.

Get specific value

th exposes all utilities to directly get the type of property you need:

import { th } from '@xstyled/...' const Container = styled.div` box-shadow: 0 0 3px ${th.color('primary', '#000')}; `

The example above reads theme.colors.primary and use #000 as default value if not defined.

Get arbitrary value

import { th } from '@xstyled/...' const Container = styled.div` box-shadow: 0 0 3px ${th('primaryColor', '#000')}; `

Mapping

All available theme getters are automatically bound to a theme section and to CSS properties.

GetterTheme keyAutomatic CSS Properties
th.animationanimationsanimation
th.borderbordersborder, border-top, border-right, border-bottom, border-left
th.borderStyleborderStylesborder-style, border-top-style, border-right-style, border-bottom-style, border-left-style, outline-style
th.borderWidthborderWidthsborder-width, border-top-width, border-right-width, border-bottom-width, border-left-width, outline-width
th.colorcolorscolor, background-color, border-color, border-top-color, border-right-color, border-bottom-color, border-left-color, outline-color, fill, stroke
th.durationdurationstransition-duration, animation-duration
th.fontfontsfont-family
th.fontSizefontSizesfont-size
th.fontWeightfontWeightsfont-weight
th.insetinsettop, right, bottom, left
th.letterSpacingletterSpacingsletter-spacing
th.lineHeightlineHeightsline-height
th.radiusradiiborder-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius
th.shadowshadowsbox-shadow, text-shadow
th.sizesizeswidth, height, max-width, max-height, min-width, min-height
th.spacespacemargin, margin-top, margin-bottom, margin-left, margin-right, padding, padding-top, padding-bottom, padding-left, padding-right, gap, grid-gap, grid-row-gap, grid-column-gap
th.timingFunctionstimingFunctionsanimation-timing-function, transition-timing-function
th.transformtransformstransform
th.transitiontransitionstransition
th.transitionPropertytransitionPropertiestransition-property
th.zIndexzIndicesz-index

Add utility props to styled components

Sometimes it is convenient to mix styled components and utility props. It is possible to do it by adding a Box suffix to styled.tag. Using styled.buttonBox instead of styled.button let you use any props utilities on the component:

import styled from '@xstyled/...' const Button = styled.buttonBox` border-radius: md; font-weight: semibold; transition: default; background-color: emerald-500; color: #fff; ` function App() { return <Button bg="red-500">Danger</Button> }

It is possible to explicitly add utility props by using system or any utility as interpolation:

import { system, typography } from '@xstyled/styled-components' import styled from 'styled-components' const Button = styled.div` ${system} ` const Paragraph = styled.p` ${typography} ` function App() { return ( <> <Button bg="red-500">Danger</Button> <Paragraph fontSize="sm">Hello world!</Paragraph> </> ) }

Use utility props to apply style in styled components

Some utilities like ring can't be used in styled components. The apply method available on each utility or utilities family allows you to apply style directly on your styled components:

import styled, { system } from '@xstyled/...' const Button = styled.buttonBox` border-radius: md; font-weight: semibold; transition: default; background-color: emerald-500; color: #fff; &:focus { ${system.apply({ ring: 2, ringColor: 'emerald-800' })} } ` function App() { return <Button bg="red-500">Danger</Button> }

Responsive utilities

Media queries are automatically transformed by xstyled, these utilities are deprecated and will be removed in next major version. Please use @media instead.

breakpoints

breakpoints lets you write style for each breakpoint.

import { breakpoints } from '@xstyled/...' const Container = styled.div` ${breakpoints({ xs: css` /* All devices */ `, md: css` /* From md breakpoint */ `, lg: css` /* From lg breakpoint */ `, })} `

up

up lets you apply style from a breakpoint.

import styled, { css, up } from '@xstyled/...' const Box = styled.div` width: 200px; height: 200px; ${up( 'md', css` height: 300px; `, )} `

down

down lets you apply style up to a breakpoint.

import styled, { css, down } from '@xstyled/...' const Box = styled.div` width: 200px; height: 200px; ${down( 'md', css` height: 100px; `, )} `

between

between lets you apply style between two breakpoints.

import styled, { css, between } from '@xstyled/...' const Box = styled.div` width: 200px; height: 200px; ${between( 'md', 'lg', css` height: 300px; `, )} `

Styled Components Rules

For the magic to work, you must follow rules. If you don't follow them, automatic theme getter could not work as expected.

Only strings are transformed

CSS as object already does magic on your properties, for example a margin is automatically converted in px. To avoid any problem of migration, xstyled magic only applies on string properties.

import styled from '@xstyled/...' const Box = styled.div({ margin: 2, // '2px' (not transformed by xstyled) marginTop: '2', // '8px' (transformed by styled) })

css utility is required

With xstyled, you need to explicitly transforms your CSS using css utility:

🚫 Not supported

import styled, { css } from '@xstyled/...' const Box = styled.div` ${(p) => ({ margin: p.margin })} `

✅ Supported

import styled, { css } from '@xstyled/...' const Box = styled.div` ${(p) => css({ margin: p.margin })} `

Don't use interpolation in the middle of a declaration

xstyled analyze strings generated from css or styled and detects prop: value; pattern. Adding interpolation in the middle of a declaration is not supported.

🚫 Not supported

import styled from '@xstyled/...' const Box = styled.div` margin: ${(p) => p.margin}; `

If you need to access props, then returns a css expression that includes prop: value; pattern.

✅ Supported

const Box = styled.div` ${(p) => css` margin: ${p.margin}; `} `
Edit this page on GitHub