Our goal with Primer React is to hit the sweet spot between providing too little and too much styling flexibility; too little and the design system is too rigid, and too much and it becomes too difficult to maintain a consistent style. Our components are designed to cover common usage patterns, but sometimes a component just isn't quite flexible enough to look the way you need it to look. For those cases, we provide the sx
prop.
The sx
prop allows ad-hoc styling that is still theme-aware. Declare the styles you want to apply in CamelCase object notation, and try to use theme values in appropriate CSS properties when possible. If you've passed a custom theme using ThemeProvider
or a theme
prop, the sx
prop will honor the custom theme. For more information on theming in Primer React, check out the Primer Theme documentation.
sx
propThe sx
prop provides a lot of power, which means it is an easy tool to abuse. To best make use of it, we recommend following these guidelines:
sx
prop for small stylistic changes to components. For more substantial changes, consider abstracting your style changes into your own wrapper component.sx
prop values when possible.This example demonstrates applying a bottom border to Heading
, a component that does not receive BORDER
system props. The borderBottomWidth
value comes from theme.borderWidths
and borderBottomColor
comes from theme.colors
.
<><Heading pb={2}>Heading</Heading><Headingpb={2}sx={{borderBottomWidth: 1,borderBottomColor: 'border.default',borderBottomStyle: 'solid'}}>Heading with bottom border</Heading></>
Just like values passed to system props, values in the sx
prop can be provided as arrays to provide responsive styling.
<BoxborderWidth="1px"borderStyle="solid"borderColor="border.default"borderRadius={2}p={2}sx={{bg: ['neutral.subtle', 'accent.subtle', 'success.subtle', 'attention.subtle', 'danger.subtle']}}>Responsive background color</Box>
The sx
prop also allows for declaring styles based on media queries, pseudo-classes, and pseudo-elements. This example, though contrived, demonstrates the ability:
<Boxsx={{'> *': {borderWidth: 1,borderColor: 'border.default',borderStyle: 'solid',borderBottomWidth: 0,padding: 2,':last-child': {borderBottomWidth: 1},':hover': {bg: 'neutral.muted'}}}}><Box>First</Box><Box>Second</Box><Box>Third</Box></Box>