Documentation Index
Fetch the complete documentation index at: https://mintlify.com/system-ui/theme-ui/llms.txt
Use this file to discover all available pages before exploring further.
sx prop
The sx prop is the primary way to style components in Theme UI. It accepts all CSS properties with theme-aware values, shorthand aliases, and responsive arrays. This page documents the TypeScript types that power the sx prop.
Type Definition
type ThemeUIStyleObject<TTheme = Theme> =
| ThemeUICSSObject
| ThemeDerivedStyles<TTheme>
The sx prop accepts a ThemeUIStyleObject which can be:
- A plain style object (
ThemeUICSSObject)
- A function that receives the theme and returns a style object (
ThemeDerivedStyles)
Core Types
ThemeUICSSObject
interface ThemeUICSSObject
extends ThemeUICSSProperties,
CSSPseudoSelectorProps<Theme>,
CSSOthersObject,
VariantProperty,
Label {}
This is the main type for style objects. It includes:
- All CSS properties with theme-aware values
- Pseudo-selectors (
:hover, :focus, etc.)
- Custom CSS selectors
- Variant references
- Label for Emotion class names
ThemeDerivedStyles
interface ThemeDerivedStyles<TTheme = Theme> {
(theme: TTheme): ThemeUICSSObject
}
Allows styles to be defined as a function that receives the theme:
<Box
sx={(theme) => ({
color: theme.colors.primary,
fontSize: theme.fontSizes[2]
})}
/>
CSS Properties
Standard Properties
All standard CSS properties are supported with responsive and theme-aware values:
interface CSSProperties
extends CSS.StandardProperties<number | string>,
CSS.SvgProperties<number | string>,
CSS.VendorProperties<number | string> {}
Responsive Values
Every CSS property accepts arrays for mobile-first responsive styling:
type ResponsiveStyleValue<T> = T | ThemeUIEmpty | Array<T | ThemeUIEmpty>
type ThemeUIEmpty = undefined | null | false
Example:
<Box
sx={{
fontSize: [14, 16, 20, 24],
padding: [2, 3, 4],
display: ['block', null, 'flex']
}}
/>
Values of null, undefined, or false are ignored:
<Box
sx={{
// Only applies fontSize at first and third breakpoints
fontSize: [16, null, 24, null]
}}
/>
Shorthand Aliases
The sx prop supports convenient shorthand properties:
interface AliasesCSSProperties {
bg?: StandardCSSProperties['backgroundColor']
m?: StandardCSSProperties['margin']
mt?: StandardCSSProperties['marginTop']
mr?: StandardCSSProperties['marginRight']
mb?: StandardCSSProperties['marginBottom']
ml?: StandardCSSProperties['marginLeft']
mx?: StandardCSSProperties['marginLeft']
my?: StandardCSSProperties['marginTop']
p?: StandardCSSProperties['padding']
pt?: StandardCSSProperties['paddingTop']
pr?: StandardCSSProperties['paddingRight']
pb?: StandardCSSProperties['paddingBottom']
pl?: StandardCSSProperties['paddingLeft']
px?: StandardCSSProperties['paddingLeft']
py?: StandardCSSProperties['paddingTop']
}
Margin Aliases:
m - margin
mt - marginTop
mr - marginRight
mb - marginBottom
ml - marginLeft
mx - marginLeft + marginRight
my - marginTop + marginBottom
Padding Aliases:
p - padding
pt - paddingTop
pr - paddingRight
pb - paddingBottom
pl - paddingLeft
px - paddingLeft + paddingRight
py - paddingTop + paddingBottom
Other Aliases:
Extended Aliases:
marginX - marginLeft + marginRight
marginY - marginTop + marginBottom
paddingX - paddingLeft + paddingRight
paddingY - paddingTop + paddingBottom
scrollMarginX - scrollMarginLeft + scrollMarginRight
scrollMarginY - scrollMarginTop + scrollMarginBottom
scrollPaddingX - scrollPaddingLeft + scrollPaddingRight
scrollPaddingY - scrollPaddingTop + scrollPaddingBottom
size - width + height
Theme-Aware Properties
Certain CSS properties automatically look up values from the theme. Here’s the complete mapping:
Maps to theme.colors:
color: 'primary' // → theme.colors.primary
backgroundColor: 'muted' // → theme.colors.muted
borderColor: 'gray.2' // → theme.colors.gray[2]
All color properties:
color
backgroundColor, background, bg
borderColor, borderTopColor, borderBottomColor, borderLeftColor, borderRightColor
borderBlockColor, borderBlockEndColor, borderBlockStartColor
borderInlineColor, borderInlineEndColor, borderInlineStartColor
caretColor
columnRuleColor
outlineColor
textDecorationColor
accentColor
fill, stroke (SVG properties)
Maps to theme.space:
margin: 3 // → theme.space[3]
padding: 4 // → theme.space[4]
gap: 2 // → theme.space[2]
All space properties:
- All margin properties:
margin, marginTop, marginRight, marginBottom, marginLeft, marginX, marginY
- All margin logical properties:
marginBlock, marginBlockEnd, marginBlockStart, marginInline, marginInlineEnd, marginInlineStart
- All padding properties:
padding, paddingTop, paddingRight, paddingBottom, paddingLeft, paddingX, paddingY
- All padding logical properties:
paddingBlock, paddingBlockEnd, paddingBlockStart, paddingInline, paddingInlineEnd, paddingInlineStart
- Positioning:
top, right, bottom, left
- Inset properties:
inset, insetBlock, insetBlockEnd, insetBlockStart, insetInline, insetInlineEnd, insetInlineStart
- Scroll margins:
scrollMargin, scrollMarginTop, scrollMarginRight, scrollMarginBottom, scrollMarginLeft, scrollMarginX, scrollMarginY
- Scroll padding:
scrollPadding, scrollPaddingTop, scrollPaddingRight, scrollPaddingBottom, scrollPaddingLeft, scrollPaddingX, scrollPaddingY
- Gaps:
gap, gridGap, columnGap, gridColumnGap, rowGap, gridRowGap
Typography
fontFamily: 'body' // → theme.fonts.body
fontSize: 2 // → theme.fontSizes[2]
fontWeight: 'bold' // → theme.fontWeights.bold
lineHeight: 'body' // → theme.lineHeights.body
letterSpacing: 'wide' // → theme.letterSpacings.wide
Typography mappings:
fontFamily → theme.fonts
fontSize → theme.fontSizes
fontWeight → theme.fontWeights
lineHeight → theme.lineHeights
letterSpacing → theme.letterSpacings
Borders
border: 'thin' // → theme.borders.thin
borderWidth: 2 // → theme.borderWidths[2]
borderStyle: 'dashed' // → theme.borderStyles.dashed
borderRadius: 'medium' // → theme.radii.medium
Border mappings:
border, borderTop, borderRight, borderBottom, borderLeft → theme.borders
- All border block/inline properties →
theme.borders
borderWidth, borderTopWidth, borderBottomWidth, etc. → theme.borderWidths
borderStyle, borderTopStyle, borderBottomStyle, etc. → theme.borderStyles
borderRadius, borderTopLeftRadius, borderTopRightRadius, etc. → theme.radii
columnRuleWidth → theme.borderWidths
width: 'container' // → theme.sizes.container
height: 'full' // → theme.sizes.full
maxWidth: 'prose' // → theme.sizes.prose
Size mappings:
width, minWidth, maxWidth → theme.sizes
height, minHeight, maxHeight → theme.sizes
flexBasis → theme.sizes
size → theme.sizes
blockSize, minBlockSize, maxBlockSize → theme.sizes
inlineSize, minInlineSize, maxInlineSize → theme.sizes
columnWidth → theme.sizes
Other Scales
boxShadow: 'elevated' // → theme.shadows.elevated
zIndex: 'modal' // → theme.zIndices.modal
opacity: 'disabled' // → theme.opacities.disabled
transition: 'smooth' // → theme.transitions.smooth
Other mappings:
boxShadow, textShadow → theme.shadows
zIndex → theme.zIndices
opacity → theme.opacities
transition → theme.transitions
Pseudo-Selectors
All CSS pseudo-selectors are supported:
type CSSPseudoSelectorProps<TTheme> = {
[K in CSS.Pseudos]?: ThemeUIStyleObject<TTheme>
}
Example:
<Button
sx={{
color: 'text',
bg: 'primary',
':hover': {
bg: 'primaryHover'
},
':focus': {
outline: '2px solid',
outlineColor: 'primary'
},
':disabled': {
opacity: 0.5,
cursor: 'not-allowed'
},
'::before': {
content: '"→"',
mr: 2
}
}}
>
Submit
</Button>
CSS Selectors
Custom CSS selectors are supported through an index signature:
interface CSSOthersObject {
[k: string]: StylePropertyValue<string | number>
}
Example:
<Box
sx={{
color: 'text',
'& > *': {
margin: 0
},
'& a': {
color: 'primary',
textDecoration: 'none'
},
'@media print': {
display: 'none'
}
}}
/>
Variants
Reference predefined variants from the theme:
interface VariantProperty {
variant?: string
}
Example:
const theme = {
buttons: {
primary: {
color: 'white',
bg: 'primary',
padding: 3,
borderRadius: 2
},
secondary: {
color: 'text',
bg: 'secondary',
padding: 2
}
}
}
<Button sx={{ variant: 'buttons.primary' }}>Primary</Button>
<Button sx={{ variant: 'buttons.secondary' }}>Secondary</Button>
You can extend variants with additional styles:
<Button
sx={{
variant: 'buttons.primary',
fontSize: 4, // Overrides or extends variant
textTransform: 'uppercase'
}}
>
Large Primary
</Button>
Nested Theme Values
Theme scales can be nested using the __default key:
interface ObjectWithDefault<T> {
__default?: T
}
interface NestedScaleDict<T>
extends ScaleDict<T>,
ObjectWithDefault<T> {}
Example:
const theme = {
colors: {
blue: {
__default: '#0066cc',
light: '#3399ff',
dark: '#003366'
}
}
}
<Box
sx={{
color: 'blue', // Uses __default → '#0066cc'
bg: 'blue.light', // → '#3399ff'
borderColor: 'blue.dark' // → '#003366'
}}
/>
Special Properties
Emotional label for debugging:
interface Label {
label?: string
}
Example:
<Box
sx={{
label: 'hero-section',
padding: 4,
bg: 'muted'
}}
/>
// Generates class name like: css-<hash>-hero-section
Type Overrides
Some CSS properties accept additional types for theme compatibility:
interface OverwriteCSSProperties {
boxShadow?: CSS.Property.BoxShadow | number
fontWeight?: CSS.Property.FontWeight | string
borderTopStyle?: CSS.Property.BorderTopStyle | string
borderBottomStyle?: CSS.Property.BorderBottomStyle | string
borderRightStyle?: CSS.Property.BorderRightStyle | string
borderLeftStyle?: CSS.Property.BorderLeftStyle | string
borderRadius?: CSS.Property.BorderRadius<string | number>
zIndex?: CSS.Property.ZIndex | string
}
This allows you to use theme keys or indices:
<Box
sx={{
boxShadow: 0, // theme.shadows[0]
fontWeight: 'bold', // theme.fontWeights.bold or CSS 'bold'
zIndex: 'modal', // theme.zIndices.modal
borderRadius: 2 // theme.radii[2]
}}
/>
Examples
Responsive Layout
<Flex
sx={{
flexDirection: ['column', 'row'],
gap: [2, 3, 4],
padding: [3, 4, 5],
maxWidth: 'container',
mx: 'auto'
}}
>
<Box sx={{ flex: ['1 1 100%', '1 1 50%'] }}>Column 1</Box>
<Box sx={{ flex: ['1 1 100%', '1 1 50%'] }}>Column 2</Box>
</Flex>
Component with Variants and States
<Button
sx={{
variant: 'buttons.primary',
fontSize: [1, 2],
px: [3, 4],
py: 2,
':hover': {
bg: 'primaryHover',
transform: 'translateY(-2px)',
boxShadow: 1
},
':active': {
transform: 'translateY(0)'
},
':disabled': {
opacity: 0.5,
cursor: 'not-allowed'
}
}}
>
Click Me
</Button>
Nested Selectors
<Box
sx={{
'& > h1': {
fontSize: [4, 5, 6],
mb: 3
},
'& p': {
fontSize: 2,
lineHeight: 'body',
color: 'text',
'&:first-of-type': {
fontSize: 3,
fontWeight: 'bold'
}
},
'& a': {
color: 'primary',
textDecoration: 'none',
':hover': {
textDecoration: 'underline'
}
}
}}
>
{content}
</Box>
Theme Function Form
<Box
sx={(theme) => ({
padding: theme.space[3],
color: theme.colors.text,
backgroundColor: theme.colors.background,
borderRadius: theme.radii.medium,
boxShadow: theme.shadows.card,
[theme.mediaQueries?.lg]: {
padding: theme.space[4]
}
})}
/>
Related
- css - The underlying function that processes sx prop styles
- get - Function used to extract theme values