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 themecolor: 'primary',bg: 'lightgray',fontFamily: 'body',// raw CSS valueboxShadow: '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.
Property | Theme Key |
---|---|
fontFamily | fonts |
fontSize | fontSizes |
fontWeight | fontWeights |
lineHeight | lineHeights |
letterSpacing | letterSpacings |
color | colors |
bg , backgroundColor | colors |
borderColor | colors |
caretColor | colors |
outlineColor | colors |
textDecorationColor | colors |
opacity | opacities |
transition | transitions |
m , margin | space |
mt , marginTop | space |
mr , marginRight | space |
mb , marginBottom | space |
ml , marginLeft | space |
mx , marginX | space |
my , marginY | space |
p , padding | space |
pt , paddingTop | space |
pr , paddingRight | space |
pb , paddingBottom | space |
pl , paddingLeft | space |
px , paddingX | space |
py , paddingY | space |
scrollMargin | space |
scrollMarginTop | space |
scrollMarginRight | space |
scrollMarginBottom | space |
scrollMarginLeft | space |
scrollMarginX | space |
scrollMarginY | space |
scrollPadding | space |
scrollPaddingTop | space |
scrollPaddingRight | space |
scrollPaddingBottom | space |
scrollPaddingLeft | space |
scrollPaddingX | space |
scrollPaddingY | space |
top | space |
right | space |
bottom | space |
left | space |
gridGap | space |
gridColumnGap | space |
gridRowGap | space |
gap | space |
columnGap | space |
rowGap | space |
border | borders |
borderTop | borders |
borderRight | borders |
borderBottom | borders |
borderLeft | borders |
borderWidth | borderWidths |
borderStyle | borderStyles |
borderRadius | radii |
borderTopRightRadius | radii |
borderTopLeftRadius | radii |
borderBottomRightRadius | radii |
borderBottomLeftRadius | radii |
borderTopWidth | borderWidths |
borderTopColor | colors |
borderTopStyle | borderStyles |
borderBottomWidth | borderWidths |
borderBottomColor | colors |
borderBottomStyle | borderStyles |
borderLeftWidth | borderWidths |
borderLeftColor | colors |
borderLeftStyle | borderStyles |
borderRightWidth | borderWidths |
borderRightColor | colors |
borderRightStyle | borderStyles |
columnRuleColor | colors |
columnRuleWidth | borderWidths |
boxShadow | shadows |
textShadow | shadows |
zIndex | zIndices |
width | sizes |
minWidth | sizes |
maxWidth | sizes |
columnWidth | sizes |
height | sizes |
minHeight | sizes |
maxHeight | sizes |
flexBasis | sizes |
size | sizes |
fill | colors |
stroke | colors |
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
Property | Theme Key |
---|---|
marginBlock | space |
marginBlockEnd | space |
marginBlockStart | space |
marginInline | space |
marginInlineEnd | space |
marginInlineStart | space |
paddingBlock | space |
paddingBlockEnd | space |
paddingBlockStart | space |
paddingInline | space |
paddingInlineEnd | space |
paddingInlineStart | space |
inset | space |
insetBlock | space |
insetBlockEnd | space |
insetBlockStart | space |
insetInline | space |
insetInlineEnd | space |
insetInlineStart | space |
borderBlock | borders |
borderBlockColor | colors |
borderBlockEnd | borders |
borderBlockEndColor | colors |
borderBlockEndStyle | borderStyles |
borderBlockEndWidth | borderWidths |
borderBlockStart | borders |
borderBlockStartColor | colors |
borderBlockStartStyle | borderStyles |
borderBlockStartWidth | borderWidths |
borderBlockStyle | borderStyles |
borderBlockWidth | borderWidths |
borderEndEndRadius | radii |
borderEndStartRadius | radii |
borderInline | borders |
borderInlineColor | colors |
borderInlineEnd | borders |
borderInlineEndColor | colors |
borderInlineEndStyle | borderStyles |
borderInlineEndWidth | borderWidths |
borderInlineStart | borders |
borderInlineStartColor | colors |
borderInlineStartStyle | borderStyles |
borderInlineStartWidth | borderWidths |
borderInlineStyle | borderStyles |
borderInlineWidth | borderWidths |
borderStartEndRadius | radii |
borderStartStartRadius | radii |
blockSize | sizes |
inlineSize | sizes |
maxBlockSize | sizes |
maxInlineSize | sizes |
minBlockSize | sizes |
minInlineSize | sizes |
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%'],}}/>)
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.
<divsx={{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<divsx={{px: 3, // padding-left & padding-right// paddingX: 3 will also workpy: 4, // padding-top & padding-bottommb: 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.
/** @jsx jsx */import { jsx } from 'theme-ui'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 valuescolor: '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'<Boxsx={{padding: 3,bg: 'highlight',}}># Hello</Box>
Work with className
theme-ui
has its own function to build JSX with sx prop. How does it works?
theme-ui
will use praseProps
to deal with all props. it will firstly deal
with sx
and/or css
props, to get the new css
prop with original props
except the old sx
and/or old css
props. Then it will let
emtion
's jsx
function to finish the other works.
You can click [emotion css-prop][] to get more infomation.
So, emtion will deal with the new css
prop and className
(for example,
'bar'
) prop. Then make new style class with new name(for example,
'foo'
), and replace old className
with new className
.
const Comp = (props) => {// - theme-ui will turn `sx` prop into `css` prop.// - emtion will mixin `css` prop and `className` prop to get new `className`// prop<div className={props.className} sx={{width: 1}}/>}<Comp />// => <div class="bar" />// => .bar {// width: 1px;// }// sx prop with turn into `className` prop.<Comp sx={{height: 1}} />// => <div class="foo" />// => .foo {// width: 1px;// height: 1px;// }
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