File: styling.md | Updated: 11/15/2025
ThemesThemes PrimitivesPrimitives IconsIcons ColorsColors
Getting started Styling Layout Releases Resources
Overview Color Dark mode Typography Spacing Breakpoints Radius Shadows Cursors
Box Flex Grid Container Section
Text Heading Blockquote Code Em Kbd Link Quote Strong
Alert Dialog Aspect Ratio Avatar Badge Button Callout Card Checkbox Checkbox Group Checkbox Cards Context Menu Data List Dialog Dropdown Menu Hover Card Icon Button Inset Popover Progress Radio Radio Group Radio Cards Scroll Area Segmented Control Select Separator Skeleton Slider Spinner Switch Table Tabs Tab Nav Text Area Text Field Tooltip
Accessible Icon Portal Reset Slot Theme Visually Hidden
Overview
How to approach styling with Radix Themes.
Radix Themes does not come with a built-in styling system. Thereâs no css or sx prop, and it does not use any styling libraries internally. Under the hood, itâs built with vanilla CSS.
Thereâs no overhead when it comes to picking a styling technology for your app.
The components in Radix Themes are relatively closedâthey come with a set of styles that arenât always easily overridden. They are customizable within whatâs allowed by their props and the theme configuration.
However, you also get access to the same CSS variables that power the Radix Themes components. You can use these tokens to create custom components that naturally feel at home in the original theme. Changes to the token system are treated as breaking.
For more information on specific tokens, refer to the corresponding guides in the Theme section .
Color system
ABCD
========
ABCDEFG
===========
ABCDEFGHI
=============
ABCDEFGHIJ
==============
ABCDEFGHIJKL
================
A wonderful serenity has taken possession of my entire soul, like these sweet mornings of spring which I enjoy with my whole heart. I am alone, and feel the charm of existence in this spot, which was created for the bliss of souls like mine. I am so happy, my dear friend, so absorbed in the exquisite sense of mere tranquil existence, that I neglect my talents. I should be incapable of drawing a single stroke at the present moment; and yet I feel that I never was a greater artist than now. When, while the lovely valley teems with vapour around me, and the meridian sun strikes the upper surface of the impenetrable foliage of my trees, and but a few stray gleams steal into the inner sanctuary, I throw myself down among the tall grass by the trickling stream; and, as I lie close to the earth, a thousand unknown plants are noticed by me: when I hear the buzz of the little world among the stalks, and grow familiar with the countless indescribable forms of the insects and flies, then I feel the presence of the Almighty, who formed us in his own image, and the breath
Typography examples
Shadow and radius examples
Beyond simple style overrides, we recommend using the components as-is, or create your own versions using the same building blocks.
Most components do have className and style props, but if you find yourself needing to override a lot of styles, itâs a good sign that you should either:
Tailwind is great. Yet, if you plan to use Radix Themes with Tailwind, keep in mind how its ergonomics may encourage you to create complex styles on the fly, sometimes reaching into the component internals without friction.
Tailwind is a different styling paradigm, which may not mix well with the idea of a closed component system where customization is achieved through props, tokens, and creating new components on top of a shared set of building blocks.
If you need to create a custom component, use the same building blocks that Radix Themes uses:
Feel free to explore the source code of Radix Themes to see how it is built.
Out of the box, portalled Radix Themes components can be nested and stacked in any order without conflicts. For example, you can open a popover that opens a dialog, which in turn opens another popover. They all stack on top of each other in the order they were opened:
Recursive popover
When building your own components, use the following rules to avoid z-index conflicts:
z-index values other than auto, 0, or -1 in rare cases.Your main content and portalled content are separated by the stacking context that the styles of the root <Theme> component create. This allows you to stack portalled content on top of the main content without worrying about z-indices.
As of Next.js 13.0 to 14.1, the import order of CSS files in app/**/layout.tsx is not guaranteed, so Radix Themes may overwrite your own styles even when written correctly:
import "@radix-ui/themes/styles.css";
import "./my-styles.css";
This Next.js issue may come and go sporadically, or happen only in development or production.
As a workaround, you can merge all the CSS into a single file first via postcss-import
and import just that into your layout. Alternatively, importing the styles directly in page.tsx files also works.
As of Tailwind v3, styles produced by the @tailwind directive are usually appended after any imported CSS, no matter the original import order. In particular, Tailwindâs button reset
style may interfere with Radix Themes buttons, rendering certain buttons without a background color.
Workarounds:
@tailwind base@import tailwindcss/base before Radix Themes styles. Example setupWhen you render a custom portal in a Radix Themes project, it will naturally appear outside of the root <Theme> component, which means it wonât have access to most of the theme tokens and styles. To fix that, wrap the portal content with another <Theme>:
// Implementation example of a custom dialog using the low-level Dialog primitive
// Refer to https://www.radix-ui.com/primitives/docs/components/dialog
import { Dialog } from "radix-ui";
import { Theme } from "@radix-ui/themes";
function MyCustomDialog() {
return (
<Dialog.Root>
<Dialog.Trigger>Open</Dialog.Trigger>
<Dialog.Portal>
<Theme>
<Dialog.Overlay />
<Dialog.Content>
<Dialog.Title />
<Dialog.Description />
<Dialog.Close />
</Dialog.Content>
</Theme>
</Dialog.Portal>
</Dialog.Root>
);
}
Components like Dialog and Popover in Radix Themes already handle this for you, so this is only necessary when creating your own portalled components.
Usually, youâd want your custom CSS to override Radix Themes styles. However, there are cases when it is natural to expect the opposite.
Consider a simple paragraph style that just resets the browserâs default margin:
.my-paragraph {
margin: 0;
}
You might apply the margin prop from a Box onto your custom paragraph via asChild:
import "@radix-ui/themes/styles.css";
import "./my-styles.css";
function MyApp() {
return (
<Theme>
<Box asChild m="5">
<p className="my-paragraph">My custom paragraph</p>
</Box>
</Theme>
);
}
Yet, this wonât work intuitively. The custom styles are imported after Radix Themes styles, so they will override the margin prop. As a workaround, Radix Themes provides separate tokens.css, components.css, and utilities.css files that the original styles.css is built upon:
import "@radix-ui/themes/tokens.css";
import "@radix-ui/themes/components.css";
import "@radix-ui/themes/utilities.css";
You can import utilities.css after your custom styles to ensure that the layout props work as expected with your custom styles. However, if you use Next.js, keep in mind the import order issue
thatâs mentioned above.
If you use standalone layout components , split CSS files are also available for them:
import "@radix-ui/themes/layout/tokens.css";
import "@radix-ui/themes/layout/components.css";
import "@radix-ui/themes/layout/utilities.css";
PreviousGetting started
NextLayout