Skip to content
Theme UI
GitHub

The sx Prop

The sx prop lets you style elements inline, using values from your theme. To use the sx prop, add the custom /** @jsxImportSource theme-ui */ pragma comment to the top of your module or configure automatic JSX runtime in your transpiler.

The sx prop lets you add any valid CSS to an element, while using values from your theme to keep styles consistent. You can think of the style object that the sx prop accepts as a superset of CSS.

/** @jsxImportSource theme-ui */
export default (props) => (
<div
{...props}
sx={{
// values referencing scales defined in a theme
color: 'primary',
bg: 'lightgray',
fontFamily: 'body',
// raw CSS value
boxShadow: '0 0 1px 3px rgba(0, 0, 0, .125)',
}}
/>
)

Theme-Aware Properties

The following CSS properties will use values defined in the theme, when available.

PropertyTheme Key
fontFamilyfonts
fontSizefontSizes
fontWeightfontWeights
lineHeightlineHeights
letterSpacingletterSpacings
colorcolors
bg, backgroundColorcolors
accentColorcolors
borderColorcolors
caretColorcolors
outlineColorcolors
textDecorationColorcolors
opacityopacities
transitiontransitions
m, marginspace
mt, marginTopspace
mr, marginRightspace
mb, marginBottomspace
ml, marginLeftspace
mx, marginXspace
my, marginYspace
p, paddingspace
pt, paddingTopspace
pr, paddingRightspace
pb, paddingBottomspace
pl, paddingLeftspace
px, paddingXspace
py, paddingYspace
scrollMarginspace
scrollMarginTopspace
scrollMarginRightspace
scrollMarginBottomspace
scrollMarginLeftspace
scrollMarginXspace
scrollMarginYspace
scrollPaddingspace
scrollPaddingTopspace
scrollPaddingRightspace
scrollPaddingBottomspace
scrollPaddingLeftspace
scrollPaddingXspace
scrollPaddingYspace
topspace
rightspace
bottomspace
leftspace
gridGapspace
gridColumnGapspace
gridRowGapspace
gapspace
columnGapspace
rowGapspace
borderborders
borderTopborders
borderRightborders
borderBottomborders
borderLeftborders
borderWidthborderWidths
borderStyleborderStyles
borderRadiusradii
borderTopRightRadiusradii
borderTopLeftRadiusradii
borderBottomRightRadiusradii
borderBottomLeftRadiusradii
borderTopWidthborderWidths
borderTopColorcolors
borderTopStyleborderStyles
borderBottomWidthborderWidths
borderBottomColorcolors
borderBottomStyleborderStyles
borderLeftWidthborderWidths
borderLeftColorcolors
borderLeftStyleborderStyles
borderRightWidthborderWidths
borderRightColorcolors
borderRightStyleborderStyles
columnRuleColorcolors
columnRuleWidthborderWidths
boxShadowshadows
textShadowshadows
zIndexzIndices
widthsizes
minWidthsizes
maxWidthsizes
columnWidthsizes
heightsizes
minHeightsizes
maxHeightsizes
flexBasissizes
sizesizes
fillcolors
strokecolors

Theme UI also supports CSS Logical Properties, which follow this structure:

  • margin-{block,inline}-{start,end}
  • padding-{block,inline}-{start,end}
  • border-{block,inline}-{start,end}-{width,style,color}
  • inset-{block,inline}-{start,end}
See the full list
PropertyTheme Key
marginBlockspace
marginBlockEndspace
marginBlockStartspace
marginInlinespace
marginInlineEndspace
marginInlineStartspace
paddingBlockspace
paddingBlockEndspace
paddingBlockStartspace
paddingInlinespace
paddingInlineEndspace
paddingInlineStartspace
insetspace
insetBlockspace
insetBlockEndspace
insetBlockStartspace
insetInlinespace
insetInlineEndspace
insetInlineStartspace
borderBlockborders
borderBlockColorcolors
borderBlockEndborders
borderBlockEndColorcolors
borderBlockEndStyleborderStyles
borderBlockEndWidthborderWidths
borderBlockStartborders
borderBlockStartColorcolors
borderBlockStartStyleborderStyles
borderBlockStartWidthborderWidths
borderBlockStyleborderStyles
borderBlockWidthborderWidths
borderEndEndRadiusradii
borderEndStartRadiusradii
borderInlineborders
borderInlineColorcolors
borderInlineEndborders
borderInlineEndColorcolors
borderInlineEndStyleborderStyles
borderInlineEndWidthborderWidths
borderInlineStartborders
borderInlineStartColorcolors
borderInlineStartStyleborderStyles
borderInlineStartWidthborderWidths
borderInlineStyleborderStyles
borderInlineWidthborderWidths
borderStartEndRadiusradii
borderStartStartRadiusradii
blockSizesizes
inlineSizesizes
maxBlockSizesizes
maxInlineSizesizes
minBlockSizesizes
minInlineSizesizes

Responsive Values

Theme UI, like Styled System, includes a shorthand syntax for writing mobile-first responsive styles using arrays as values. This is useful when you want to change a single property across multiple breakpoints without needing to write verbose media query syntax.

/** @jsxImportSource theme-ui */
export default (props) => (
<div
{...props}
sx={{
width: ['100%', '50%', '25%'],
}}
/>
)

With responsive arrays, the 0-th element maps to all breakpoints, and the n-th element maps to the (n - 1)-th breakpoint. For example:

  • The default width is 100%
  • At the 0th breakpoint & larger, width is 50%
  • At the 1st breakpoint & larger, width is 25%

Skipping Breakpoints

If you want to skip a breakpoint, you can use the value null. This is useful if you want to set a value for only the largest breakpoint, for example.

/** @jsxImportSource theme-ui */
export default (props) => (
<div
{...props}
sx={{
width: [null, null, '25%'],
}}
/>
)

Media Queries

If you prefer standard CSS media query syntax, you can use nested objects for responsive styles as well.

<div
sx={{
width: '100%',
'@media screen and (min-width: 40em)': {
width: '50%',
},
}}
/>

Margin and Padding

Margin and padding are treated as first-class citizens in Theme UI, using values defined in the theme.space scale, and include an optional shorthand syntax for using negative space in your application.

In addition to shorthands for applying margin and padding on the x- and y-axes, a terse naming convention can be used to quickly edit styles.

// example of using margin and padding shorthand syntax
<div
sx={{
px: 3, // padding-left & padding-right
// paddingX: 3 will also work
py: 4, // padding-top & padding-bottom
mb: 3, // margin-bottom
}}
/>

Functional Values

For shorthand CSS properties or ones that are not automatically mapped to values in the theme, use an inline function to reference values from the theme object.

/** @jsxImportSource theme-ui */
export default (props) => (
<div
{...props}
sx={{
boxShadow: (theme) => `0 0 4px ${theme.colors.primary}`,
}}
/>
)

Child Selectors

In some cases you might want to apply styles to children of the current element. You can do so with Emotion's nested selectors.

/** @jsxImportSource theme-ui */
export default (props) => (
<div
{...props}
sx={{
h1: {
backgroundColor: 'tomato',
'a, span': {
backgroundColor: 'white',
color: 'tomato',
},
},
}}
/>
)

If you want to reference the current class selector of the component, such as for psuedo-classes & psuedo-elements, you can use the & symbol.

export default (props) => (
<div
{...props}
sx={{
'& > p': {
fontSize: [2, 3, 4],
},
'&:hover': {
color: 'accent',
},
}}
/>
)

Raw CSS

To opt-out of using theme-based CSS, use the css prop to render raw CSS values.

/** @jsxImportSource theme-ui */
export default (props) => (
<div
{...props}
css={{
// raw values
color: 'tomato',
fontSize: 24,
}}
/>
)

Using the sx Prop in MDX

Because MDX uses its own custom pragma and createElement function, the Theme UI pragma will not work in MDX files. You can use any of the Theme UI components, which support the sx prop, in an MDX file as a workaround.

import { Box } from 'theme-ui'
<Box
sx={{
padding: 3,
bg: 'highlight',
}}
>
# Hello
</Box>

Object Styles

If you're new to using JavaScript object notation for authoring styles, see the guide to using objects for styling.

Edit the page on GitHub
Previous:
Theming
Next:
Color Modes