学会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等这类的处理器,确实能大大减少我们的重复编写样式的工作用,并且增加可读性,更贴切逻辑性编写。

相关推荐
y先森3 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy3 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189113 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿4 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡5 小时前
commitlint校验git提交信息
前端
虾球xz6 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇6 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒6 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员6 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐6 小时前
前端图像处理(一)
前端