Files
EmailBill/openspec/changes/archive/2026-02-18-unify-card-styles-across-pages/design.md
SunCheng c49f66757e
Some checks failed
Docker Build & Deploy / Build Docker Image (push) Waiting to run
Docker Build & Deploy / Deploy to Production (push) Has been cancelled
Docker Build & Deploy / Cleanup Dangling Images (push) Has been cancelled
Docker Build & Deploy / WeChat Notification (push) Has been cancelled
1
2026-02-18 21:16:45 +08:00

5.4 KiB
Raw Blame History

Context

当前项目中三个核心页面(日历、统计、预算)使用了不同的卡片样式规范:

现状分析

  • 日历页面使用 CSS 变量系统(var(--spacing-2xl), var(--radius-lg)
  • 统计页面部分使用 CSS 变量(var(--spacing-xl), var(--radius-lg)
  • 预算页面使用硬编码数值(16px, 12px 混用)

约束条件

  • 必须保持响应式布局不被破坏
  • 必须支持暗色模式的自动适配
  • 不能影响现有的功能逻辑
  • 需要最小化对现有代码的侵入性

利益相关者

  • 前端团队:执行样式统一
  • 设计团队:确保视觉一致性
  • 用户:获得更统一的使用体验

Goals / Non-Goals

Goals:

  • 统一三个页面的卡片基础样式padding、margin、border-radius、box-shadow
  • 建立基于 CSS 变量的样式系统,方便未来维护
  • 确保所有卡片在暗色模式下表现一致
  • 为未来的组件化(如通用 Card 组件)奠定基础

Non-Goals:

  • 不创建新的通用 Card 组件(本次仅统一样式)
  • 不修改卡片内部的业务逻辑或数据展示方式
  • 不重构卡片的布局结构(如 flex 方向、grid 系统)
  • 不涉及其他页面(只针对 calendarV2、statisticsV2、budgetV2

Decisions

决策 1: 使用现有 CSS 变量系统,不引入新的样式规范

理由

  • 项目已有完整的 CSS 变量系统(Web/src/assets/theme.css
  • 日历和统计页面已部分使用该系统
  • 避免引入新的样式标准增加维护成本

替代方案

  • 创建全新的样式规范:增加学习成本,与现有系统冲突
  • 使用 Tailwind CSS项目未使用 Tailwind引入成本过高
  • 统一使用现有 CSS 变量:保持一致性,最小化改动

决策 2: 定义标准的卡片样式值

标准值(基于现有变量和最佳实践):

// 卡片容器样式
.common-card {
  background: var(--bg-secondary);
  border-radius: var(--radius-lg);         // 12px
  padding: var(--spacing-xl);              // 16px
  margin-bottom: var(--spacing-xl);        // 16px
  box-shadow: var(--shadow-sm);
}

// 卡片间距(页面级别)
.page-cards-container {
  padding: var(--spacing-xl);              // 16px (左右)
  padding-top: var(--spacing-md);          // 12px (顶部,紧跟 header)
  padding-bottom: var(--spacing-3xl);      // 24px (底部,预留安全区)
  gap: var(--spacing-xl);                  // 16px (卡片之间)
}

理由

  • var(--spacing-xl) (16px) 在移动端提供舒适的点击区域
  • var(--radius-lg) (12px) 符合现代移动端设计趋势
  • var(--shadow-sm) 提供微妙的层次感,不会过于突兀

替代方案

  • padding: 12px - 太紧凑,触控体验差
  • padding: 20px - 浪费屏幕空间
  • padding: 16px - 平衡美观与空间利用

决策 3: 渐进式迁移策略

步骤

  1. 在受影响的文件中查找硬编码的样式值(如 padding: 16px, border-radius: 12px
  2. 替换为对应的 CSS 变量(如 padding: var(--spacing-xl), border-radius: var(--radius-lg)
  3. 确保 .common-card 类在所有卡片上统一应用
  4. 验证暗色模式和不同屏幕尺寸下的显示效果

理由

  • 最小化风险,逐文件验证
  • 不引入破坏性变更
  • 易于回滚

替代方案

  • 一次性全局替换:风险高,难以定位问题
  • 创建新组件并迁移:工作量大,超出本次范围
  • 文件级逐步替换:可控、安全、可追溯

决策 4: 不创建全局共享样式文件(暂不引入)

理由

  • 当前三个页面的样式文件已经独立且清晰
  • 引入共享样式文件会增加依赖关系
  • 留待后续如果需要更多页面统一时再考虑

替代方案

  • 立即创建 common-card.scss 并全局导入:过度设计
  • 保持现状,但确保使用相同的 CSS 变量值:简单高效

Risks / Trade-offs

[风险] 样式改动可能导致布局轻微变化

缓解措施

  • 在多个设备和屏幕尺寸下进行视觉回归测试
  • 重点检查内容溢出、文字截断、图表显示问题
  • 必要时微调内部元素的间距

[风险] CSS 变量未定义导致样式回退

缓解措施

  • 确认 theme.css 中所有使用的变量已定义
  • 在替换前验证变量的计算值是否符合预期
  • 为关键样式提供 fallback 值(如 padding: var(--spacing-xl, 16px)

[风险] 暗色模式下视觉效果不一致

缓解措施

  • 测试所有卡片在暗色模式下的背景色、阴影、边框表现
  • 确保 var(--bg-secondary)var(--shadow-sm) 在暗色模式下有正确定义

[权衡] 短期内仍需手动维护样式一致性

说明

  • 本次不创建通用 Card 组件,未来新增卡片时仍需手动应用 .common-card
  • 后续可考虑将其封装为 Vue 组件(如 <CommonCard>

Open Questions

  1. 是否需要在 theme.css 中新增卡片专用的变量组

    • 例如 --card-padding, --card-radius, --card-shadow
    • 优势:语义更清晰,方便未来全局调整
    • 劣势:增加变量数量,可能产生冗余
    • 建议:暂不新增,优先使用现有 --spacing-*--radius-* 变量
  2. 是否需要为特殊卡片(如 gauge 卡片)定义例外规则

    • BudgetChartAnalysis 中的 gauge 卡片当前使用 padding: 12px
    • 建议:保持 12px因为仪表盘需要更紧凑的布局以适应图表