CSS 与 SCSS 规范
BBC 8.0 使用普通 CSS 与 SCSS。页面局部样式优先写在 Vue 组件的 scoped style 中;跨页面主题和公共布局样式放在共享入口,不能靠业务页面覆盖 TDesign 内部结构形成第二套设计系统。
格式
项目 Prettier 配置的关键值:
- 两个空格缩进,不使用 Tab。
- 单行宽度 120。
- LF 换行。
- Vue 的 script 和 style 不额外缩进。
每条声明独占一行并保留分号。零值不带无意义单位,颜色和空格交给 Prettier 保持一致。
.goods-card {
display: flex;
gap: 12px;
align-items: center;
padding: 16px;
color: var(--shop-color-text-primary);
background: var(--shop-color-bg-container);
border: 1px solid var(--shop-color-border);
border-radius: 8px;
}
样式归属
| 范围 | 位置 |
|---|---|
| 单个页面或组件 | 对应 .vue 的 <style scoped> |
| 单个应用全局样式 | apps/<app>/src/assets/styles |
| Admin/Seller 公共表格样式 | packages/components/styles/backend-table.scss |
| 跨后台主题变量 | packages/core/styles/theme.scss |
| 装修组件样式 | packages/decor 内对应组件或 styles |
只有组件确实需要 SCSS 嵌套或变量时使用 lang="scss":
<style lang="scss" scoped>
.goods-list-page {
&__toolbar {
display: flex;
gap: 12px;
}
}
</style>
新 SCSS 模块之间优先使用 @use。不要在业务组件中重复导入全局主题文件,主题由应用启动链路统一安装。
class 命名
采用小写 kebab-case 与 block、element、modifier 关系:
.order-detail-page {
&__summary {
display: grid;
}
&__item--warning {
color: var(--td-error-color);
}
}
- block 使用页面或组件的稳定业务名。
- element 使用
__,modifier 使用--。 - 不使用
.red、.left-20等只描述视觉结果的名称。 - 不复用 TDesign 内部 class 作为业务 block。
- 不用 ID 选择器编写可复用样式。
主题变量
Admin 和 Seller 的明暗主题变量集中在 packages/core/styles/theme.scss。常用变量包括:
var(--shop-color-bg-page)
var(--shop-color-bg-container)
var(--shop-color-border)
var(--shop-color-text-primary)
var(--shop-color-text-secondary)
var(--shop-color-brand)
var(--shop-shadow-md)
后台业务页面不要硬编码大面积白色背景、固定文字黑色或品牌蓝色,否则暗色模式会失效。确实属于业务语义的成功、警告和错误色优先使用 TDesign token。
买家 PC 另有 --buyer-primary-color、--buyer-price-color 等主题变量。价格和品牌组件应读取变量,不要在每个页面复制固定红色。
scoped 与 :deep
页面和端内组件默认使用 scoped style,避免选择器跨页面污染。只有以下情况考虑全局样式:
- 应用根级 reset、字体和主题。
- 多页面统一的后台表格或布局协议。
- 第三方组件确实需要全局修正且已有共享入口。
:deep() 只用于当前组件必须影响的子组件结构。优先扩展公共组件 props 或共享样式,不要在多个业务页重复覆盖 .t-tabs__header、.t-table 等 TDesign 内部结构。
例如 Admin/Seller 页签应直接使用 BackendTabs,列表应优先使用 TableLayout,而不是在页面重做其外观。
布局与完整内容
- 优先使用 flex、grid 和 gap 表达布局。
- 不用空 div、连续
<br>或不可解释的固定高度制造间距。 - 表格超宽时保留字段内容,由 TableLayout 和 TTable 横向滚动承载。
- 订单号、流水号等不可拆分标识保持单行;自然文本可换行。
- fixed/sticky 元素必须考虑占位、窄视口和页面卸载清理。
PageActionBar自己管理 AppShell 内容区占位,页面不得再补底部 padding。
响应式与单位
普通 PC、Admin 和 Seller 页面使用 px、rem、百分比、flex 和 grid 等 Web 单位。断点应放在相关组件附近,并验证内容而不是只缩放视觉。
rpx 只允许在 packages/decor/components/decor/mobile/**/*.vue 使用。Vite 插件按 750rpx 设计宽度、375px 预览宽度转换;其他路径不会自动转换 rpx。
@media (max-width: 640px) {
.example-form__field {
width: 100%;
}
}
PC 买家站当前以 1210px 桌面布局为主。不要假装它已经是完整移动响应式站点,也不要用移动端装修预览规则改写普通 PC 页面。
图片与字体
- 页面业务图片放在对应 app 的
src/assets,共享组件资源放在所属 package。 - 文件名使用小写 kebab-case 并表达用途。
- 可压缩的位图先压缩,图标优先复用现有图标系统或 SVG。
- CSS 背景图应通过模块导入或可被 Vite 解析的相对路径引用。
- 不把 base64 大图直接写入样式文件。
- CDN 与部署前缀通过
VITE_ASSETS_*配置,不在 CSS 中硬编码环境域名。
注释
不要在 CSS、SCSS 或 Vue <style> 中新增注释。复杂业务意图应通过清晰 class、变量和组件边界表达;确需解释的设计决策放在临近 TypeScript 或项目文档中,避免构建产物样式充满维护说明。
不推荐写法
.box {
color: #000;
background: #fff;
}
.page :deep(.t-tabs__header) {
padding: 3px 17px;
}
#goodsTable .t-table td {
overflow: hidden;
text-overflow: ellipsis;
}
这些写法分别绕过主题、复制 TDesign 内部覆盖、以及静默截断业务内容。
检查
pnpm lint
pnpm exec prettier --check <修改文件>
按变更范围执行 pnpm build:dev:<端> 或 pnpm build:dev。浏览器验收至少检查明暗主题、长文本、空数据、表格横向滚动、窄视口以及 fixed/sticky 元素是否遮挡内容。