scss精华总结

一、 环境搭建

本篇演示使用vite 搭建一个简单的项目来看演示效果。搭建步骤如下:

1、 新建一个项目vite-scss

2、 初始化项目: pnpm init,这时候会生成packages.json

3、 安装vite: pnpm i vite -D

4、 在packages.json中添加打包命令

js 复制代码
"scripts": {
    "dev": "vite",
    "build": "vite build"
},

5、 安装sass: pnpm i sass -D

6、 根目录下新建index.html作为vite 的入口文件

7、 根目录下面创建src 目录

8、 src 下面创建css 目录和js目录

9、 css 目录下创建index.scss

10、 js 目录下创建index.js

11、 index.js中引入index.csss

12 index.html中引入index.js , 注意scrpit标签上必须添加type="module"

搭建完成之后目录结构如下:

13、 运行项目:pnpm run dev

14、 预览效果: 打开浏览器输入http://localhost:5173

二、scss 嵌套语法

在早期的原生csss是不支持嵌套的写法的,所以我们为了css 样式尽量的不出现覆盖,我们会一直在前面重复写父级的类名来规避。会非常麻烦,这个时候就scss就很好的解决了这个问题。scss提供了嵌套写法,使得我们不用重复写父级的类名,且结构更加清晰易读。现在我们用scss来写一个简单的导航:

html 结构如下

html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>vite+scss</title>
  </head>
  <body>
    <nav>
      <a href="#">首页</a>
      <a href="#">列表</a>
      <a href="#">个人中心</a>
    </nav>
    <script src="./src/js/index.js" type="module"></script>
  </body>
</html>

index.scss

css 复制代码
nav {
  display: flex;
  justify-content: space-around;
  box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.3);
  a {
    color: #333;
    text-decoration: none;
    padding: 6px 16px;
  }
}

浏览器f12可以在浏览器调试工具中看到编译后css:

可以看到我们编写scss 被编译成了普通的css

三、scss 中变量的使用

在早期的css 中同样不支持变量的写法,这样使得我们在实现某些需求的时候就非常麻烦,比如说现在有一个需求,要开发一个产品,这个产品有不同的品牌,不同品牌之间除了颜色不同外其他基本相同,这个时候如果没有scss 我们可能就会想着写两套代码,来实现这个需求,这样就需要维护两套代码,造成了很大的维护成本,产品更新的时候需要两套代码同时更新。而有了scss 变量 就可以很好的解决这个问题。还是以之前的导航为例:

html 结构中增加选中导航的类名:

在src/css下面增加品牌配置变量的scss文件,brand.scss

scss 复制代码
// 品牌主风格颜色变量
$color: blue;
$active-bg: yellow;

根目录新增vite.config.js配置文件,内容如下:

js 复制代码
// vite.config.js
import { defineConfig } from "vite";
import path from "path";

export default defineConfig({
  css: {
    preprocessorOptions: {
      scss: {
        additionalData: `
          @use "@/css/brand.scss" as *; 
        `, // 配置全局scss
      },
    },
  },
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "src"), // 配置别名
    },
  },
});

修改index.scss

scss 复制代码
nav {
  display: flex;
  justify-content: space-around;
  box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.3);
  a {
    color: $color; // 使用导航文字颜色变量
    text-decoration: none;
    padding: 6px 16px;

    &.active{ // 选中的类样式
      background: $active-bg; // 使用选中的颜色变量
      color: #fff;
    }
  }
}

主要修改以下内容:

这样要把不同品牌的代码发布到不同平台就非常简单了,只需要修改brand.scss中的变量,然后重新打包发布即可。甚至你可以将不同品牌的变量写成多个文件,通过命令的mode参数引用不同的文件。

上面的scss代码编译后同样会生成普通的css,将变量替换为我们定义时候的值:

四、混合指令

scss 的混合指令可以减少样式中相同部分样式的书写,来直接看例子

1. 不带参数的混合指令

html 结构:

html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>vite+scss</title>
  </head>
  <body>
    <button class="primary">按钮</button>
    <button class="sucecss">按钮</button>
    <script src="./src/js/index.js" type="module"></script>
  </body>
</html>

index.scss

scss 复制代码
@mixin button-style{ // 定义按钮的混合指令
  padding: 8px 20px;
  font-size: 16px;
  border-radius: 5px;
  color: #fff;
  border: none;
  outline: none
}

.primary{
  @include button-style; // 引用按钮的混合指令
  background: #409EFF;
}

.sucecss {
  @include button-style; // 引用按钮的混合指令
  background: #67C23A;
}

运行效果:

编译成css 后的样子:

可以看到混合指令在编译后,会把混合指令中的样式复制到引用混合指令的地方。

2. 带参数的混合指令

混合指令可以像js中函数一样可以传递参数,通过传递参数可以增强代码的复用性和可维护性。将上述按钮的scss实现代码优化一下。

scss 复制代码
@mixin button-style($bg-color){ // 定义按钮的混合指令
  padding: 8px 20px;
  font-size: 16px;
  border-radius: 5px;
  color: #fff;
  border: none;
  outline: none;
  background: $bg-color;
}

.primary{
  @include button-style(#409EFF); // 引用按钮的混合指令
}

.sucecss {
  @include button-style(#67C23A); // 引用按钮的混合指令
}

主要修改部分:

查看编译结果:

可以看到编译结果和之前是一样的。

3. 带有默认参数值的混合指令

和es6中的函数一样,混合指令的参数也可以定义默认值。具体使用方式如下:

index.scss

scss 复制代码
@mixin button-style($bg-color: #409EFF){ // 定义按钮的混合指令
  padding: 8px 20px;
  font-size: 16px;
  border-radius: 5px;
  color: #fff;
  border: none;
  outline: none;
  background: $bg-color;
}

.primary{
  @include button-style; // 引用按钮的混合指令
}

.sucecss {
  @include button-style(#67C23A); // 引用按钮的混合指令
}

主要修改内容:

可以看到我们将.primary的背景颜色值定义为了默认颜色,调用时不用传参就能达到我们想要的效果。

五、扩展/继承指令

扩展/继承指令 和混合指令功能有点类似,但也有很大差别。

  • 相同点: 都是为了实现一些样式属性的复用
  • 不同点: 混合指令可以传参数,扩展/继承指令不能传参数,混合指令编译后是将定义混合指令里的内容复制到引用混合的地方,而扩展/继承指令则是将这些相同的部分抽离成分组选择器。

来看扩展/继承指令 的使用:

scss 复制代码
.btn { // 定义按钮的混合指令
  padding: 8px 20px;
  font-size: 16px;
  border-radius: 5px;
  color: #fff;
  border: none;
  outline: none;
}

.primary{
  @extend .btn; // 引用按钮的混合指令
  background: #409EFF;
}

.sucecss {
  @extend .btn; // 引用按钮的混合指令
  background: #67C23A;
}

可以看到扩展/继承指令使用@extend 来实现。编译结果如下:

可以看到,@extend 比混合指令的编译出来的代码更简洁。

六、站位符%

细心的你可能会发现上面我们实现的继承的代码中的.btn这个类名编译后我们并不需要它,但是编译后它仍然存在,这不是我们想要的。这个时候就可以使用站位符来解决这个问题。

修改index.scss

scss 复制代码
%btn { // 定义按钮的混合指令
  padding: 8px 20px;
  font-size: 16px;
  border-radius: 5px;
  color: #fff;
  border: none;
  outline: none;
}

.primary{
  @extend %btn; // 引用按钮的混合指令
  background: #409EFF;
}

.sucecss {
  @extend %btn; // 引用按钮的混合指令
  background: #67C23A;
}

可以看到占位符以%开头,后面跟选择器名称,注意不要点

看看编译结果:

可以看到btn 在编译后就不存在了。

总结一下混合指令,扩展/继承指令,占位符的优缺点:

  • 三者都可以在看开发阶段节省代码
  • 混合指令,可以传参数,可以根据参数来决定渲染,开发阶段看上去更简单灵活,但是编译后代码重复的相对较多。
  • 继承普通类如果直接继承一个类,而这个类在html结构中又没有使用到,编译后则会多出一些无用的类
  • 继承占位符,如果继承的类在html结构中没有用到,则使用占位符代替,使得代码编译后更简洁

综上所述:在需要传参时优先使用混合指令,如果一个被继承的类在html结构中有使用到,则直接使用继承普通类名称,如果被继承的类在html结构中没有被使用到则使用占位符

七、父选择器 &

其实在之前的导航案例中我们就用到了 &,接下来就来介绍下 & 的用法

scss 复制代码
nav {
  &.list{
    color: #333;
  }
}

nav {
  & .list {
    color: #333;
  }
}
nav {
  .list & {
    color: #333;
  }
}

编译结果:

可以看到 & 有三种用法,所以写的时候要知道自己需要的是哪种,它们编译后的结果是不一样的。第一种方式是最常用的。后面两种几乎不用。

七、总结

本篇介绍了scss 最常用的5个功能,运用好它们让我们在项目开发中写出的代码更简洁,更高效,在选择混合选择器,继承/扩展指令,占位符时要注意哪个场景适合它们。

今天的分享就到这里了,感谢收看

相关推荐
朴shu5 分钟前
Avatar-Clipper 轻量级图片裁剪工具
前端·设计模式·开源
古夕5 分钟前
webpack 之 Loader 和 Plugin 接收参数对比
前端·面试·webpack
一只叫煤球的猫10 分钟前
1200行代码的前端组件?这套拆分套路让代码从此优雅
前端·vue.js·性能优化
涵信12 分钟前
第八节 工程化与高级特性-模块与命名空间的选择
前端·javascript·typescript
慢知行18 分钟前
VS Code 插件开发必备:轻量级日志工具的设计与实现
前端·typescript·visual studio code
上车函予19 分钟前
干掉图形验证码!基于PoW的Cap验证码集成指南
前端·后端
努力了吗梁同学25 分钟前
Nuxt3 中使用 pnpm 安装的 NuxtImg 使用会提示找不到图片
前端·vue·pnpm·nuxt·nuxtimg
归于尽28 分钟前
用火山引擎实现语音生成的实战踩坑与优化
前端·react.js
渐行渐远君4890128 分钟前
从手动到自动,React一站式前端国际化解决方案
前端