Theme Styling with the sx Prop

Enhance your component flexibility while sticking to your design principles.

As React components become the building blocks of our application, styling them becomes a crucial part of our development. Scaling these styles as our codebase grows is critical – balancing modularity, performance, and developer experience.

Today, there are many ways to apply styles to your React, just to name a few popular methods:

Let's take a closer look at a CSS-in-JS approach used by Theme UI which provides amazing developer ergonomics while respecting design constraints.

A quick setup

The up-coming examples assume a project that has already been set up with Theme UI. To set up a project with Theme UI:

  • Install the Theme UI package with
    npm i theme-ui
    
  • Wrap your application with the
    ThemeProvider
    
    passing in the
    theme
    
    object as a prop
  • See the Getting Started section for more details

The sx prop

Theme UI introduces a powerful styling feature, the sx prop. This prop lets you style elements inline using values from your theme.

You can add the

sx
prop to your JSX elements by simply adding the custom
/** @jsx jsx */
pragma comment to the top of your file and importing the
jsx
function from
theme-ui
.

/** @jsx jsx */
import { jsx } from 'theme-ui';

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

This is a similar method to the Emotion

css
prop, but now we have the nifty features of Theme UI:

First-class component support

Instead of bringing in all of Theme UI into our project, we can leverage the smaller

package to add
sx
prop powers to individual components. Theme UI uses this package to add
sx
prop support to its foundational Box component.

/**
 * Simplified modification of the Theme UI Box
 * http://bit.ly/3pzPiAr
 */

import styled from '@emotion/styled';
import { css } from '@theme-ui/css';

// Parse the style objects passed via `sx` to the `css(...)` function
const sx = (props) => css(props.sx)(props.theme);

const Box = styled.div(
  {
    boxSizing: 'border-box',
    margin: 0,
    minWidth: 0,
  },
  sx,
  (props) => props.css
);

export default Box;

Now, Box has

sx
prop support integrated into the component and can be used without the need for the JSX pragma.

/** No need to import the theme-ui jsx pragma! */
import Box from './components/Box'

export const Card = ({ sx, ...props }) => (
  <Box
    {...props}
    sx={{
      border: '1px solid',
      borderColor: 'border',
      borderRadius: "grayLight"
      p: 3,
      ...sx
    }}
  />
)

export default Card;

Moving the

sx
function to its own utility file, this helper can be used to add the
sx
prop as a first-class styling feature for any component.

import styled from '@emotion/styled';
import sx from '../utils/sx';

const Button = styled.button(
  {
    appearance: 'none',
    display: 'inline-block',
    textAlign: 'center',
    lineHeight: 'inherit',
    textDecoration: 'none',
    fontSize: 'inherit',
    px: 3,
    py: 2,
    color: 'white',
    bg: 'primary',
    border: 0,
    borderRadius: 4,
  },
  sx
);

export default Button;

Next steps

This is a simple approach for adding a powerful styling layer to your React components, allowing for flexibility while promoting development within the theme constraints.

I recommend checking out the Theme UI source code on how this technique is taken one step farther in adding theme-based variants, base styles, and hooking in additional prop conveniences from Styled System.

You can expand on this technique by using your foundational

Box
component as the basis for all your UI pieces. More on that in part 2, Building from the Box.

Subscribe to the newsletter

Be the first to know when I post something new! Thoughts about code, design, startups and other interesting things.

© 2025 Sam Rose
All Rights Reserved.