# SCSS 使用指南 ## 📚 目录 1. [基础语法](#基础语法) 2. [变量](#变量) 3. [嵌套](#嵌套) 4. [混入(Mixin)](#混入mixin) 5. [函数](#函数) 6. [继承](#继承) 7. [模块化](#模块化) 8. [实际应用示例](#实际应用示例) 9. [最佳实践](#最佳实践) --- ## 基础语法 ### 文件扩展名 - SCSS 文件使用 `.scss` 扩展名 - 在组件中导入:`import './style.scss'` ### 注释 ```scss // 单行注释(不会编译到 CSS) /* 多行注释(会编译到 CSS) */ ``` --- ## 变量 ### 定义变量 ```scss // 颜色变量 $primary-color: #0769fb; $secondary-color: #6c757d; $text-color: #333; $bg-color: #fff; // 尺寸变量 $spacing-sm: 8px; $spacing-md: 16px; $spacing-lg: 24px; $spacing-xl: 32px; // 字体变量 $font-size-base: 16px; $font-size-lg: 20px; $font-size-sm: 14px; // 布局变量 $container-width: 1200px; $sidebar-width: 250px; ``` ### 使用变量 ```scss .button { background-color: $primary-color; padding: $spacing-md; font-size: $font-size-base; color: $text-color; } ``` ### 变量作用域 ```scss $global-color: #000; // 全局变量 .container { $local-color: #fff; // 局部变量,只在 .container 内可用 color: $local-color; border-color: $global-color; } ``` ### 默认值 ```scss // 如果变量未定义,使用默认值 $primary-color: #0769fb !default; .button { background-color: $primary-color; // 如果未定义,使用 #0769fb } ``` --- ## 嵌套 ### 基本嵌套 ```scss // 传统 CSS .container { width: 100%; } .container .title { font-size: 20px; } .container .title:hover { color: red; } // SCSS 嵌套 .container { width: 100%; .title { font-size: 20px; &:hover { color: red; } } } ``` ### & 符号(父选择器引用) ```scss .button { background: blue; // &:hover 编译为 .button:hover &:hover { background: darkblue; } // &.active 编译为 .button.active &.active { background: green; } // &::before 编译为 .button::before &::before { content: ''; } // 嵌套中的 & 引用 .icon { // .button .icon 中的 & 仍然是 .button &:hover { // 编译为 .button .icon:hover } } } ``` ### 属性嵌套 ```scss // 传统写法 .box { border-width: 1px; border-style: solid; border-color: #ddd; } // SCSS 属性嵌套 .box { border: { width: 1px; style: solid; color: #ddd; } // 也可以嵌套伪类 font: { family: Arial; size: 16px; weight: bold; } } ``` ### 媒体查询嵌套 ```scss .container { width: 100%; @media (max-width: 768px) { width: 100%; padding: 10px; .title { font-size: 18px; } } @media (min-width: 1200px) { max-width: 1200px; margin: 0 auto; } } ``` --- ## 混入(Mixin) ### 基础混入 ```scss // 定义混入 @mixin flex-center { display: flex; align-items: center; justify-content: center; } // 使用混入 .container { @include flex-center; height: 100vh; } ``` ### 带参数的混入 ```scss // 定义带参数的混入 @mixin button($bg-color, $text-color: white) { background-color: $bg-color; color: $text-color; padding: 12px 24px; border-radius: 4px; cursor: pointer; transition: all 0.3s; &:hover { background-color: darken($bg-color, 10%); } } // 使用 .btn-primary { @include button(#0769fb); } .btn-danger { @include button(#dc3545); } .btn-custom { @include button(#28a745, #fff); } ``` ### 带默认参数的混入 ```scss @mixin card($padding: 16px, $shadow: true) { padding: $padding; border-radius: 8px; @if $shadow { box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } } .card { @include card; // 使用默认值 } .card-large { @include card(24px, false); // 自定义参数 } ``` ### 内容块混入 ```scss @mixin responsive($breakpoint) { @media (max-width: $breakpoint) { @content; // 插入传入的内容 } } .container { width: 100%; @include responsive(768px) { width: 100%; padding: 10px; } } ``` --- ## 函数 ### 内置函数 #### 颜色函数 ```scss $primary: #0769fb; .button { // 变亮/变暗 background: lighten($primary, 20%); border-color: darken($primary, 10%); // 调整饱和度 background: saturate($primary, 20%); background: desaturate($primary, 20%); // 调整透明度 background: rgba($primary, 0.8); background: fade-in($primary, 0.2); background: fade-out($primary, 0.2); // 混合颜色 background: mix($primary, white, 50%); // 调整色调 background: adjust-hue($primary, 30deg); // 互补色 border-color: complement($primary); } ``` #### 字符串函数 ```scss $font-family: 'Arial'; .text { // 转大写 text-transform: to-upper-case($font-family); // 转小写 text-transform: to-lower-case($font-family); // 引用字符串 content: quote('Hello'); // 取消引用 font-family: unquote('Arial'); } ``` #### 数学函数 ```scss .container { // 百分比 width: percentage(2/3); // 66.666667% // 四舍五入 font-size: round(18.7px); // 19px // 向上取整 padding: ceil(18.2px); // 19px // 向下取整 margin: floor(18.9px); // 18px // 绝对值 left: abs(-10px); // 10px // 最小值/最大值 width: min(100px, 200px); // 100px height: max(50px, 100px); // 100px } ``` ### 自定义函数 ```scss // 计算 rem @function calculate-rem($pixels) { @return $pixels / 16px * 1rem; } .title { font-size: calculate-rem(24px); // 1.5rem } // 间距函数 @function spacing($multiplier) { @return $multiplier * 8px; } .container { padding: spacing(2); // 16px margin: spacing(3); // 24px } // 颜色对比度函数 @function get-text-color($bg-color) { @if lightness($bg-color) > 50% { @return #000; // 浅色背景用黑色文字 } @else { @return #fff; // 深色背景用白色文字 } } .button { background: $primary-color; color: get-text-color($primary-color); } ``` --- ## 继承 ### 基础继承 ```scss // 定义占位符选择器(%) %button-base { padding: 12px 24px; border-radius: 4px; cursor: pointer; transition: all 0.3s; border: none; } // 继承 .btn-primary { @extend %button-base; background-color: #0769fb; color: white; } .btn-secondary { @extend %button-base; background-color: #6c757d; color: white; } ``` ### 继承 vs 混入 ```scss // 混入:会复制代码到每个类中 @mixin button-mixin { padding: 12px; } .btn1 { @include button-mixin; } .btn2 { @include button-mixin; } // 编译后:两个类都有 padding: 12px // 继承:会合并选择器 %button-extend { padding: 12px; } .btn1 { @extend %button-extend; } .btn2 { @extend %button-extend; } // 编译后:.btn1, .btn2 { padding: 12px; } ``` --- ## 模块化 ### @import(旧方式,已废弃) ```scss @import 'variables'; @import 'mixins'; ``` ### @use(推荐方式) ```scss // _variables.scss $primary-color: #0769fb; $spacing: 16px; // _mixins.scss @mixin flex-center { display: flex; align-items: center; justify-content: center; } // main.scss @use 'variables' as vars; @use 'mixins' as mix; .container { color: vars.$primary-color; padding: vars.$spacing; @include mix.flex-center; } // 或者不使用命名空间 @use 'variables'; @use 'mixins'; .container { color: variables.$primary-color; @include mixins.flex-center; } ``` ### @forward(转发模块) ```scss // _all.scss @forward 'variables'; @forward 'mixins'; // main.scss @use 'all'; .container { color: all.$primary-color; @include all.flex-center; } ``` --- ## 实际应用示例 ### 1. 按钮组件系统 ```scss // _variables.scss $button-colors: ( 'primary': #0769fb, 'success': #28a745, 'danger': #dc3545, 'warning': #ffc107 ); $button-padding: 12px 24px; $button-radius: 4px; // _mixins.scss @mixin button-base { padding: $button-padding; border-radius: $button-radius; border: none; cursor: pointer; font-size: 16px; transition: all 0.3s; &:hover { transform: translateY(-2px); } &:active { transform: translateY(0); } } @mixin button-variant($color-name) { $color: map-get($button-colors, $color-name); background-color: $color; color: white; &:hover { background-color: darken($color, 10%); } &:active { background-color: darken($color, 15%); } } // buttons.scss @use 'variables' as vars; @use 'mixins' as mix; .button { @include mix.button-base; @each $name, $color in vars.$button-colors { &.#{$name} { @include mix.button-variant($name); } } } ``` ### 2. 响应式网格系统 ```scss // _variables.scss $breakpoints: ( 'sm': 576px, 'md': 768px, 'lg': 992px, 'xl': 1200px ); $grid-columns: 12; // _mixins.scss @mixin respond-to($breakpoint) { $value: map-get($breakpoints, $breakpoint); @if $value { @media (min-width: $value) { @content; } } } @mixin grid-column($columns) { width: percentage($columns / $grid-columns); @include respond-to('md') { width: percentage($columns / $grid-columns); } } // grid.scss @use 'variables' as vars; @use 'mixins' as mix; .container { display: flex; flex-wrap: wrap; @include respond-to('md') { display: grid; grid-template-columns: repeat(12, 1fr); gap: 16px; } } @for $i from 1 through vars.$grid-columns { .col-#{$i} { @include mix.grid-column($i); } } ``` ### 3. 主题切换系统 ```scss // _themes.scss $themes: ( 'light': ( 'bg': #fff, 'text': #333, 'primary': #0769fb ), 'dark': ( 'bg': #1a1a1a, 'text': #fff, 'primary': #4a9eff ) ); @function theme($theme-name, $key) { $theme: map-get($themes, $theme-name); @return map-get($theme, $key); } // main.scss @use 'themes' as t; body { background-color: t.theme('light', 'bg'); color: t.theme('light', 'text'); &.dark-theme { background-color: t.theme('dark', 'bg'); color: t.theme('dark', 'text'); } } .button { background-color: t.theme('light', 'primary'); .dark-theme & { background-color: t.theme('dark', 'primary'); } } ``` ### 4. 动画系统 ```scss // _animations.scss @mixin fade-in($duration: 0.3s) { animation: fadeIn $duration ease-in-out; @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } } @mixin slide-in($direction: left, $distance: 100px, $duration: 0.3s) { $transform: null; @if $direction == 'left' { $transform: translateX(-$distance); } @else if $direction == 'right' { $transform: translateX($distance); } @else if $direction == 'up' { $transform: translateY(-$distance); } @else { $transform: translateY($distance); } animation: slideIn $duration ease-out; @keyframes slideIn { from { transform: $transform; opacity: 0; } to { transform: translate(0, 0); opacity: 1; } } } // 使用 .modal { @include fade-in(0.5s); } .sidebar { @include slide-in('left', 200px, 0.4s); } ``` --- ## 最佳实践 ### 1. 文件组织 ``` styles/ ├── _variables.scss # 变量 ├── _mixins.scss # 混入 ├── _functions.scss # 函数 ├── _base.scss # 基础样式 ├── _components.scss # 组件样式 └── main.scss # 主文件 ``` ### 2. 命名规范 ```scss // 变量:使用 kebab-case $primary-color: #0769fb; $spacing-base: 8px; // 混入:使用 kebab-case @mixin flex-center { } @mixin button-variant { } // 函数:使用 kebab-case @function calculate-rem { } ``` ### 3. 避免过度嵌套 ```scss // ❌ 不好:嵌套太深 .container { .wrapper { .content { .title { .text { color: red; } } } } } // ✅ 好:保持 3-4 层以内 .container { .content { .title { color: red; } } } ``` ### 4. 使用变量统一管理 ```scss // ✅ 好:使用变量 $primary: #0769fb; .button { background: $primary; } // ❌ 不好:硬编码 .button { background: #0769fb; } ``` ### 5. 合理使用混入和继承 ```scss // 混入:用于需要参数的样式 @mixin button($color) { background: $color; } // 继承:用于不需要参数的通用样式 %reset-list { margin: 0; padding: 0; list-style: none; } ``` ### 6. 使用 @use 替代 @import ```scss // ✅ 推荐 @use 'variables'; // ❌ 已废弃 @import 'variables'; ``` --- ## 常用代码片段 ### 清除浮动 ```scss @mixin clearfix { &::after { content: ''; display: table; clear: both; } } ``` ### 文本省略 ```scss @mixin text-ellipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } @mixin text-ellipsis-multi($lines: 2) { display: -webkit-box; -webkit-line-clamp: $lines; -webkit-box-orient: vertical; overflow: hidden; } ``` ### 居中布局 ```scss @mixin flex-center { display: flex; align-items: center; justify-content: center; } @mixin absolute-center { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } ``` ### 响应式断点 ```scss $breakpoints: ( 'sm': 576px, 'md': 768px, 'lg': 992px, 'xl': 1200px ); @mixin respond-to($breakpoint) { $value: map-get($breakpoints, $breakpoint); @if $value { @media (min-width: $value) { @content; } } } ``` --- ## 调试技巧 ### 1. 使用 @debug ```scss $width: 100px; @debug "Width is: #{$width}"; ``` ### 2. 使用 @warn ```scss @function calculate-rem($pixels) { @if unit($pixels) != 'px' { @warn "Expected pixels, got #{unit($pixels)}"; } @return $pixels / 16px * 1rem; } ``` ### 3. 检查变量值 ```scss @mixin debug-variable($var) { &::before { content: '#{$var}'; } } ``` --- ## 总结 SCSS 的核心优势: 1. ✅ **变量** - 统一管理值 2. ✅ **嵌套** - 代码更清晰 3. ✅ **混入** - 复用样式块 4. ✅ **函数** - 计算和转换 5. ✅ **继承** - 减少重复代码 6. ✅ **模块化** - 代码组织更清晰 记住:**功能强大,但要适度使用,保持代码简洁易读!**