Sass 进阶:当 CSS 学会了编程,变量函数循环全都安排上

昨天我们用Sass告别了手工作坊,学会了变量和嵌套。今天咱们继续深入,看看Sass还有哪些骚操作------模块化、内置函数、条件循环,让你的CSS代码像程序一样聪明。准备好,我们要从"会用"进化到"玩出花"了。

前言

还记得你第一次写CSS时的样子吗?一个属性一个属性地敲,一个颜色一个颜色地复制,改个主题色就像在玩"大家来找茬"。昨天学了Sass基础,你已经能像模像样地用变量和嵌套了,感觉自己有点东西了是吧?

但Sass的真正威力远不止于此。今天我们要学的这些东西,会让你忍不住喊出:"卧槽,CSS还能这样写?"------模块化让你的代码像乐高一样拼装,内置函数让颜色和数字自动计算,循环让你批量生成样式就像打印传单。准备好了吗?上车!

一、模块化:别再写一个几千行的巨型文件了

你有没有见过那种一个文件几千行的CSS?看到就想吐对吧?维护起来更是噩梦。Sass的模块化功能就是来拯救你的。

1. @use:新一代的模块引入

以前Sass用@import,但@import有个问题:它会把你引入的所有东西都混到一个全局作用域里,变量重名就覆盖,混乱不堪。现在推荐用@use,它创建了命名空间,隔离了变量。

scss 复制代码
// _variables.scss
$primary-color: #8A2BE2;
$font-stack: 'Helvetica', sans-serif;

// _buttons.scss
@use 'variables';
.button {
  background: variables.$primary-color;  // 通过命名空间访问
  font-family: variables.$font-stack;
}

看到没,通过variables.前缀访问,清清楚楚,妈妈再也不用担心我变量重名了。

2. 下划线开头的"部分文件"

你发现上面文件名是_variables.scss,有个下划线。这是Sass的约定:下划线开头的文件是"部分文件",不会被单独编译成CSS,只用来被别的文件引入。就像厨房里的半成品食材,不直接上桌,但做菜要用。

3. @forward:合并转发

如果你有一堆工具函数,想打包成一个入口文件让别人用,就用@forward

scss 复制代码
// _mixins.scss
@mixin flex-center { ... }

// _variables.scss
$primary: #8A2BE2;

// _index.scss
@forward 'variables';
@forward 'mixins';

// main.scss
@use 'index' as *;  // 直接使用所有转发的成员,无需命名空间

这样别人只要引入index,就能用你所有的变量和混入,方便又优雅。

二、内置函数:Sass自带的神兵利器

Sass内置了很多函数,让你能操作颜色、数字、字符串,就像JavaScript一样。这些函数能帮你省掉无数计算和手工调整。

1. 颜色函数:调色盘在手

颜色是CSS里最烦人的东西之一。你要一个颜色变暗10%?用darken()。变亮?用lighten()。混合两个颜色?用mix()

scss 复制代码
$primary: #8A2BE2;

.btn {
  background: $primary;
  
  &:hover {
    background: darken($primary, 10%);  // 变暗10%
  }
  
  &.disabled {
    background: lighten($primary, 20%);  // 变亮20%
  }
}

.card {
  border: 1px solid rgba($primary, 0.3);  // 转成半透明
}

还有adjust-hue()调整色相,saturate()增加饱和度,desaturate()降低饱和度......总之,调色不再靠肉眼,全交给Sass计算。

2. 数字函数:算清楚

percentage(0.3) 转成30%,round(3.14) 取整,min(1, 2, 3) 取最小值,max()取最大值。这些函数在处理响应式尺寸时尤其好用。

scss 复制代码
$container-width: 1200px;
$gutter: 20px;

.item {
  width: percentage(1/3);  // 33.33333%
  margin-right: $gutter;
  
  &:nth-child(3n) {
    margin-right: 0;
  }
}

3. 字符串函数:玩文字

quote()加引号,unquote()去引号,str-index()查找位置,str-insert()插入。虽然不是天天用,但需要的时候真香。

4. 检查函数:知己知彼

type-of($var)返回变量类型,unit(10px)返回单位,unitless(10px)判断是否有单位。写mixin时常用到,比如:

scss 复制代码
@mixin size($value) {
  @if unitless($value) {
    // 如果没单位,默认px
    width: #{$value}px;
  } @else {
    width: $value;
  }
}

三、控制指令:让CSS长脑子

这才是Sass最像编程语言的地方------有了条件判断和循环,你就能批量生成样式,再也不用一个一个手写了。

1. @if:聪明的条件判断

根据不同的情况输出不同的样式。

scss 复制代码
@mixin theme($mode) {
  @if $mode == 'light' {
    background: white;
    color: black;
  } @else if $mode == 'dark' {
    background: #333;
    color: white;
  } @else {
    background: gray;
    color: black;
  }
}

.light-theme { @include theme(light); }
.dark-theme { @include theme(dark); }

这个例子在真实项目中很有用,比如根据主题切换颜色。

2. @for:循环造样式

你写过这样的代码吗?

css 复制代码
.m-1 { margin: 4px; }
.m-2 { margin: 8px; }
.m-3 { margin: 12px; }
.m-4 { margin: 16px; }
.m-5 { margin: 20px; }

写了五行手就酸了。用@for:

scss 复制代码
@for $i from 1 through 5 {
  .m-#{$i} {
    margin: #{$i * 4}px;
  }
}

一行代码生成了五个类,想生成到100也是分分钟的事。through包括结束值,to不包括。

3. @each:遍历列表

如果你要基于一个列表生成样式,比如不同颜色的按钮:

scss 复制代码
$colors: (primary: #8A2BE2, success: #28a745, danger: #dc3545);

@each $name, $color in $colors {
  .btn-#{$name} {
    background: $color;
    color: white;
    
    &:hover {
      background: darken($color, 10%);
    }
  }
}

一键生成三个按钮样式,想加新的颜色?往列表里加一项就行。

4. @while:用条件控制循环

虽然不如for常用,但遇到动态条件时很有用。比如生成一个步长递增的系列:

scss 复制代码
$i: 6;
@while $i > 0 {
  .item-#{$i} {
    width: 2px * $i;
  }
  $i: $i - 2;
}

四、实战:用Sass生成一个完整的工具类库

我们来做点实在的。比如你要做一个工具类库,包含外边距、内边距、文字颜色、背景色,而且要有不同的尺寸和状态。手动写?那得写到明年。用Sass的循环和函数,分分钟搞定。

scss 复制代码
// 定义配置
$spacing-sizes: (0, 4, 8, 12, 16, 20, 24);
$colors: (
  primary: #8A2BE2,
  success: #28a745,
  danger: #dc3545,
  warning: #ffc107
);

// 生成外边距工具类
@each $size in $spacing-sizes {
  .m-#{$size} {
    margin: #{$size}px !important;
  }
  
  .mt-#{$size} {
    margin-top: #{$size}px !important;
  }
  
  .mb-#{$size} {
    margin-bottom: #{$size}px !important;
  }
  
  .ml-#{$size} {
    margin-left: #{$size}px !important;
  }
  
  .mr-#{$size} {
    margin-right: #{$size}px !important;
  }
  
  .mx-#{$size} {
    margin-left: #{$size}px !important;
    margin-right: #{$size}px !important;
  }
  
  .my-#{$size} {
    margin-top: #{$size}px !important;
    margin-bottom: #{$size}px !important;
  }
}

// 生成颜色工具类
@each $name, $color in $colors {
  .text-#{$name} {
    color: $color !important;
  }
  
  .bg-#{$name} {
    background-color: $color !important;
  }
  
  .border-#{$name} {
    border-color: $color !important;
  }
}

这段代码编译后会生成上百个工具类,够你在项目里用一辈子。而且改一个配置,所有类自动更新,爽不爽?

五、进阶技巧:让Sass更上一层楼

1. 使用&选择器的高级玩法

&代表父选择器,除了用在伪类,还能用来生成BEM风格的类名。

scss 复制代码
.block {
  background: #f5f5f5;
  
  &__element {
    padding: 10px;
  }
  
  &--modifier {
    border: 1px solid red;
  }
}

编译成:

css 复制代码
.block { background: #f5f5f5; }
.block__element { padding: 10px; }
.block--modifier { border: 1px solid red; }

完美符合BEM命名规范,还不用手写冗长的类名。

2. 使用@error做校验

在mixin里加参数校验,提前报错,省得调试半天不知道错在哪。

scss 复制代码
@mixin size($width, $height: $width) {
  @if unitless($width) or unitless($height) {
    @error "width和height必须带单位!";
  }
  
  width: $width;
  height: $height;
}

3. 使用@debug和@warn

调试时输出变量值,或者在即将弃用的样式上给警告。

scss 复制代码
@debug $primary-color;  // 控制台输出变量值
@warn "这个mixin快过期了,别用了";  // 警告信息

六、总结

Sass真正强大之处,在于它把CSS从"描述语言"变成了"编程语言"。通过今天的内容,你学会了:

  • 模块化 :用@use@forward组织代码,告别混乱
  • 内置函数:操作颜色、数字、字符串,让样式自动计算
  • 控制指令@if判断,@for循环,@each遍历,批量生成样式
  • 高级技巧&的妙用,参数校验,调试工具

掌握了这些,你写CSS的效率能提升好几倍。更重要的是,你的样式代码会变得像程序一样有逻辑、可维护。别人还在手动改颜色,你已经用循环生成了整个主题;别人还在复制粘贴,你已经用mixin封装了所有复用逻辑。

明天我们将进入JavaScript的世界,从基础开始重新认识这门"前端灵魂语言"。无论你是想巩固基础,还是查漏补缺,都值得期待。

如果你觉得今天的文章够骚够实用,点个赞让更多人看到。有问题评论区见,我们明天见!

相关推荐
cpolar技术支持1 分钟前
本地 Playwright 测试报告怎么远程复盘?Trace Viewer 跑起来后,用 cpolar 分享失败现场
前端·自动化测试·测试工具·cpolar·playwright
wordbaby1 分钟前
企业级后台管理系统路由设计与最佳实践指南
前端
胡志辉的博客11 分钟前
【完全开源】IP 纯净度检测 可一键部署到自己的CF
前端·javascript·chrome·ip·chromium
Hilaku37 分钟前
作为面试官,我最怕遇到什么样的候选人?
前端·javascript·程序员
TiDi1 小时前
Pinia优化重复请求
前端
web3d5201 小时前
01-用 Leafletjs 10 分钟搭一张水利一张图(Vue3 + Vite 实战)
前端·javascript
晚安日记wanna1 小时前
Vue2 的 defineProperty 差在哪四层追问筛掉九成候选人
前端·vue.js·面试
TiDi1 小时前
吸顶导航交互实现
前端
kisshyshy1 小时前
从Props透传到自定义Hook:系统梳理React跨层级通信与逻辑复用
前端·架构·代码规范
yume_sibai1 小时前
05-Flutter实战项目
前端·flutter