共计 1979 个字符,预计需要花费 5 分钟才能阅读完成。
为什么我们需要设计系统
最近在重构公司老项目时,我深刻体会到传统 CSS 编写方式的痛点:

- 样式冲突 :
.card在不同页面表现不一致,不得不使用!important救火 - 响应式臃肿:媒体查询散落在各处,修改断点需要全局搜索
- 维护困难:新同事不敢动老 CSS,只能不断追加新样式
这些正是设计系统 (Design System) 要解决的问题。下面分享我们团队从混乱到规范的实践历程。
技术方案选型
方法论对比
- BEM (Block Element Modifier)
- 优点:命名约定简单,适合中小项目
-
缺点:无法解决 CSS 特异性 (Specificity) 问题
-
ITCSS (Inverted Triangle CSS)
- 优点:通过分层结构控制特异性
-
示例分层:
Settings → Tools → Generic → Elements → Objects → Components → Utilities -
CSS-in-JS
- 优点:完美的组件隔离
- 缺点:SSR 性能损耗,学习成本高
我们最终选择 ITCSS+Sass 的组合,因为它:
– 保持纯 CSS 优势
– 适合大型项目长期维护
– 与现有技术栈无缝集成
核心实现
设计令牌(Design Tokens)
设计令牌是样式系统的原子单位,比如颜色、间距等。我们这样实现:
// types/tokens.d.ts
type TokenScale = '50' | '100' | '200' | '300' | '400' | '500';
interface DesignTokens {
color: {
primary: Record<TokenScale, string>;
neutral: Record<TokenScale, string>;
};
spacing: Record<TokenScale, string>;
breakpoints: {
sm: string;
md: string;
lg: string;
};
}
// tokens/_variables.scss
:root {
// 颜色定义
--color-primary-100: #e0f2fe;
--color-primary-500: #0ea5e9;
// 间距系统
--spacing-100: 0.25rem;
--spacing-200: 0.5rem;
// 断点系统
--breakpoint-sm: 640px;
--breakpoint-md: 768px;
}
响应式断点系统
通过 Sass mixin 实现优雅的媒体查询:
// tools/_breakpoints.scss
@mixin respond-to($breakpoint) {@if map-has-key($breakpoints, $breakpoint) {@media (min-width: map-get($breakpoints, $breakpoint)) {@content;}
} @else {@warn "Undefined breakpoint: #{$breakpoint}";
}
}
// 使用示例
.card {padding: var(--spacing-200);
@include respond-to('md') {padding: var(--spacing-300);
}
}
避坑指南
控制 CSS 特异性
-
避免嵌套过深
// 错误示范 .sidebar { .nav {li { /* 特异性过高 */} } } -
善用工具类
<!-- 优于自定义样式 --> <button class="padding-200 text-primary-500">
主题切换优化
动态主题的关键是 CSS 变量 + 类名切换:
// 主题切换时不重绘 DOM
function toggleTheme() {document.documentElement.classList.toggle('dark-theme');
}
// CSS 通过变量控制
:root.dark-theme {--color-primary-500: #38bdf8;}
进阶实践
与 Storybook 集成
- 安装
@storybook/addon-designs - 创建设计规范文档:
export default { title: 'Design System/Colors', parameters: { design: { type: 'figma', url: 'https://figma.com/file/...' } } };
拥抱 CSS 新特性
容器查询 (Container Queries) 将改变响应式设计方式:
/* 根据容器宽度而非视口响应 */
.card {container-type: inline-size;}
@container (min-width: 400px) {.card__title { font-size: 1.2rem;}
}
总结
这次设计系统改造后,我们的收获:
- UI 变更响应速度提升 60%
- CSS 体积减少 45%
- 新成员上手时间缩短 70%
建议从设计令牌开始逐步重构,不必追求一步到位。记住:好的设计系统是长出来的,不是设计出来的。
正文完
