分类
标签
API设计 BEM Core Web Vitals CSRF CSS CSS-in-JS CSS变量 Flexbox Grid HTTP HTTP-2 HTTP-3 HTTPS JavaScript Less RESTful Sass SSL-TLS Stylus WebSocket Web安全 Web性能 XSS 主题切换 全双工通信 前端 前端优化 前端安全 前端工程化 前端开发 前端架构 动画 后端开发 响应式设计 团队协作 媒体查询 子网格 实时通信 容器查询 层叠层 布局 性能优化 接口规范 架构设计 模块化 渲染性能 现代CSS 用户体验 移动优先 组件库 缓存策略 网络 网络协议 网络安全 网络请求 自定义属性 认证授权 设计令牌 设计系统 过渡 预处理器 颜色函数
1915 字
10 分钟
CSS 模块化与架构设计
CSS 模块化与架构设计
概述
随着前端项目规模的扩大,CSS 的模块化和架构设计变得至关重要,它直接影响代码的可维护性、可扩展性和团队协作效率。
模块化方法论
1. BEM 命名规范
/* Block - 块 */
.block {
/* 块样式 */
}
/* Element - 元素 */
.block__element {
/* 元素样式 */
}
/* Modifier - 修饰符 */
.block--modifier {
/* 修饰符样式 */
}
.block__element--modifier {
/* 带修饰符的元素 */
}
/* 实际示例 */
.button {
display: inline-block;
padding: 10px 20px;
border: 1px solid #ddd;
border-radius: 4px;
}
.button__icon {
margin-right: 8px;
}
.button--primary {
background-color: #007bff;
color: white;
border-color: #007bff;
}
.button--large {
padding: 15px 30px;
font-size: 18px;
}
2. SMACSS 架构
/* 1. Base - 基础样式 */
html, body {
margin: 0;
padding: 0;
font-family: sans-serif;
}
a {
color: #007bff;
text-decoration: none;
}
/* 2. Layout - 布局样式 */
.l-header {
height: 60px;
background: #333;
color: white;
}
.l-main {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.l-sidebar {
width: 250px;
float: left;
}
/* 3. Module - 模块样式 */
.card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
}
.card__title {
font-size: 20px;
margin-bottom: 10px;
}
.card__body {
color: #666;
line-height: 1.6;
}
/* 4. State - 状态样式 */
.is-active {
background-color: #f8f9fa;
}
.is-hidden {
display: none;
}
.is-loading {
opacity: 0.5;
pointer-events: none;
}
/* 5. Theme - 主题样式 */
.t-dark .card {
background-color: #333;
color: white;
border-color: #444;
}
3. OOCSS 面向对象CSS
/* 1. 分离结构与皮肤 */
/* 结构类 */
.media {
display: flex;
align-items: flex-start;
}
.media__body {
flex: 1;
}
/* 皮肤类 */
.media--bordered {
border: 1px solid #ddd;
padding: 15px;
border-radius: 8px;
}
.media--shadow {
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
/* 2. 分离容器与内容 */
/* 容器无关的样式 */
.btn {
display: inline-block;
padding: 10px 20px;
border-radius: 4px;
font-weight: 600;
text-align: center;
cursor: pointer;
transition: all 0.3s ease;
}
/* 具体样式 */
.btn-primary {
background-color: #007bff;
color: white;
border: 1px solid #007bff;
}
.btn-secondary {
background-color: #6c757d;
color: white;
border: 1px solid #6c757d;
}
/* 使用组合 */
<button class="btn btn-primary">主要按钮</button>
<button class="btn btn-secondary">次要按钮</button>
现代CSS架构
1. ITCSS 倒三角架构
/* 1. Settings - 设置层 */
/* 变量、配置、开关 */
:root {
--color-primary: #007bff;
--spacing-unit: 8px;
--font-size-base: 16px;
}
/* 2. Tools - 工具层 */
/* 函数、混入、工具类 */
@mixin respond-to($breakpoint) {
@media (min-width: $breakpoint) {
@content;
}
}
/* 3. Generic - 通用层 */
/* 重置、规范化、盒子模型 */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
/* 4. Elements - 元素层 */
/* 原生HTML元素样式 */
h1, h2, h3 {
margin-bottom: 1rem;
line-height: 1.2;
}
a {
color: var(--color-primary);
text-decoration: none;
}
/* 5. Objects - 对象层 */
/* 布局类、容器、网格系统 */
.o-container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
.o-grid {
display: grid;
gap: 20px;
}
/* 6. Components - 组件层 */
/* 具体UI组件 */
.c-button {
display: inline-block;
padding: 10px 20px;
background: var(--color-primary);
color: white;
border-radius: 4px;
}
.c-card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
}
/* 7. Utilities - 工具类层 */
/* 辅助类、覆盖样式 */
.u-text-center { text-align: center; }
.u-mt-1 { margin-top: var(--spacing-unit); }
.u-mt-2 { margin-top: calc(var(--spacing-unit) * 2); }
.u-hidden { display: none; }
2. Atomic CSS 原子化CSS
/* 原子类示例 */
/* 间距 */
.m-0 { margin: 0; }
.m-1 { margin: 4px; }
.m-2 { margin: 8px; }
.mt-1 { margin-top: 4px; }
.mb-2 { margin-bottom: 8px; }
/* 颜色 */
.text-primary { color: #007bff; }
.bg-white { background-color: white; }
/* 布局 */
.d-flex { display: flex; }
.flex-col { flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
/* 尺寸 */
.w-full { width: 100%; }
.h-auto { height: auto; }
/* 使用示例 */
<div class="d-flex items-center justify-between p-4 bg-white">
<h1 class="text-primary m-0">标题</h1>
<button class="btn btn-primary">按钮</button>
</div>
3. Utility-First CSS 工具优先CSS
/* 工具优先框架(类似 Tailwind CSS) */
/* 配置层 */
:root {
--spacing-1: 0.25rem; /* 4px */
--spacing-2: 0.5rem; /* 8px */
--spacing-3: 0.75rem; /* 12px */
--spacing-4: 1rem; /* 16px */
--spacing-5: 1.25rem; /* 20px */
}
/* 工具类生成 */
.m-1 { margin: var(--spacing-1); }
.m-2 { margin: var(--spacing-2); }
.p-3 { padding: var(--spacing-3); }
.p-4 { padding: var(--spacing-4); }
/* 响应式工具类 */
@media (min-width: 640px) {
.sm\:m-2 { margin: var(--spacing-2); }
.sm\:p-4 { padding: var(--spacing-4); }
}
@media (min-width: 768px) {
.md\:m-3 { margin: var(--spacing-3); }
.md\:p-5 { padding: var(--spacing-5); }
}
组件化CSS架构
1. 组件隔离
/* 使用 CSS Modules */
/* Button.module.css */
.button {
display: inline-block;
padding: 10px 20px;
border: 1px solid #ddd;
border-radius: 4px;
background: white;
color: #333;
cursor: pointer;
transition: all 0.3s ease;
}
.button:hover {
border-color: #007bff;
color: #007bff;
}
.buttonPrimary {
composes: button;
background: #007bff;
color: white;
border-color: #007bff;
}
.buttonPrimary:hover {
background: #0056b3;
border-color: #0056b3;
}
/* 使用 */
import styles from './Button.module.css';
function Button({ primary, children }) {
const className = primary ? styles.buttonPrimary : styles.button;
return <button className={className}>{children}</button>;
}
2. 设计令牌系统
/* 设计令牌定义 */
:root {
/* 颜色令牌 */
--color-primary: #007bff;
--color-secondary: #6c757d;
--color-success: #28a745;
--color-danger: #dc3545;
/* 间距令牌 */
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 32px;
/* 字体令牌 */
--font-size-xs: 12px;
--font-size-sm: 14px;
--font-size-md: 16px;
--font-size-lg: 18px;
--font-size-xl: 20px;
/* 边框令牌 */
--border-radius-sm: 4px;
--border-radius-md: 8px;
--border-radius-lg: 12px;
--border-width: 1px;
}
/* 组件使用令牌 */
.button {
background-color: var(--color-primary);
color: white;
padding: var(--spacing-sm) var(--spacing-md);
border-radius: var(--border-radius-md);
font-size: var(--font-size-md);
border: var(--border-width) solid transparent;
}
.card {
padding: var(--spacing-lg);
border-radius: var(--border-radius-lg);
border: var(--border-width) solid #dee2e6;
}
3. CSS-in-JS 架构
/* styled-components 示例 */
import styled from 'styled-components';
// 基础按钮组件
const BaseButton = styled.button`
display: inline-block;
padding: 10px 20px;
border: 1px solid #ddd;
border-radius: 4px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
font-family: inherit;
font-size: 16px;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
&:active {
transform: translateY(0);
}
`;
// 变体按钮
const PrimaryButton = styled(BaseButton)`
background-color: ${props => props.theme.colors.primary};
color: white;
border-color: ${props => props.theme.colors.primary};
&:hover {
background-color: ${props => props.theme.colors.primaryDark};
border-color: ${props => props.theme.colors.primaryDark};
}
`;
// 主题定义
const theme = {
colors: {
primary: '#007bff',
primaryDark: '#0056b3',
secondary: '#6c757d',
},
spacing: {
xs: '4px',
sm: '8px',
md: '16px',
lg: '24px',
},
};
// 使用
<ThemeProvider theme={theme}>
<PrimaryButton>主要按钮</PrimaryButton>
</ThemeProvider>
工程化实践
1. 目录结构
src/
├── styles/
│ ├── base/ # 基础样式
│ │ ├── reset.css
│ │ ├── typography.css
│ │ └── variables.css
│ ├── components/ # 组件样式
│ │ ├── Button/
│ │ │ ├── Button.css
│ │ │ ├── Button.module.css
│ │ │ └── index.js
│ │ └── Card/
│ ├── layouts/ # 布局样式
│ │ ├── Header.css
│ │ └── Footer.css
│ ├── utilities/ # 工具类
│ │ ├── spacing.css
│ │ └── display.css
│ └── main.css # 入口文件
├── components/ # React/Vue组件
└── pages/ # 页面组件
2. 构建工具配置
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]__[local]--[hash:base64:5]',
},
},
},
'postcss-loader',
],
},
],
},
};
// postcss.config.js
module.exports = {
plugins: [
require('autoprefixer'),
require('postcss-preset-env'),
require('cssnano')({
preset: 'default',
}),
],
};
3. 代码规范
/* .stylelintrc.json */
{
"extends": [
"stylelint-config-standard",
"stylelint-config-prettier"
],
"rules": {
"selector-class-pattern": "^[a-z][a-zA-Z0-9]+$",
"max-nesting-depth": 3,
"no-descending-specificity": null,
"selector-max-id": 0,
"selector-max-universal": 0
}
}
/* 命名约定 */
/* BEM 格式 */
.block-name__element-name--modifier-name {
/* 样式 */
}
/* 工具类格式 */
.u-text-center {
text-align: center;
}
/* 组件类格式 */
.c-button {
/* 组件样式 */
}
性能优化
1. 代码分割
/* 按需加载 CSS */
// 动态导入 CSS 模块
import('./Button.module.css').then(styles => {
// 使用样式
});
// 使用 loadable-components
import loadable from '@loadable/component';
const Button = loadable(() => import('./Button'));
2. 关键CSS提取
/* 提取首屏关键CSS */
/* critical.css - 首屏必要样式 */
.header, .hero, .navigation {
/* 关键样式 */
}
/* non-critical.css - 非关键样式 */
.footer, .sidebar, .ads {
/* 延迟加载 */
}
3. 缓存策略
/* 使用版本控制 */
<link rel="stylesheet" href="/styles/main.css?v=1.2.3">
/* 内容哈希 */
<link rel="stylesheet" href="/styles/main.a1b2c3d4.css">
团队协作
1. 设计系统文档
/* 设计系统示例 */
:root {
/* 颜色系统 */
--color-primary: #007bff;
--color-primary-hover: #0056b3;
--color-primary-active: #004085;
/* 使用说明 */
/*
使用方式:
1. 文本颜色:color: var(--color-primary);
2. 背景颜色:background-color: var(--color-primary);
3. 边框颜色:border-color: var(--color-primary);
*/
}
2. 代码审查清单
## CSS 代码审查清单
### 架构与组织
- [ ] 是否符合项目架构规范?
- [ ] 是否有适当的注释和文档?
- [ ] 是否遵循命名约定?
### 性能与优化
- [ ] 是否有不必要的嵌套?
- [ ] 是否使用了合适的单位?
- [ ] 是否有重复的样式?
### 可维护性
- [ ] 样式是否足够模块化?
- [ ] 是否有硬编码的值?
- [ ] 是否考虑了响应式设计?
总结
CSS 模块化和架构设计是现代前端工程的核心组成部分。成功的 CSS 架构应该:
- 可维护:代码清晰、结构合理、易于修改
- 可扩展:支持项目增长和功能添加
- 可复用:组件化设计,减少重复代码
- 高性能:优化加载和渲染性能
- 团队友好:统一的规范和协作流程
随着前端技术的不断发展,CSS 架构也在不断演进。建议团队根据项目需求选择合适的架构模式,并建立持续改进的机制。
创建时间:2022-06-08 最后更新:2022-06-08 作者:前端开发团队 标签:CSS, 模块化, 架构设计, BEM, CSS-in-JS, 前端工程化
