学会Sass的高级用法,减少样式冗余

在当今的前端开发领域,样式表语言的进步已经显著提升了代码组织性和可维护性。Sass(Syntactically Awesome Style Sheets)作为CSS预处理器的翘楚,以其强大的变量、嵌套规则、混合宏(mixin)、循环和函数等高级特性,正在引领一种革命性的编写CSS的新方式。通过掌握Sass的这些高级用法,开发者能够有效地减少样式冗余,提升工作效率,并构建出更易于理解和扩展的样式结构。

引述一个具体的实践场景,想象一个大型项目中存在大量的重复颜色、尺寸或动画定义,使用Sass变量,可以将这些共享值统一管理,一处变更即全局生效。此外,借助@each循环语句,我们可以轻松地为一组类名生成具有不同颜色主题的一系列样式,避免了手动编写多条相似规则所带来的繁琐与潜在错误。

而诸如嵌套规则这样的功能,则允许我们以更加直观的方式模拟DOM结构,使得CSS选择器之间的层级关系更为清晰可见。同时,通过自定义混合宏,复杂的样式块得以模块化封装和复用,从而极大地降低了代码重复度,提高整体代码质量。

因此,深入学习并运用Sass的高级用法不仅简化了样式编写过程,也有助于构建出适应性强、扩展性好且易于维护的CSS代码库,是现代Web开发实践中不可或缺的一部分。

例举几个常见的用法:

一、控制指令

Sass提供了控制指令,允许你在样式表中使用条件语句和循环,从而更加灵活地控制样式的生成。

1. @if和@else if/else

Sass中的@if@else if@else指令允许你根据条件判断来输出不同的样式。

css 复制代码
$is-dark: true;  
  
body {  
  @if $is-dark {  
    background-color: black;  
    color: white;  
  } @else {  
    background-color: white;  
    color: black;  
  }  
}

2.@for

Sass的@for指令可以用于循环输出样式,支持两种循环方式:from <start> through <end>from <start> to <end>

css 复制代码
@for $i from 1 through 3 {  
  .item-#{$i} { width: 10px * $i; }  
}

二、函数

Sass内置了一系列函数,可以用于处理颜色、数值和字符串等,同时你也可以定义自己的函数。

1.内置函数

Sass内置函数如darken()lighten()opacity()等,用于操作颜色值。

css 复制代码
$base-color: #333;  
  
.dark-text {  
  color: darken($base-color, 10%);  
}  
  
.light-text {  
  color: lighten($base-color, 20%);  
}

2.自定义函数

你可以使用@function指令定义自己的Sass函数。

css 复制代码
@function em($px) {  
  @return $px / 16 * 1em;  
}  
  
h1 {  
  font-size: em(32); // 等同于 font-size: 2em;  
}

三、扩展/占位符

Sass的扩展(Extend)和占位符(Placeholder)功能,可以帮助你避免重复编写相同的样式代码。

1.扩展(@extend)

@extend允许你共享一组CSS属性的选择器。

css 复制代码
.message {  
  border: 1px solid #ccc;  
  padding: 10px;  
  color: #333;  
}  
  
.success {  
  @extend .message;  
  border-color: green;  
}  
  
.error {  
  @extend .message;  
  border-color: red;  
}

2.占位符(%)

占位符类似于类选择器,但它不会直接输出到CSS中,只有当它被@extend时才会被渲染。

css 复制代码
%ir {  
  display: inline-block;  
  background-color: transparent;  
  border: none;  
  padding: 0;  
  /* ... */  
}  
  
button {  
  @extend %ir;  
  font-size: 1rem;  
  /* ... */  
}

四、Map数据结构

Sass支持Map数据结构,它允许你存储键值对,并通过键来访问对应的值。

1、map-get

复制代码
css 复制代码
$font-sizes: (  
  xsmall: 12px,  
  small: 14px,  
  medium: 16px,  
  large: 18px,  
  xlarge: 20px  
);  
  
h1 {  
  font-size: map-get($font-sizes, large);  
}

2、map-merge

map-merge是Sass中的一个函数,用于将两个map(映射)合并成一个新的map。Sass中的映射表示一个或多个键值对,并且是不可改变的。因此,map-merge函数会返回一个新的map,而不会更改原始的map。

具体来说,如果你有两个map,你可以使用map-merge函数将它们合并为一个map。在合并过程中,如果两个map中存在相同的键,那么新map中的值将是第二个map中对应键的值,因为它会覆盖第一个map中的值。

css 复制代码
$map1: (  
  key1: value1,  
  key2: value2  
);  
  
$map2: (  
  key2: value3,  
  key3: value4  
);  
  
$mergedMap: map-merge($map1, $map2);  
  
// 输出:$mergedMap 为 (key1: value1, key2: value3, key3: value4)

五、使用@import合并文件

Sass允许你使用@import指令来导入其他Sass文件,这样可以更好地组织你的样式代码。

css 复制代码
// styles.scss  
@import 'partials/variables';  
@import 'partials/mixins';  
@import 'partials/reset';  
@import 'partials/layout';  
@import 'partials/modules';

以上只是Sass高级用法的一部分,Sass还提供了更多强大的功能,如颜色运算、选择器嵌套等。掌握这些高级用法将使你在编写样式时更加得心应手,提高代码的可读性和可维护性。通过不断地实践和学习,你可以发掘Sass的更多潜力,并将其应用于实际项目中,创造出更加美观和高效的界面。

下面我们来列举几个实战例子,实战才是快速学习的捷径。

例子

需求1:我们需要在每个标题前添加不同颜色的小方块作为无序列表的原点。如图所示

常规做法:

css 复制代码
.icon {
  &::before {
    content: '';

    width: 8px;
    height: 8px;

    position: absolute;
    top: 50%;
    left: 0;
    transform: translateY(-50%);

  }
}

.color-icon-1 {
   background: #0096ff;
}

.color-icon-2 {
   background: #ffcc00;
}

.color-icon-3 {
   background: #00ffff;
}

.color-icon-4 {
   background: #ff6363;
}

.color-icon-5 {
   background: #00ccff;
}

.color-icon-6 {
  background: #483B3B;
}

使用时就是 <p class="color-icon-1 icon" />,这种写法极其不优雅,并且定义的样式也冗余。

下面使用Sass > (@each, @mixin)进行二次封装

  • @each: 类似用JS中的for循环
  • @mixin: 利用mixin创建的函数需使用@include注入
css 复制代码
@mixin screenBefore(
  $color,
  $width: 0.13rem,
  $height: 0.13rem
) {
  &::before {
    content: '';

    width: $width;
    height: $height;

    position: absolute;
    top: 50%;
    left: 0;
    transform: translateY(-50%);

    background: $color;
  }
}
$colors: (
    1:#0096ff,
    2:#ffcc00,
    3:#00ffff,
    4:#ff6363,
    5:#00ccff,
    6:#483B3B
  );

  @each $colorIndex, $colorValue in $colors {
    .color-icon-#{$colorIndex} {
      @include screenBefore($colorValue )
    }
  }

是不是有写JS的既视感?

多参则利用列表去作为参数

css 复制代码
$alarm-colors: (
    1:(#d9001b, 0.17rem, 0.17rem),
    2:(#8a00e1, 0.17rem, 0.17rem),
    3:(#34d160, 0.17rem, 0.17rem),
    4:(#00c6ff, 0.17rem, 0.17rem),
    5:(#d9001b, 0.15rem, 0.15rem),
    6:(#8a00e1, 0.15rem, 0.15rem),
    7:(#34d160, 0.15rem, 0.15rem),
    8:(#00c6ff, 0.15rem, 0.15rem)
  );

  @each $colorIndex, $colorValue in $alarm-colors {
    $color: nth($colorValue, 1);
    $width: nth($colorValue, 2);
    $height: nth($colorValue, 3);
    .screen-alarm-list-#{$colorIndex} {
      @include screenBefore(
        $color,
        $width,
        $height
      )
    }
  }

}

需求二、利用map_merge实现主题的切换

现有两个颜色map的键值对文件

css 复制代码
// theme-default
$theme-default {
    colorPrimary: #FFF
}

// theme-blue
$theme-blue {
    colorPrimary: blue
}

// 主要color-map
$themes: map_merge($theme-default, $theme-blue);

下面使用高级用法,列举一个全局注入主题样式的详细过程

1、首先定义一个高阶Sass插槽处理函数。

css 复制代码
@mixin generateThemeContent($name, $theme) {
  $globalTheme: $theme !global;
  $globalThemeName: $name !global;

  @if (str_length($name)>0) {
    .theme-#{$name} {
      @content;
    }
  } @else {
    html {
      @if ($generate_default) {
        @content;
      }
    }
  }
}

2、其次在Sass主入口文件中定义全局Mixin

css 复制代码
@import './blue.scss'; // $theme-blue
@import './default.scss'; // $theme-default

$themes: map_merge($theme-default, $theme-blue);
$generate_default: true; // 触发插槽判断

@mixin theme {
  @each $curThemeName, $curTheme in $themes {
    @include generateThemeContent($curThemeName, $curTheme) {
      @content;
    }
  }
}

拿Vue为例子,在其vue.config.js配置中找到css配置如下:

css 复制代码
css: {
    sourceMap: false,
    loaderOptions: {
      sass: {
        prependData: `@import "src/styles/theme/global-import.scss";` // 在 sass-loader v8 中,这个选项名是 "prependData"
      }
    }
  },

项目用法:

html 复制代码
<style lang="scss" scoped>
@include theme {
    // 这里可以尽情用主题中定义的变量
}
</style>

用好Sass/Less等这类的处理器,确实能大大减少我们的重复编写样式的工作用,并且增加可读性,更贴切逻辑性编写。

相关推荐
恋猫de小郭25 分钟前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅7 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60618 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅8 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅9 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅9 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊9 小时前
jwt介绍
前端