技术手册
CSS 样式与作用域
从一张状态卡开始,再使用平台稳定选择器调整聊天界面。
换配色、改气泡,直接跟 AI 创作助手说,还能发参考图(见第 10 关)。这一页讲 CSS 能改哪里、怎么检查。
CSS 负责改变外观,不负责修改消息内容。优先美化正则替换产生的自定义类名,再按需要调整平台聊天区域。
先做出第一张卡片
上一页的正则会生成:
<aside class="status-card">地点:玻璃温室</aside>把下面代码加入角色的“全局 CSS”:
.status-card {
box-sizing: border-box;
max-width: 100%;
margin: 0.75rem 0;
padding: 0.75rem 1rem;
border: 1px solid #a85c8d;
border-radius: 0.875rem;
background: #fff4fa;
color: #5f304d;
line-height: 1.6;
overflow-wrap: anywhere;
}
@media (prefers-color-scheme: dark) {
.status-card {
border-color: #b7779e;
background: #3b2934;
color: #f5dce9;
}
}
@media (max-width: 480px) {
.status-card {
padding: 0.7rem 0.8rem;
}
}聊天预览中应该出现一张玫瑰色描边的状态卡。窄屏时卡片不能超过消息宽度,长文字需要自动换行。
.status-card 是本例自己的类名,最容易控制,也不依赖平台页面结构。
平台稳定选择器
需要调整整个聊天区域时,优先使用这些语义选择器:
| 选择器 | 对象 |
|---|---|
.charx-chat-bg | 聊天背景容器 |
[data-charx-slot="nav"] | 导航区域 |
[data-charx-slot="messages"] | 消息列表 |
[data-charx-slot="message-row"] | 消息行 |
[data-charx-slot="message-surface"] | 消息气泡或内容表面 |
.charx-message-surface--assistant | 角色消息表面 |
.charx-message-surface--user | 用户消息表面 |
.message-body | 消息正文 |
[data-charx-slot="input-bar"] | HTML 输入栏区域 |
[data-charx-slot="input-box"] | HTML 输入框区域 |
[data-charx-slot="send-button"] | HTML 发送按钮 |
不要依赖 Tailwind 组合类、临时生成的 class、复杂 DOM 层级或 nth-child 顺序。这些写法容易在页面更新后失效。
最小聊天主题
.charx-chat-bg {
--charx-color-primary: #a85c8d;
background: #f7f2f6;
}
[data-charx-slot="message-surface"] {
border-radius: 0.875rem;
}
.charx-message-surface--assistant {
border: 1px solid #dfced8;
background: #fff9fc;
}
.charx-message-surface--user {
background: #9d5b82;
color: #fff9fc;
}完整版本和交互预览见聊天主题美化。
常用 CSS 变量
CSS 变量适合统一颜色、圆角和正文排版。先在 .charx-chat-bg 上覆盖,再由内部元素读取。
| 变量 | 用途 |
|---|---|
--charx-color-primary | 角色主题主色 |
--charx-color-bg | 聊天背景色 |
--charx-color-bg-bubble-user | 用户消息背景 |
--charx-color-bg-bubble-char | 角色消息背景 |
--charx-color-text | 主要文字色 |
--charx-color-text-muted | 次要文字色 |
--charx-color-border | 边框色 |
--charx-bubble-radius | 消息圆角 |
--charx-bubble-padding | 消息内边距 |
--charx-font-family | 消息正文字体 |
--charx-font-size-base | 消息基础字号 |
--charx-line-height | 消息正文行高,默认 1.85 |
--charx-message-gap | 消息之间的间距 |
--charx-avatar-size | 消息头像尺寸 |
--charx-dialogue-color | 台词颜色 |
--charx-action-color | 动作文字颜色 |
--charx-ooc-color | OOC 或补充说明颜色 |
--charx-name-color | 角色名颜色 |
变量只会影响实际读取它们的元素。完整 HTML 中写死的颜色不会自动跟随变量改变,宿主主题和更高优先级规则也会影响结果。
HTML 消息为什么可能不一样
HTML 消息可能位于独立 iframe 或 Shadow DOM。外层选择器无法跨过这些边界。消息内部内容应使用自己的类名,例如 .status-card 或 .intel-panel。
平台会在相应 HTML 渲染路径传入角色 CSS,但每个宿主的隔离方式不同,所以消息内部布局仍要分别检查。
Creator、Web、App 的作用域
| 环境 | 当前边界 |
|---|---|
| Creator 编辑预览 | 选择器会改写到 [data-charx-preview-runtime],html、body、:root 映射到预览根 |
| Web 正式聊天 | 角色 CSS 作为 style 注入页面,没有 Creator 的预览前缀改写 |
| App 聊天 | 角色 CSS 注入聊天 WebView;原生界面不属于这份 DOM |
原生输入栏不能被 HTML 选择器直接控制
App 开启原生输入模式时,WebView 输入区域会隐藏。input-bar 等选择器不能直接命中原生组件,平台只桥接部分外观信息。键盘、安全区和滚动必须在 App 单独检查。
CSS 片段按编辑器顺序合并。片段名称只是管理信息,不会自动形成独立作用域。尽量给自定义组件使用独特根类名。
动画怎么写
只动画 opacity 和 transform,并提供减少动画设置:
@media (prefers-reduced-motion: no-preference) {
.status-card {
animation: status-enter 240ms ease-out both;
}
@keyframes status-enter {
from {
opacity: 0;
transform: translateY(6px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
}
@media (prefers-reduced-motion: reduce) {
.status-card {
animation: none;
}
}不要制作遮挡输入区的固定层、持续高频粒子或无限增加 DOM 的效果。
保存前检查
- 自定义类名与替换 HTML 完全一致。
- 宿主样式只使用稳定语义选择器。
- 浅色、深色文字都能看清。
- 390px 宽度下没有横向页面滚动。
- App 原生输入模式已经单独检查。
- 动画支持
prefers-reduced-motion。 - 合并后的全局 CSS 不超过 500 × 1024 字节(500 KiB)。
- 代码不包含
@import、expression()、behavior:、javascript:、vbscript:或-moz-binding。
下一步:查看JavaScript Hook 与交互,或从四个美化实例挑一个开始。