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

相关推荐
匹马夕阳1 小时前
Vue 3中导航守卫(Navigation Guard)结合Axios实现token认证机制
前端·javascript·vue.js
你熬夜了吗?1 小时前
日历热力图,月度数据可视化图表(日活跃图、格子图)vue组件
前端·vue.js·信息可视化
screct_demo2 小时前
詳細講一下在RN(ReactNative)中,6個比較常用的組件以及詳細的用法
javascript·react native·react.js
沈梦研8 小时前
【Vscode】Vscode不能执行vue脚本的原因及解决方法
ide·vue.js·vscode
轻口味9 小时前
Vue.js 组件之间的通信模式
vue.js
光头程序员11 小时前
grid 布局react组件可以循数据自定义渲染某个数据 ,或插入某些数据在某个索引下
javascript·react.js·ecmascript
limit for me11 小时前
react上增加错误边界 当存在错误时 不会显示白屏
前端·react.js·前端框架
浏览器爱好者11 小时前
如何构建一个简单的React应用?
前端·react.js·前端框架
fmdpenny12 小时前
Vue3初学之商品的增,删,改功能
开发语言·javascript·vue.js
涔溪12 小时前
有哪些常见的 Vue 错误?
前端·javascript·vue.js