How to approach styling with Radix Themes.
如何处理 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.
Radix Themes 没有内置的样式系统。它没有 css
或 sx
属性,内部也不使用任何样式库。在底层,它是用原生 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.
Radix Themes 中的组件相对封闭——它们带有一组不易被覆盖的样式。它们可以在属性和主题配置允许的范围内进行自定义。
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.
然而,您也可以访问驱动 Radix Themes 组件的相同 CSS 变量。您可以使用这些令牌创建自定义组件,使其自然地融入原始主题。对令牌系统的更改被视为破坏性的。
For more information on specific tokens, refer to the corresponding guides in the Theme section.
有关特定令牌的更多信息,请参阅主题部分中的相应指南。
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:
大多数组件确实有 className
和 style
属性,但如果你发现自己需要覆盖大量样式,这是一个很好的信号,表明你应该:
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 很棒。但是,如果你计划将 Radix Themes 与 Tailwind 一起使用,请记住它的人体工程学可能会鼓励你即时创建复杂的样式,有时会毫无阻碍地深入组件内部。
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.
Tailwind 是一种不同的样式范例,可能不太适合封闭组件系统的理念,在这种系统中,定制是通过属性、令牌和在共享的构建块集上创建新组件来实现的。
If you need to create a custom component, use the same building blocks that Radix Themes uses:
如果你需要创建自定义组件,请使用 Radix Themes 使用的相同构建块:
Feel free to explore the source code of Radix Themes to see how it is built.
请随意探索 Radix Themes 的源代码,看看它是如何构建的。
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:
开箱即用,Radix Themes 的门户组件可以以任何顺序嵌套和堆叠,而不会产生冲突。例如,你可以打开一个弹出窗口,该窗口打开一个对话框,而对话框又打开另一个弹出窗口。它们都按照打开的顺序堆叠在一起:
When building your own components, use the following rules to avoid z-index conflicts:
在构建自己的组件时,请遵循以下规则以避免 z-index 冲突:
z-index
values other than auto
, 0
, or -1
in rare cases.auto
、 0
或在极少数情况下使用 -1
之外,不要使用其他 z-index
值。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.
您的主要内容和门户内容由根 <Theme>
组件的样式创建的堆叠上下文分隔开。这使您能够将门户内容堆叠在主要内容之上,而无需担心 z-index 问题。
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:
在 Next.js 13.0 到 14.1 版本中, app/**/layout.tsx
中 CSS 文件的导入顺序是不确定的,因此即使正确编写,Radix Themes 也可能会覆盖你自己的样式。
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.
这个 Next.js 问题可能会断断续续地出现和消失,或者只在开发或生产环境中发生。
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.
作为一种解决方法,你可以先通过 postcss-import 将所有 CSS 合并到一个文件中,然后只在布局中导入该文件。另外,直接在 page.tsx
文件中导入样式也是可行的。
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.
从 Tailwind v3 开始,由 @tailwind
指令生成的样式通常会附加在任何导入的 CSS 之后,无论原始导入顺序如何。特别是,Tailwind 的按钮重置样式可能会干扰 Radix Themes 按钮,导致某些按钮没有背景颜色。
Workarounds: 解决方法:
@tailwind base
不要使用 @tailwind base
@import tailwindcss/base
before Radix Themes styles. Example setup@import tailwindcss/base
手动导入 Tailwind 基础样式。示例设置When 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>
:
当你在 Radix Themes 项目中渲染自定义 portal 时,它自然会出现在根 <Theme>
组件之外,这意味着它无法访问大多数主题令牌和样式。要解决这个问题,请用另一个 <Theme>
包裹 portal 内容:
// Implementation example of a custom dialog using the low-level Dialog primitive
// Refer to https://www.radix-ui.com/primitives/docs/components/dialog
import * as Dialog from '@radix-ui/react-dialog';
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.
Radix Themes 中的 Dialog 和 Popover 等组件已经为你处理了这个问题,所以只有在创建自己的传送门组件时才需要这样做。
Usually, you’d want your custom CSS to override Radix Themes styles. However, there are cases when it is natural to expect the opposite.
通常,您希望自定义 CSS 能够覆盖 Radix Themes 的样式。然而,在某些情况下,期望相反的情况也是很自然的。
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
:
您可能会通过 asChild
将 Box
的边距属性应用到您的自定义段落上:
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:
然而,这种方式并不能直观地工作。自定义样式是在 Radix Themes 样式之后导入的,所以它们会覆盖 margin 属性。作为一种解决方法,Radix Themes 提供了单独的 tokens.css
、 components.css
和 utilities.css
文件,原始的 styles.css
就是基于这些文件构建的:
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.
您可以在自定义样式之后导入 utilities.css
,以确保布局属性能够按预期与您的自定义样式一起工作。但是,如果您使用 Next.js,请记住上面提到的导入顺序问题。
If you use standalone layout components, split CSS files are also available for them:
如果您使用独立的布局组件,也可以使用为它们提供的拆分 CSS 文件:
import '@radix-ui/themes/layout/tokens.css';
import '@radix-ui/themes/layout/components.css';
import '@radix-ui/themes/layout/utilities.css';
Styling – Radix Themes