
文章目录SCSS 常用语法速查1. 变量 $2. 嵌套Nesting3. 模块化use / forward推荐4. Mixin可复用代码块5. 函数 function6. 继承 extend 与占位符 %7. 控制流if / else if / elseforeach遍历列表/Mapwhile8. 插值 #{}9. 运算10. 内置模块sass:*11. Map 操作12. 条件指令补充13. import 旧语法仅了解新项目不建议14. 与 Vite 项目结合如本工程15. 命名 组织建议小结SCSS 进阶实战补充一、BEM SCSS 写法用 mixin 封装 BEM推荐二、深度选择器Vue scoped 场景Vue 3 推荐:deep()其它穿透写法仅了解插槽内容样式 :slotted() / 全局 :global()三、主题切换CSS 变量 SCSS Map1. 定义主题 Map2. 编译生成 CSS 变量3. 业务样式直接用 CSS 变量4. 封装一个取值函数可选5. 运行时切换主题6. 加过渡切换时丝滑四、纯 SCSS Map 换肤无 CSS 变量旧浏览器兼容五、组合实战BEM 主题 响应式选型建议SCSS 常用语法速查SCSS Sass 的 SCSS 语法与 CSS 完全兼容的超集文件后缀.scss。下面整理日常项目里高频使用的语法。1. 变量$$primary-color: #1677ff; $base-font: 14px; $radius: 4px; .btn { color: $primary-color; font-size: $base-font; border-radius: $radius; }作用域在{}内声明的是局部变量用!global可提升为全局。默认值$color: #fff !default;仅当未定义时才赋值常用于主题覆盖。2. 嵌套Nesting.card { padding: 16px; .title { font-weight: bold; } // 表示父选择器 :hover { background: #f5f5f5; } .is-active { border-color: $primary-color; } // 属性嵌套不常用 font: { family: Arial; size: 14px; } }的用法写法等价 CSS:hover.card:hover.active.card.active.dark .dark .card__title.card__titleBEM 常用3. 模块化use/forward推荐Dart Sass 1.23 推荐用use替代旧的import。// _variables.scss $primary: #1677ff; $radius: 4px;// app.scss use ./variables; // 默认带命名空间 use ./variables as v; // 自定义命名空间 use ./variables as *; // 去掉命名空间全局展开 .btn { color: variables.$primary; border-radius: v.$radius; }// index.scss —— 聚合导出 forward ./variables; forward ./mixins;文件名以_开头如_variables.scss表示部分文件不会单独编译。use引入的同一文件只会被处理一次避免重复输出。4. Mixin可复用代码块// 无参 mixin clearfix { ::after { content: ; display: block; clear: both; } } // 带参 默认值 mixin flex($direction: row, $justify: center, $align: center) { display: flex; flex-direction: $direction; justify-content: $justify; align-items: $align; } .container { include clearfix; include flex($justify: space-between); }带内容块content的高级用法mixin respond($breakpoint) { media (max-width: $breakpoint) { content; } } .title { font-size: 24px; include respond(768px) { font-size: 18px; } }5. 函数functionfunction rem($px, $base: 16px) { return ($px / $base) * 1rem; } .title { font-size: rem(24px); // - 1.5rem }与mixin的区别函数返回值mixin 返回样式块。6. 继承extend与占位符%// % 开头的占位符不会单独输出 CSS %btn-base { display: inline-block; padding: 8px 16px; border-radius: 4px; cursor: pointer; } .btn-primary { extend %btn-base; background: $primary; color: #fff; } .btn-default { extend %btn-base; background: #f5f5f5; }实际项目优先用mixinextend在合并选择器时容易产生意外的耦合。7. 控制流if / else if / elsemixin theme($name) { if $name dark { background: #000; color: #fff; } else if $name light { background: #fff; color: #000; } else { background: #f5f5f5; } }for// through 含末尾to 不含 for $i from 1 through 5 { .col-#{$i} { width: $i * 20%; } }each遍历列表/Map$colors: ( primary: #1677ff, success: #52c41a, danger: #ff4d4f, ); each $name, $color in $colors { .text-#{$name} { color: $color; } .bg-#{$name} { background-color: $color; } }while$i: 1; while $i 3 { .item-#{$i} { z-index: $i; } $i: $i 1; }8. 插值#{}用于在选择器、属性名、字符串中拼接变量$prefix: app; $prop: border; .#{$prefix}-card { #{$prop}-color: #ccc; background: url(/img/#{$prefix}-bg.png); }9. 运算.box { width: 100% - 20px; // calc 风格 height: 100px * 2; margin: 10px 5px; color: rgba($primary, 0.5); // 颜色函数 }在 Dart Sass 中除法推荐使用math.div旧/已废弃use sass:math; width: math.div(100%, 3);10. 内置模块sass:*use sass:math; use sass:color; use sass:string; use sass:list; use sass:map; $darker: color.adjust($primary, $lightness: -10%); $mixed: color.mix(#fff, $primary, 50%); $rounded: math.round(3.7); // 4 $upper: string.to-upper-case(abc); // ABC $len: list.length((1, 2, 3)); // 3 $val: map.get($colors, primary);常用颜色函数函数作用lighten($c, 10%)/darken($c, 10%)调亮/调暗rgba($c, 0.5)设透明度mix($c1, $c2, 50%)颜色混合color.adjust($c, $lightness: -10%)通用调整11. Map 操作$z-index: ( modal: 1000, dropdown: 900, header: 800, ); .modal { z-index: map-get($z-index, modal); } // 遍历 each $key, $val in $z-index { .z-#{$key} { z-index: $val; } }12. 条件指令补充debug $primary; // 调试输出到控制台 warn 该 mixin 已废弃; // 编译时警告 error 颜色不能为空; // 编译时报错并终止13.import旧语法仅了解新项目不建议import ./variables; // 已被 use / forward 取代14. 与 Vite 项目结合如本工程vite.config.ts 中css:{preprocessorOptions:{scss:{additionalData:use /styles/color.scss as *;,},},}效果所有.scss文件 /style langscss自动注入颜色变量无需每个文件手动use。Vue SFC 中作用域写法style langscss scoped use /styles/variables.scss as *; .box { color: $primary; } /style15. 命名 组织建议小结styles/ _variables.scss // 变量 _mixins.scss // mixin _functions.scss // 函数 _reset.scss // 全局 reset index.scss // forward 聚合变量、mixin、函数文件用_前缀业务样式按组件就近写style langscss scoped主题色/间距/字号沉淀到统一变量文件便于换肤。SCSS 进阶实战补充一、BEM SCSS 写法BEM 命名规范Block__Element--Modifier// ❌ 啰嗦写法 .card{}.card__header{}.card__header--fixed{}.card__title{}.card__body{}// ✅ SCSS 嵌套 拼接 .card{padding:16px;border:1px solid #eee;__header{font-weight:bold;--fixed{position:sticky;top:0;}}__title{font-size:18px;}__body{padding:12px 0;}// 修饰符 --dark{background:#000;color:#fff;.card__title{color:$primary;}}}编译结果.card{padding:16px;border:1px solid #eee;}.card__header{font-weight:bold;}.card__header--fixed{position:sticky;top:0;}.card__title{font-size:18px;}.card__body{padding:12px 0;}.card--dark{background:#000;color:#fff;}.card--dark .card__title{color:#1677ff;}用 mixin 封装 BEM推荐// _bem.scssmixinb($block){.#{$block}{content;}}mixine($el){__#{$el}{content;}}mixinm($modifier){--#{$modifier}{content;}}使用use./bemas *;includeb(card){padding:16px;includee(header){font-weight:bold;includem(fixed){position:sticky;top:0;}}includem(dark){background:#000;}}二、深度选择器Vue scoped 场景style scoped会给每个选择器加上[data-v-xxx]属性导致无法穿透到子组件 / 第三方组件库。Vue 3 推荐:deep()stylelangscssscoped.wrapper{// ❌ 失效el-input 内部的 .el-input__inner 不会被加>{border-color:red;}// ✅ 穿透 :deep(.el-input__inner){border-color:red;}// ✅ 也可以放在嵌套里 .form-item{:deep(.el-input__inner){height:32px;}}}/style其它穿透写法仅了解stylescoped/* Vue 2 写法Vue 3 也兼容 */.wrapper .el-input__inner{}.wrapper /deep/ .el-input__inner{}/* SCSS 中只能用这个或 :deep *//styleSCSS 里不能用会被预处理器报错用:deep()或/deep/。插槽内容样式:slotted()/ 全局:global()stylelangscssscoped// 给传入插槽的内容加样式 :slotted(.title){color:red;}// 写一段全局样式不加 scoped 属性 :global(.app-toast){z-index:9999;}/style三、主题切换CSS 变量 SCSS Map思路SCSS Map 集中定义主题→编译期生成 CSS 变量→运行时切换html的data-theme即可换肤无需重新加载样式。1. 定义主题 Map// _themes.scss $themes:(light:(bg:#ffffff,text:#1f1f1f,primary:#1677ff,border:#e5e7eb,card-bg:#f9fafb,),dark:(bg:#0f172a,text:#f1f5f9,primary:#38bdf8,border:#1e293b,card-bg:#1e293b,),);2. 编译生成 CSS 变量usesass:map;use./themesas *;// 遍历每个主题输出一份变量each$theme-name,$theme-map in $themes{// 根主题 $selector:if($theme-name light,:root,[data-theme#{$theme-name}]);#{$selector}{each$key,$value in $theme-map{--color-#{$key}: #{$value};}}}编译结果:root{--color-bg:#ffffff;--color-text:#1f1f1f;--color-primary:#1677ff;--color-border:#e5e7eb;--color-card-bg:#f9fafb;}[data-themedark]{--color-bg:#0f172a;--color-text:#f1f5f9;/* ... */}3. 业务样式直接用 CSS 变量.card{background:var(--color-card-bg);color:var(--color-text);border:1px solidvar(--color-border);}.btn-primary{background:var(--color-primary);}4. 封装一个取值函数可选functiontc($key){returnvar(--color-#{$key});}.title{color:tc(primary);// 编译为color:var(--color-primary)background:tc(card-bg);}5. 运行时切换主题// theme.tsexporttypeThemelight|darkexportfunctionsetTheme(theme:Theme){document.documentElement.dataset.themetheme localStorage.setItem(theme,theme)}exportfunctioninitTheme(){constsaved(localStorage.getItem(theme)asTheme)??lightsetTheme(saved)}scriptsetuplangtsimport{setTheme}from/theme/scripttemplatebuttonclicksetTheme(light)浅色/buttonbuttonclicksetTheme(dark)深色/button/template6. 加过渡切换时丝滑*{transition:background-color 0.3s,color 0.3s,border-color 0.3s;}四、纯 SCSS Map 换肤无 CSS 变量旧浏览器兼容如果项目必须支持不支持 CSS 变量的环境可用 mixin 编译期多套样式。usesass:map;$themes:(light:(bg:#fff,text:#000),dark:(bg:#000,text:#fff),);// 当前 $theme-name 由调用方传入mixinthemify{each$name,$map in $themes{[data-theme#{$name}] {$theme-map:$map !global;content;$theme-map:null !global;}}}functiont($key){returnmap.get($theme-map,$key);}.card{includethemify{background:t(bg);color:t(text);}}编译产物会为每个主题各生成一份样式体积会大一点但兼容性最好。五、组合实战BEM 主题 响应式use/styles/themesas *;use/styles/mixinsas *;.product-card{padding:16px;background:var(--color-card-bg);border:1px solidvar(--color-border);border-radius:8px;__title{color:var(--color-text);font-size:18px;includerespond(768px){font-size:16px;}}__price{color:var(--color-primary);font-weight:bold;}--featured{border-color:var(--color-primary);box-shadow:0 4px 12pxrgba(0,0,0,0.1);}}选型建议场景推荐方案现代项目 需要换肤CSS 变量 SCSS Map 生成不需要换肤纯设计规范SCSS 变量足够必须兼容 IE 11 等老环境纯 SCSS Map mixin编译多套组件库二次定制:deep() CSS 变量覆盖