第 53 章

LSP Server 插件:9种官方语言服务器集成与自定义 LSP 配置

第五十三章:主题与外观插件:CSS 变量、Dark Mode 与品牌定制

53.1 外观插件的定位与价值

Claude Code 是一个以文本为核心的工具,但视觉体验对生产力的影响不可忽视。长时间使用默认主题会造成视觉疲劳;企业用户需要将工具的外观与品牌视觉系统对齐;不同的工作环境(白天/黑夜、高对比度需求、色盲友好模式)需要不同的色彩方案。

外观 Plugin(Theme Plugin)解决的就是这一类需求。它通过向 Claude Code 注入 CSS 变量和样式覆盖,在不修改核心代码的前提下实现深度的视觉定制。

与功能型 Plugin 不同,外观 Plugin 通常:

53.2 Claude Code 的 CSS 变量系统

变量分层架构

Claude Code 的样式系统基于 CSS 自定义属性(CSS Custom Properties,即 CSS 变量)构建,分为三个层次:

基础令牌(Base Tokens)
  ├── 原始色值(如 --cc-color-blue-500: #3B82F6)
  └── 原始尺寸(如 --cc-spacing-4: 16px)

语义令牌(Semantic Tokens)
  ├── 功能色(如 --cc-color-primary: var(--cc-color-blue-500))
  └── 角色色(如 --cc-color-text-primary: #1a1a1a)

组件令牌(Component Tokens)
  ├── 按钮(如 --cc-button-bg: var(--cc-color-primary))
  └── 输入框(如 --cc-input-border: var(--cc-color-border))

主题 Plugin 主要操作语义令牌层,偶尔调整组件令牌。直接修改基础令牌会影响范围过大,容易破坏视觉一致性。

核心语义变量完整列表

/* === 文字颜色 === */
--cc-color-text-primary          /* 主要文字 */
--cc-color-text-secondary        /* 次要文字(注释、标签) */
--cc-color-text-tertiary         /* 三级文字(占位符、禁用状态) */
--cc-color-text-inverse          /* 反色文字(深色背景上的白字) */
--cc-color-text-accent           /* 强调文字(链接、高亮) */
--cc-color-text-error            /* 错误文字 */
--cc-color-text-success          /* 成功文字 */
--cc-color-text-warning          /* 警告文字 */

/* === 背景颜色 === */
--cc-color-bg-primary            /* 主背景 */
--cc-color-bg-secondary          /* 次级背景(侧边栏、面板) */
--cc-color-bg-tertiary           /* 三级背景(卡片、弹窗) */
--cc-color-bg-elevated           /* 浮起背景(下拉菜单、tooltip) */
--cc-color-bg-hover              /* 悬停状态背景 */
--cc-color-bg-active             /* 激活状态背景 */
--cc-color-bg-code               /* 代码块背景 */

/* === 边框颜色 === */
--cc-color-border                /* 默认边框 */
--cc-color-border-strong         /* 强调边框 */
--cc-color-border-focus          /* 焦点边框(聚焦状态) */

/* === 功能色 === */
--cc-color-primary               /* 品牌主色(按钮、链接) */
--cc-color-primary-hover         /* 主色悬停态 */
--cc-color-primary-active        /* 主色激活态 */

/* === 代码高亮 === */
--cc-syntax-keyword              /* 关键字 */
--cc-syntax-string               /* 字符串 */
--cc-syntax-comment              /* 注释 */
--cc-syntax-number               /* 数字 */
--cc-syntax-function             /* 函数名 */
--cc-syntax-variable             /* 变量名 */
--cc-syntax-operator             /* 运算符 */
--cc-syntax-type                 /* 类型名 */

/* === 字体排版 === */
--cc-font-family-sans            /* 无衬线字体 */
--cc-font-family-mono            /* 等宽字体(代码) */
--cc-font-size-base              /* 基础字号 */
--cc-line-height-base            /* 基础行高 */

/* === 间距与圆角 === */
--cc-radius-sm                   /* 小圆角 */
--cc-radius-md                   /* 中圆角 */
--cc-radius-lg                   /* 大圆角 */

53.3 Theme Plugin 项目结构

my-theme-plugin/
├── plugin.json
├── themes/
│   ├── light.css          ← 浅色主题变量
│   ├── dark.css           ← 深色主题变量
│   └── high-contrast.css  ← 高对比度变量
├── theme.json             ← 主题元数据和注册信息
├── preview/
│   ├── light.png          ← 浅色主题预览图(市场展示用)
│   └── dark.png           ← 深色主题预览图
└── README.md

plugin.json(主题专用字段)

{
  "name": "acme-brand-theme",
  "version": "1.0.0",
  "description": "ACME Corporation brand theme for Claude Code",
  "author": "ACME Design Team <[email protected]>",
  "license": "MIT",
  "keywords": ["theme", "brand", "corporate"],
  
  "type": "theme",
  
  "theme": {
    "variants": [
      {
        "id": "acme-light",
        "name": "ACME Light",
        "appearance": "light",
        "stylesheet": "./themes/light.css"
      },
      {
        "id": "acme-dark",
        "name": "ACME Dark",
        "appearance": "dark",
        "stylesheet": "./themes/dark.css"
      },
      {
        "id": "acme-high-contrast",
        "name": "ACME High Contrast",
        "appearance": "dark",
        "stylesheet": "./themes/high-contrast.css",
        "tags": ["accessibility", "high-contrast"]
      }
    ],
    "defaultVariant": "acme-light",
    "previewImages": {
      "acme-light": "./preview/light.png",
      "acme-dark": "./preview/dark.png"
    }
  },
  
  "engines": {
    "claude-code": ">=1.0.0"
  },
  
  "permissions": []
}

注意 type: "theme" 声明——这告诉 Claude Code 这是一个纯外观 Plugin,不需要启动任何子进程。

53.4 编写主题 CSS

浅色主题示例

/* themes/light.css */
/* ACME Brand Light Theme */

:root[data-theme="acme-light"] {
  /* === 品牌色系 === */
  /* ACME 品牌主色:深海蓝 */
  --cc-color-primary: #0047AB;
  --cc-color-primary-hover: #003580;
  --cc-color-primary-active: #002460;
  
  /* === 背景色系 === */
  --cc-color-bg-primary: #FFFFFF;
  --cc-color-bg-secondary: #F5F7FA;
  --cc-color-bg-tertiary: #EDF0F5;
  --cc-color-bg-elevated: #FFFFFF;
  --cc-color-bg-hover: rgba(0, 71, 171, 0.06);
  --cc-color-bg-active: rgba(0, 71, 171, 0.12);
  --cc-color-bg-code: #F8F9FC;
  
  /* === 文字色系 === */
  --cc-color-text-primary: #1A1D23;
  --cc-color-text-secondary: #4B5568;
  --cc-color-text-tertiary: #9AA5B4;
  --cc-color-text-inverse: #FFFFFF;
  --cc-color-text-accent: #0047AB;
  
  /* === 边框色系 === */
  --cc-color-border: #D1D9E6;
  --cc-color-border-strong: #A8B4C8;
  --cc-color-border-focus: #0047AB;
  
  /* === 状态色 === */
  --cc-color-text-error: #C0392B;
  --cc-color-text-success: #1A7340;
  --cc-color-text-warning: #C17D00;
  
  /* === 代码语法高亮 === */
  --cc-syntax-keyword: #0047AB;
  --cc-syntax-string: #1A7340;
  --cc-syntax-comment: #9AA5B4;
  --cc-syntax-number: #C17D00;
  --cc-syntax-function: #6B3FA0;
  --cc-syntax-variable: #1A1D23;
  --cc-syntax-operator: #4B5568;
  --cc-syntax-type: #B83C1E;
  
  /* === 字体 === */
  --cc-font-family-sans: 'Inter', 'SF Pro Display', -apple-system, sans-serif;
  --cc-font-family-mono: 'JetBrains Mono', 'Fira Code', monospace;
  --cc-font-size-base: 14px;
  --cc-line-height-base: 1.6;
  
  /* === 圆角 === */
  --cc-radius-sm: 4px;
  --cc-radius-md: 6px;
  --cc-radius-lg: 12px;
}

深色主题示例

/* themes/dark.css */
/* ACME Brand Dark Theme */

:root[data-theme="acme-dark"] {
  /* === 品牌色系(深色模式下适当调亮) === */
  --cc-color-primary: #4D9FFF;
  --cc-color-primary-hover: #6FB3FF;
  --cc-color-primary-active: #91C5FF;
  
  /* === 背景色系 === */
  --cc-color-bg-primary: #0D1117;
  --cc-color-bg-secondary: #161B22;
  --cc-color-bg-tertiary: #21262D;
  --cc-color-bg-elevated: #2D333B;
  --cc-color-bg-hover: rgba(77, 159, 255, 0.08);
  --cc-color-bg-active: rgba(77, 159, 255, 0.16);
  --cc-color-bg-code: #161B22;
  
  /* === 文字色系 === */
  --cc-color-text-primary: #E6EDF3;
  --cc-color-text-secondary: #8B949E;
  --cc-color-text-tertiary: #484F58;
  --cc-color-text-inverse: #0D1117;
  --cc-color-text-accent: #4D9FFF;
  
  /* === 边框色系 === */
  --cc-color-border: #30363D;
  --cc-color-border-strong: #484F58;
  --cc-color-border-focus: #4D9FFF;
  
  /* === 状态色 === */
  --cc-color-text-error: #F85149;
  --cc-color-text-success: #3FB950;
  --cc-color-text-warning: #D29922;
  
  /* === 代码语法高亮 === */
  --cc-syntax-keyword: #FF7B72;
  --cc-syntax-string: #A5D6FF;
  --cc-syntax-comment: #8B949E;
  --cc-syntax-number: #F2CC60;
  --cc-syntax-function: #D2A8FF;
  --cc-syntax-variable: #E6EDF3;
  --cc-syntax-operator: #8B949E;
  --cc-syntax-type: #FFA657;
}

高对比度主题

高对比度主题的设计原则与普通主题有所不同——可读性优先,美观性次之:

/* themes/high-contrast.css */

:root[data-theme="acme-high-contrast"] {
  /* 背景:纯黑 */
  --cc-color-bg-primary: #000000;
  --cc-color-bg-secondary: #0A0A0A;
  --cc-color-bg-code: #000000;
  
  /* 文字:纯白,确保 WCAG AAA 对比度 */
  --cc-color-text-primary: #FFFFFF;
  --cc-color-text-secondary: #E0E0E0;
  --cc-color-text-tertiary: #B0B0B0;
  
  /* 主色:亮黄,最高可见度 */
  --cc-color-primary: #FFD700;
  --cc-color-primary-hover: #FFEA00;
  --cc-color-text-accent: #FFD700;
  
  /* 边框:清晰可见 */
  --cc-color-border: #808080;
  --cc-color-border-strong: #C0C0C0;
  --cc-color-border-focus: #FFD700;
  
  /* 状态色:高饱和度确保可区分 */
  --cc-color-text-error: #FF4444;
  --cc-color-text-success: #00FF88;
  --cc-color-text-warning: #FFAA00;
  
  /* 增大字号确保可读性 */
  --cc-font-size-base: 15px;
  --cc-line-height-base: 1.8;
}

53.5 Dark Mode 自动切换机制

跟随系统偏好

Claude Code 支持自动跟随系统的 Dark Mode 设置。在 theme.json 中配置自动切换规则:

{
  "autoSwitch": {
    "enabled": true,
    "lightVariant": "acme-light",
    "darkVariant": "acme-dark"
  }
}

启用后,Claude Code 会监听 prefers-color-scheme 媒体查询,当系统切换深/浅色模式时自动切换对应的主题变量。

用户手动切换

即使启用了自动切换,用户也可以手动锁定某个主题:

# 手动设置主题
claude config set theme acme-dark

# 切换回自动模式
claude config set theme auto

53.6 字体定制

内置字体与外部字体

主题 Plugin 可以使用两类字体:

内置字体:Claude Code 内置了常见的等宽字体(JetBrains Mono、Fira Code、Cascadia Code)和无衬线字体(Inter、SF Pro)。直接在 CSS 变量中引用即可。

外部字体:如果你的品牌字体不在内置列表中,需要在 plugin.json 中声明字体资源:

{
  "theme": {
    "fonts": [
      {
        "family": "ACME Sans",
        "sources": [
          {
            "url": "./fonts/ACMESans-Regular.woff2",
            "weight": 400,
            "style": "normal"
          },
          {
            "url": "./fonts/ACMESans-Bold.woff2",
            "weight": 700,
            "style": "normal"
          }
        ]
      }
    ]
  }
}

字体文件放在 Plugin 包中,Claude Code 会在加载主题时自动注册这些字体。

代码等宽字体的特殊性

代码编辑区域的等宽字体选择对开发者体验影响显著。几个实践建议:

/* 建议:提供字体降级栈 */
--cc-font-family-mono: 
  'JetBrains Mono',      /* 首选:连字支持,开发者友好 */
  'Fira Code',           /* 备选:开源,跨平台一致 */
  'Cascadia Code',       /* Windows 备选 */
  'SF Mono',             /* macOS 系统备选 */
  'Consolas',            /* Windows 系统备选 */
  monospace;             /* 最终降级 */

/* 启用连字(如果字体支持) */
font-feature-settings: "liga" 1, "calt" 1;

53.7 组件级定制

对于标准 CSS 变量无法覆盖的定制需求,主题 Plugin 支持组件级别的 CSS 覆盖:

/* themes/light.css 末尾追加 */

/* 定制侧边栏宽度 */
.cc-sidebar {
  width: 280px;
}

/* 定制对话气泡样式 */
.cc-message-bubble--assistant {
  border-left: 3px solid var(--cc-color-primary);
  border-radius: 0 var(--cc-radius-md) var(--cc-radius-md) 0;
}

/* 定制工具调用展示卡片 */
.cc-tool-call-card {
  background: var(--cc-color-bg-code);
  border: 1px solid var(--cc-color-border);
  font-family: var(--cc-font-family-mono);
  font-size: 12px;
}

使用组件级定制时需要注意:Claude Code 的内部 CSS 类名可能在版本升级时发生变化,建议在 plugin.jsonengines.claude-code 中声明精确的版本范围,并在升级后测试样式兼容性。

53.8 主题预览图规范

市场展示页面会显示主题预览图,直接影响用户的安装决策。预览图规范:

尺寸:1280 × 800 像素(16:10 比例)
格式:PNG,JPEG 或 WebP(建议 PNG 保留细节)
最大文件大小:500 KB
内容要求:
  ├── 展示对话界面(包含用户消息和 Claude 回复)
  ├── 展示代码块(体现语法高亮色彩)
  ├── 展示侧边栏(体现整体布局和色调)
  └── 不可包含真实的个人信息或企业机密内容

53.9 主题的可访问性验证

发布前必须验证主题的可访问性。WCAG 2.1 AA 标准要求:

# 使用内置可访问性检查工具
claude-plugin theme check-accessibility ./themes/light.css

# 输出示例:
# Checking accessibility for acme-light theme...
# ✓ --cc-color-text-primary on --cc-color-bg-primary: 12.4:1 (AAA)
# ✓ --cc-color-text-secondary on --cc-color-bg-primary: 5.2:1 (AA)
# ✗ --cc-color-text-tertiary on --cc-color-bg-primary: 2.8:1 (FAIL)
#   ↳ Required: 4.5:1 for normal text
#   ↳ Suggestion: Darken --cc-color-text-tertiary to #767676 or darker

所有 AA 级别不通过的对比度组合都会导致市场审核失败。


小结

主题 Plugin 通过 CSS 变量系统实现非侵入式的视觉定制,其核心是理解 Claude Code 的三层变量体系(基础令牌 → 语义令牌 → 组件令牌)并优先操作语义层。深色模式自动切换、自定义字体、高对比度可访问性支持是高质量主题 Plugin 的必备特性。发布前的可访问性验证不只是审核要求,也是对所有用户的基本尊重。下一章转向技术深度更高的 LSP Plugin 开发。

本章评分
4.9  / 5  (3 评分)

💬 留言讨论