学会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指令允许你根据条件判断来输出不同的样式。

less 复制代码
$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>

less 复制代码
@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函数。

less 复制代码
@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

less 复制代码
$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中的值。

perl 复制代码
$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文件,这样可以更好地组织你的样式代码。

scss 复制代码
// 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的既视感?

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

perl 复制代码
$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的键值对文件

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

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

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

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

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

less 复制代码
@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

ruby 复制代码
@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配置如下:

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

项目用法:

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

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

相关推荐
十一吖i8 分钟前
前端将后端返回的文件下载到本地
vue.js·elementplus
光影少年9 分钟前
vue2与vue3的全局通信插件,如何实现自定义的插件
前端·javascript·vue.js
Rattenking14 分钟前
React 源码学习01 ---- React.Children.map 的实现与应用
javascript·学习·react.js
熊的猫1 小时前
JS 中的类型 & 类型判断 & 类型转换
前端·javascript·vue.js·chrome·react.js·前端框架·node.js
mosen8682 小时前
Uniapp去除顶部导航栏-小程序、H5、APP适用
vue.js·微信小程序·小程序·uni-app·uniapp
别拿曾经看以后~3 小时前
【el-form】记一例好用的el-input输入框回车调接口和el-button按钮防重点击
javascript·vue.js·elementui
Gavin_9154 小时前
【JavaScript】模块化开发
前端·javascript·vue.js
小牛itbull6 小时前
ReactPress:重塑内容管理的未来
react.js·github·reactpress
Devil枫9 小时前
Vue 3 单元测试与E2E测试
前端·vue.js·单元测试
GIS程序媛—椰子10 小时前
【Vue 全家桶】6、vue-router 路由(更新中)
前端·vue.js