我将设计一个支持深浅主题的 SCSS 结构,采用模块化、可扩展的方式,通过变量、混合宏和控制指令实现主题切换。设计将包括全局配置、主题定义、组件样式和响应式支持,确保代码清晰、易于维护,并支持动态主题切换。
// 1. 全局变量 - 基础配置
$breakpoints: (
mobile: 768px,
tablet: 1024px,
desktop: 1200px,
);
$spacing: (
small: 8px,
medium: 16px,
large: 24px,
);
// 2. 主题配置 - 深浅主题颜色
$themes: (
light: (
background: #ffffff,
text: #333333,
primary: #007bff,
secondary: #6c757d,
accent: #28a745,
border: #dee2e6,
),
dark: (
background: #1a1a1a,
text: #ffffff,
primary: #66b0ff,
secondary: #adb5bd,
accent: #51cf66,
border: #495057,
),
);
// 3. 混合宏 - 主题样式和响应式
@mixin apply-theme($theme-name) {
@if map-has-key($themes, $theme-name) {
$theme: map-get($themes, $theme-name);
background: map-get($theme, background);
color: map-get($theme, text);
--primary: #{map-get($theme, primary)};
--secondary: #{map-get($theme, secondary)};
--accent: #{map-get($theme, accent)};
--border: #{map-get($theme, border)};
} @else {
@error "Invalid theme: #{$theme-name}. Available: #{map-keys($themes)}";
}
}
@mixin respond-to($breakpoint) {
@if map-has-key($breakpoints, $breakpoint) {
@media (max-width: map-get($breakpoints, $breakpoint)) {
@content;
}
} @else {
@error "Invalid breakpoint: #{$breakpoint}. Available: #{map-keys($breakpoints)}";
}
}
@mixin flex-center {
display: flex;
justify-content: center;
align-items: center;
}
// 4. 全局样式 - 重置和基础设置
:root {
font-family: Arial, sans-serif;
font-size: 16px;
transition: background 0.3s, color 0.3s;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
// 5. 主题应用 - 深浅主题切换
.theme-light {
@include apply-theme(light);
}
.theme-dark {
@include apply-theme(dark);
}
// 6. 组件样式 - 主题化组件
.header {
padding: map-get($spacing, medium);
border-bottom: 1px solid var(--border);
&__logo {
font-size: 1.5rem;
color: var(--primary);
}
&__nav {
@include flex-center;
gap: map-get($spacing, medium);
a {
color: var(--text);
text-decoration: none;
&:hover {
color: var(--accent);
}
}
}
@include respond-to(mobile) {
padding: map-get($spacing, small);
flex-direction: column;
&__nav {
flex-direction: column;
gap: map-get($spacing, small);
}
}
}
.card {
padding: map-get($spacing, medium);
margin: map-get($spacing, medium);
background: var(--background);
border: 1px solid var(--border);
border-radius: 8px;
&__title {
font-size: 1.25rem;
color: var(--primary);
}
&__content {
color: var(--text);
margin-top: map-get($spacing, small);
}
&__button {
padding: map-get($spacing, small) map-get($spacing, medium);
background: var(--accent);
color: var(--text);
border: none;
border-radius: 4px;
cursor: pointer;
&:hover {
background: darken(var(--accent), 10%);
}
}
@include respond-to(mobile) {
margin: map-get($spacing, small);
padding: map-get($spacing, small);
}
}
// 7. 工具类 - 通用样式
.text-center {
text-align: center;
}
.margin-bottom {
margin-bottom: map-get($spacing, medium);
@include respond-to(mobile) {
margin-bottom: map-get($spacing, small);
}
}
// 8. 动画效果 - 主题切换过渡
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.fade-in {
animation: fadeIn 0.5s ease-in;
}
设计特点和使用说明
1. 主题配置
- 方法:使用 map 存储深浅主题的颜色配置(
$themes
),通过map-get
获取具体值。 - 优势:集中管理颜色,易于扩展新主题(如高对比度主题)。
- 使用场景:通过 CSS 自定义属性(
--variable
)和apply-theme
混合宏动态应用主题,结合 JavaScript 切换类(如.theme-light
或.theme-dark
)实现主题切换。
2. CSS 自定义属性
- 方法:将主题颜色定义为 CSS 自定义属性(
--primary
等),在组件中直接引用。 - 优势:支持动态主题切换,减少 SCSS 编译时的重复代码;便于 JavaScript 操作(如动态调整颜色)。
- 使用场景:在需要动态修改样式的场景(如用户自定义主题)中使用。
3. 模块化结构
- 方法:按功能组织代码(全局变量、主题配置、组件样式、工具类)。
- 优势:提高可维护性,方便添加新组件或主题。
- 使用场景:大型项目中,可将组件样式拆分为单独文件,使用
@use
引入。
4. 响应式支持
- 方法:通过
@mixin respond-to
和$breakpoints
管理媒体查询。 - 优势:统一断点管理,简化响应式样式编写。
- 使用场景:适配 PC 和移动端,确保深浅主题在不同设备上表现一致。
5. 错误处理
- 方法:使用
@error
检查无效主题或断点。 - 优势:提高代码健壮性,方便调试。
- 使用场景:开发阶段捕获配置错误,避免运行时问题。
6. 动画效果
- 方法:为主题切换添加过渡效果(如
transition
)和动画(如fadeIn
)。 - 优势:提升用户体验,平滑切换主题。
- 使用场景:页面加载或主题切换时的视觉效果。
使用方法
1. HTML 结构
<body class="theme-light">
<header class="header">
<div class="header__logo">Logo</div>
<nav class="header__nav">
<a href="#">Home</a>
<a href="#">About</a>
</nav>
</header>
<div class="card">
<h2 class="card__title">Card Title</h2>
<p class="card__content">Card content here.</p>
<button class="card__button">Click Me</button>
</div>
</body>
2. 主题切换
- 使用 JavaScript 切换
body
的类:
document.body.classList.toggle("theme-dark"); // 切换到深色主题
document.body.classList.toggle("theme-light"); // 切换到浅色主题
3. 扩展主题
- 在
$themes
中添加新主题(如high-contrast
),只需扩展 map:
$themes: (
light: (
...,
),
dark: (
...,
),
high-contrast: (
background: #000000,
text: #ffffff,
primary: #ffff00,
...,
),
);
.theme-high-contrast {
@include apply-theme(high-contrast);
}
优势总结
- 灵活性:通过 map 和 CSS 自定义属性支持动态主题切换。
- 可维护性:模块化结构和集中配置便于修改和扩展。
- 响应式:结合媒体查询确保深浅主题在不同设备上表现良好。
- 用户体验:过渡动画和错误处理提升开发和使用体验。
这个设计适合需要深浅主题切换的现代 Web 应用,可轻松扩展到更多主题或复杂组件,同时保持代码整洁和高效。