---
description: 样式规范 - BEM 命名、预处理器、响应式设计。涉及 CSS 编写、样式组织、单位转换时触发。
globs: ["**/*.css", "**/*.less", "**/*.scss", "**/*.sass", "**/*.vue"]
alwaysApply: false
---

# 样式规范

该规则定义 CSS/预处理器的编写标准，包括 BEM 命名、变量管理、响应式设计。

> 📋 适用于 Less/Scss/Sass 项目。Tailwind CSS 项目优先使用工具类，可忽略 BEM 部分。

---

## 必须遵守

- ✅ 所有样式基于 `box-sizing: border-box` 盒模型（padding/border 不增加元素总宽度）
- ✅ 组件样式使用 `scoped` 避免全局污染
- ✅ 全局样式仅在 `src/assets/styles/` 定义
- ✅ 使用 BEM 命名：Block `__` Element `--` Modifier
- ✅ 类名使用 kebab-case（如 `.user-card`）
- ✅ 预处理器嵌套不超过 3 层
- ✅ 颜色、字号、间距、断点使用变量统一管理
- ✅ 移动端使用 REM/VW，PC 端使用 Media Query
- ✅ 修改第三方组件样式使用 `:deep()`
- ✅ `line-height: normal` 必须转换为 `line-height: 1.2`

---

## 严格禁止

- ❌ 禁止非 scoped 样式污染全局
- ❌ 禁止内联样式（除动态样式）
- ❌ 禁止 `/deep/` 或 `>>>`（已废弃）
- ❌ 禁止拼音或无意义类名（`.box1`、`.temp`）
- ❌ 禁止嵌套超过 3 层
- ❌ 禁止通配符选择器 `*`（除全局重置）
- ❌ 禁止硬编码颜色值（使用变量）
- ❌ 禁止滥用 `!important`
- ❌ 禁止性能差选择器（`[class*="user-"]`）
- ❌ 禁止 `line-height: normal`（使用 `1.2` 替代）

---

## 最佳实践

- 💡 全局设置 `box-sizing: border-box` 后，设置宽度时 padding/border 不会溢出
- 💡 Block 命名具有特征（`.user-card` 优于 `.card`）
- 💡 Element 扁平化（`.user-card__title` 优于 `.user-card__header__title`）
- 💡 Modifier 语义明确（`--highlighted` 优于 `--new`）
- 💡 固定尺寸（边框等）用 px，弹性尺寸用 rem/vw
- 💡 仅在 hover 等状态下使用 `will-change`
- 💡 Mixins 用于通用模式（文本溢出、居中等）

---

## 代码示例

### BEM 命名

```scss
// Block + Element + Modifier
.user-card {
  box-sizing: border-box;
  padding: $spacing-md;

  &__header {
    display: flex;
    align-items: center;
  }

  &__avatar {
    width: 48px;
    height: 48px;
    border-radius: 50%;
  }

  &--active {
    border: 2px solid $color-primary;
  }

  &__button--primary {
    background: $color-primary;
    color: #fff;
  }
}
```

### 变量定义

```scss
// src/assets/styles/variables.scss
$color-primary: #1890ff;
$color-error: #f5222d;
$color-text: #333;
$color-text-secondary: #666;

$font-size-base: 14px;
$font-size-large: 16px;

$spacing-sm: 8px;
$spacing-md: 16px;
$spacing-lg: 24px;

$border-radius-base: 4px;

$breakpoint-mobile: 768px;
$breakpoint-tablet: 992px;
```

### Scoped + :deep()

```vue
<style scoped lang="scss">
.user-card {
  padding: $spacing-md;

  // 修改第三方组件
  :deep(.van-button) {
    background: $color-primary;
  }
}
</style>
```

### 响应式

```scss
// 移动端 REM
.product-card {
  width: 10rem;
  padding: 0.4rem;
  font-size: 0.373333rem;
  border: 1px solid #ddd; // 边框用 px
}

// PC 端 Media Query
.product-list {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: $spacing-lg;

  @media (max-width: $breakpoint-tablet) {
    grid-template-columns: repeat(3, 1fr);
  }

  @media (max-width: $breakpoint-mobile) {
    grid-template-columns: repeat(2, 1fr);
  }
}
```

### Mixins

```scss
// src/assets/styles/mixins.scss
@mixin text-ellipsis($lines: 1) {
  @if $lines == 1 {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  } @else {
    display: -webkit-box;
    -webkit-line-clamp: $lines;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
}

@mixin center-position {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
```
