---
type: reference
title: 用 CSS 给组件设样式
summary: 从你自己的样式表给组件外壳设样式，用 ::part() 选择器和 --cpt-skin 自定义属性，外加每个 part 和变量的参考。
---

组件在一个开放的 shadow root 里渲染，并给你两种从你自己的页面给它设样式的方式：**shadow part**（用 `::part()` 瞄准一个元素）和 **CSS 自定义属性**（用 `--cpt-skin-*` 覆盖一个颜色）。对于颜色和措辞，优先用 [白标](/docs/widget-customization/white-label)（它就是为那个而造的，并随每一次嵌入一起旅行）；当你想要一个页面本地的微调、或某个白标不覆盖的东西时，再去用这里的 CSS 面。

这只是组件外壳。游戏跑在一个你无法从页面设样式的、独立的沙箱化的框里。

## 瞄准一个 part

用 `::part(name)` 在元素上选一个 part：

```css
caputchin-widget::part(simple-checkbox) {
  border-radius: 1rem;
}

caputchin-game::part(game-frame) {
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
}
```

几个实用的注意点：

- shadow root 是开放的，所以从你页面来的 `::part()` 在每个现代浏览器里都能用。
- 一些结构性的 part（复选框容器、游戏框）带着内联应用在元素上的基础布局样式。要覆盖那些属性之一，你可能需要 `!important`，因为一个内联样式压过一条普通的 `::part()` 规则。文本和品牌 part 不用它就能干净地设样式。
- part 就是那个设样式的面；组件不暴露它的内部类名，而它们可能会变。按 part 设样式，不要靠扒进 shadow 树。

## 复选框组件上的 part

这些出现在 `<caputchin-widget>` 上（以及 `<caputchin-game>` 的赛前覆盖层上，它复用同一个品牌块）。

| Part | 它是什么 |
|---|---|
| `simple-checkbox` | 外层复选框容器（边框、背景、内边距）。 |
| `simple-shield-box` | 显示验证状态的盾形指示器。 |
| `simple-shield-spinner` | 验证时盾形里面的旋转弧。 |
| `simple-checkbox-label` | 状态文本（验证、正在验证、已验证、失败）。 |
| `simple-brand` | 品牌块（徽标、名称和标语在一起）。 |
| `simple-brand-home` | 包住徽标和名称的链接，指向主页链接。 |
| `simple-brand-logo` | 品牌徽标图像。 |
| `simple-brand-name` | 品牌字标文本。 |
| `simple-brand-tag` | 品牌标语行，一个指向法律链接的链接。 |

## 游戏组件上的 part

这些出现在 `<caputchin-game>` 上，环绕那个沙箱化的游戏框。

| Part | 它是什么 |
|---|---|
| `game-frame` | 游戏周围的外饰框。 |
| `game-iframe-slot` | 持有游戏沙箱化 iframe 的那个槽。 |
| `game-slot` | 游戏渲染进去的那个投影容器。 |
| `game-badge-slot` | 显示在游戏下方的品牌徽章。 |
| `game-overlay-host` | 赛前覆盖层的宿主（在游戏开始前显示）。 |
| `game-overlay-checkbox` | 那个覆盖层里的复选框。 |
| `game-overlay-dialog` | 覆盖层对话框，在 modal 和 fullscreen 布局里。 |
| `game-overlay-close` | 覆盖层关闭按钮，仅在 modal 和 fullscreen 布局里。 |

## 颜色变量

组件把它解析出的外壳颜色作为命名为 `--cpt-skin-<token>` 的 CSS 自定义属性写到宿主元素上，而它自己的样式读它们。你可以从你的样式表通过在元素上设置那个属性来覆盖单个颜色：

```css
caputchin-widget {
  --cpt-skin-primary: #7c3aed !important;
  --cpt-skin-surface_bg: #faf5ff !important;
}
```

那个 `!important` 要紧：组件在解析皮肤时把这些属性内联设在宿主上，而一个内联值压过一条普通的样式表规则，所以一个普通的覆盖会被忽略。这些只是外壳的颜色；它们不到达框里面的游戏。

这是那个页面本地的逃生舱口。要在每一次嵌入上更改颜色，改 [在白标里设一个皮肤](/docs/widget-customization/white-label)；它用同样的 token 名。

| 变量 | 它给什么上色 |
|---|---|
| `--cpt-skin-primary` | 主操作色：激活的盾形、聚焦环和已验证状态。 |
| `--cpt-skin-primary_hover` | 主色的悬停变体。 |
| `--cpt-skin-surface_bg` | 组件的背景。 |
| `--cpt-skin-text_primary` | 主文本。 |
| `--cpt-skin-text_label` | 状态标签文本（验证、正在验证，等等）。 |
| `--cpt-skin-text_muted` | 次要文本，包括品牌标语。 |
| `--cpt-skin-text_passive` | 组件等待时的盾形轮廓。 |
| `--cpt-skin-separator` | 紧凑布局里品牌各块之间的分隔。 |
| `--cpt-skin-border` | 组件的边框。 |
| `--cpt-skin-glyph` | 盾形里面画的对勾或警示字形。 |
| `--cpt-skin-error` | 错误状态色。 |
| `--cpt-skin-shadow` | 组件的投影。 |
| `--cpt-skin-modal_backdrop` | modal 布局游戏覆盖层背后的背幕。 |
| `--cpt-skin-fullscreen_backdrop` | fullscreen 布局游戏覆盖层背后的背幕。 |
| `--cpt-skin-close_btn_bg` | fullscreen 覆盖层关闭按钮的背景。 |
| `--cpt-skin-brand_text` | 品牌链接文本色。 |
| `--cpt-skin-brand_text_hover` | 品牌链接悬停时的颜色。 |

品牌徽标是一个独立的皮肤 token（一个图像，不是一个颜色），所以它通过 [白标](/docs/widget-customization/white-label) 替换，而非 CSS。同样的 token 名及其亮和暗默认在 [模式参考](/docs/references/customization-schema) 里。

这些 `--cpt-skin-*` 变量只携带 **组件外壳的** 皮肤。一个 **游戏** 把它自己的皮肤作为交给它代码的值来接收（不是作为 CSS 变量，而且你无法从你的页面给一个游戏设样式）；见 [自定义一个游戏的皮肤](/docs/game-customization/skin#how-a-skin-value-reaches-the-game)。

## 另见

- [给组件做白标](/docs/widget-customization/white-label)：用受支持的方式更改措辞、颜色和链接。
- [组件如何解析它的语言和皮肤](/docs/widget-customization/resolution)：在你设样式之前外壳渲染什么。
- [我们的理念](/docs/understanding-caputchin/philosophy)：为什么这个设样式的面在每个套餐上都开放且免费。
