Files
education/frontend/src/assets/styles/design-system.scss
T
2026-08-24 14:48:08 +08:00

326 lines
8.9 KiB
SCSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ============================================================
// 全局设计系统(Design System
// 收敛 Element 基元 + 统一页面结构基线 + 工具类
// 依赖 design-tokens.scss 中的 $token 与 --token
//
// 用途:业务页面优先复用以下区块/工具类,删除各自 scoped 中重复定义,
// 实现全站风格、排版、按钮统一。仅需在 index.scss 末尾引入一次。
// ============================================================
// ------------------------- 1. Element 基元收敛 -------------------------
// 1.1 按钮——统一主色、尺寸、圆角、hover/active 反馈与外光晕
.el-button {
--el-button-primary-text: #fff;
border-radius: var(--token-radius-md, 4px);
transition: background-color 0.2s, border-color 0.2s, color 0.2s,
box-shadow 0.2s;
// 主按钮统一教育绿
&.el-button--primary {
background-color: var(--token-color-primary, #00875a);
border-color: var(--token-color-primary, #00875a);
color: #fff;
&:hover,
&:focus {
background-color: var(--token-color-primary-hover, #0b9e6c);
border-color: var(--token-color-primary-hover, #0b9e6c);
}
&:active {
background-color: var(--token-color-primary-active, #006b47);
border-color: var(--token-color-primary-active, #006b47);
}
&.is-plain {
color: var(--token-color-primary, #00875a);
background-color: var(--token-color-primary-lighter, #f0f9f4);
border-color: var(--token-color-primary, #00875a);
&:hover,
&:focus {
color: #fff;
background-color: var(--token-color-primary, #00875a);
}
}
&.is-disabled {
background-color: #a0cfb8;
border-color: #a0cfb8;
color: rgba(255, 255, 255, 0.9);
}
}
// 危险按钮
&.el-button--danger {
background-color: var(--token-color-danger, #ff4949);
border-color: var(--token-color-danger, #ff4949);
&:hover,
&:focus {
background-color: #ff6b6b;
border-color: #ff6b6b;
}
}
// 聚焦外光晕(键盘可访问性),除 text 按钮外
&:focus-visible {
outline: none;
box-shadow: 0 0 0 3px var(--token-color-primary-ring, rgba(0, 135, 90, 0.35));
}
// 表格内文字操作按钮保持紧凑
&.el-button--text {
font-size: var(--token-font-size-sm, 13px);
padding: 0 4px;
&.danger-link {
color: var(--token-color-danger, #ff4949);
}
}
}
// 1.2 卡片——统一无内阴影、body 内边距
.el-card {
border-color: var(--token-color-border-lighter, #ebeef5);
&.is-always-shadow {
box-shadow: var(--token-shadow-card, 0 1px 4px rgba(0, 0, 0, 0.06));
}
}
// 1.3 表格——统一表头背景与居中、行 hover、斑马
.el-table {
th.el-table__cell {
background-color: var(--token-color-fill, #f5f7fa);
color: var(--token-color-text-main, #303133);
font-weight: 600;
}
th.el-table__cell > .cell {
text-align: center;
}
.el-table__body tr.hover-row > td.el-table__cell,
.el-table__body tr:hover > td.el-table__cell {
background-color: var(--token-color-primary-lighter, #f0f9f4);
}
&.el-table--striped .el-table__body tr.el-table__row--striped td.el-table__cell {
background-color: var(--token-color-fill-light, #f0f2f5);
}
}
// 1.4 表单——统一 label 对齐与错误/必填语义
.el-form {
.el-form-item {
.el-form-item__label {
color: var(--token-color-text-regular, #606266);
}
.el-form-item__error {
color: var(--token-color-danger, #ff4949);
}
}
}
// 1.5 分页——统一置于底部右侧
.el-pagination {
color: var(--token-color-text-regular, #606266);
&.pagination-right {
justify-content: flex-end;
}
}
// ------------------------- 2. 页面结构基线 -------------------------
// 说明:这些类名与历史业务页 scoped 中的自定义类名保持同名,
// 统一后应删除页面内的 scoped 重复定义,避免覆盖。
// 2.1 基础页面容器
.page-shell {
padding: var(--token-space-xl, 20px);
box-sizing: border-box;
}
// 2.2 页面标题
.page-title {
font-size: var(--token-font-size-xl, 20px);
font-weight: 600;
color: var(--token-color-text-main, #303133);
margin-bottom: var(--token-space-lg, 16px);
}
// 2.3 区块/卡片容器——统一白底 + 圆角 + 轻阴影 + 内边距
.section-card {
background: #fff;
border-radius: var(--token-radius-xl, 8px);
box-shadow: var(--token-shadow-light, 0 1px 4px rgba(0, 0, 0, 0.08));
padding: var(--token-space-lg, 16px) var(--token-space-xl, 20px);
margin-bottom: var(--token-space-lg, 16px);
&:last-child {
margin-bottom: 0;
}
}
// 兼容:el-card 封装的查询/表格卡
.search-card.el-card,
.table-card.el-card {
border-radius: var(--token-radius-xl, 8px);
}
.search-card,
.table-card {
margin-bottom: var(--token-space-lg, 16px);
}
.search-card {
.search-form {
.el-form-item {
margin-bottom: 0;
}
}
// 底部操作区(右侧对齐)
.search-actions,
.search-footer {
display: flex;
align-items: center;
justify-content: flex-end;
gap: var(--token-space-md, 12px);
}
// 仅明确标记为页脚的操作区才带轻分割线(避免误伤页面自有分割结构)
.search-footer {
margin-top: var(--token-space-md, 12px);
padding-top: var(--token-space-md, 12px);
border-top: 1px solid var(--token-color-border-lighter, #ebeef5);
}
}
.table-card {
.pagination-wrap,
.pagination-wrapper,
.pagination {
display: flex;
justify-content: flex-end;
margin-top: var(--token-space-md, 12px);
}
}
// 2.4 查询控件——统一纵向排列的表单:标签右对齐 + 控件自适应
.query-field {
display: flex;
align-items: center;
margin-bottom: var(--token-space-sm, 8px);
min-height: 32px;
.q-label {
width: 120px;
flex-shrink: 0;
font-size: var(--token-font-size-sm, 13px);
color: var(--token-color-text-main, #303133);
text-align: right;
margin-right: var(--token-space-sm, 8px);
white-space: nowrap;
&.no-check {
margin-left: var(--token-space-2xl, 24px);
}
}
.q-control {
flex: 1;
min-width: 0;
}
}
// 2.5 操作/导出按钮行——统一 flex + 等比间距 + 自动换行
.action-row,
.export-bar {
display: flex;
flex-wrap: wrap;
gap: var(--token-space-md, 12px);
}
.action-row + .action-row {
margin-top: var(--token-space-md, 12px);
}
// 2.6 列表工具栏——左右分组
.list-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--token-space-md, 12px);
flex-wrap: wrap;
margin-bottom: var(--token-space-lg, 16px);
.left-group,
.right-group {
display: flex;
align-items: center;
gap: var(--token-space-md, 12px);
flex-wrap: wrap;
}
}
// 列表标题
.list-title,
.section-title {
font-size: var(--token-font-size-lg, 16px);
font-weight: 600;
color: var(--token-color-text-main, #303133);
margin-bottom: var(--token-space-md, 12px);
}
// 2.7 危险文字(删除/停用等)
.text-danger,
.danger-text,
.danger-link {
color: var(--token-color-danger, #ff4949);
}
// ------------------------- 3. 工具类 -------------------------
// 字体
.text-center { text-align: center; }
.text-left { text-align: left; }
.text-right { text-align: right; }
.text-primary { color: var(--token-color-primary, #00875a); }
.text-regular { color: var(--token-color-text-regular, #606266); }
.text-secondary { color: var(--token-color-text-secondary, #909399); }
.font-sm { font-size: var(--token-font-size-sm, 13px); }
.font-lg { font-size: var(--token-font-size-lg, 16px); }
// 布局
.flex { display: flex; align-items: center; }
.flex-center { display: flex; align-items: center; justify-content: center; }
.flex-between { display: flex; align-items: center; justify-content: space-between; }
.flex-end { display: flex; align-items: center; justify-content: flex-end; }
.flex-wrap { flex-wrap: wrap; }
.flex-1 { flex: 1; min-width: 0; }
.w-full { width: 100%; }
// 间距(上/下)
.mt-0 { margin-top: 0; }
.mt-xs { margin-top: var(--token-space-xs, 4px); }
.mt-sm { margin-top: var(--token-space-sm, 8px); }
.mt-md { margin-top: var(--token-space-md, 12px); }
.mt-lg { margin-top: var(--token-space-lg, 16px); }
.mt-xl { margin-top: var(--token-space-xl, 20px); }
.mb-0 { margin-bottom: 0; }
.mb-xs { margin-bottom: var(--token-space-xs, 4px); }
.mb-sm { margin-bottom: var(--token-space-sm, 8px); }
.mb-md { margin-bottom: var(--token-space-md, 12px); }
.mb-lg { margin-bottom: var(--token-space-lg, 16px); }
.mb-xl { margin-bottom: var(--token-space-xl, 20px); }
// 圆角/阴影
.radius-sm { border-radius: var(--token-radius-sm, 2px); }
.radius-md { border-radius: var(--token-radius-md, 4px); }
.radius-lg { border-radius: var(--token-radius-lg, 6px); }
.radius-xl { border-radius: var(--token-radius-xl, 8px); }
.shadow-light { box-shadow: var(--token-shadow-light, 0 1px 4px rgba(0, 0, 0, 0.08)); }
// 等宽
.mono {
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
}