Scss 基础

2024 年 8 月 10 日 星期六(已编辑)
/
44
1
摘要
Scss 基础学习
这篇文章上次修改于 2024 年 8 月 10 日 星期六,可能部分内容已经不适用,如有疑问可询问作者。

Scss 基础

[TOC]

Vue3 + Vite + typescript 使用 Scss

  1. 安装 npm install sass sass-loader --save-dev 如果使用 vite 则可以忽略 sass-loader,因为 vite 内置支持 sass

  2. 在 vue 文件中即可使用<style scope lang="scss"></style>

  3. 定义全局 scss 文件(不需要可以忽略)

    1. 新建文件(假如目录为:./src/assets/style/global.scss
    2. vite.config.ts中添加下面代码:(其中,css 是与 plugins 同级)
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: '@use "./src/assets/style/globalStyle.scss" as *;'
        }
      }
    }

​ 3. 即可直接使用,无需使用@use@import

定义变量

$font-stack:  Helvetica, sans-serif;
$primary-color: #333;
$class-name: myClass;

body {
  font: 100% $font-stack;
  color: $primary-color;
}

#{$class-name} {
    color: $primary-color;
}

块语法

.nav {
  background: #eee;
  li {
    display: inline-block;
  }
}

& 引用父选择器

需注意缩排写法,可使用&符号来引用父选择器,常用于 CSS 元件状态:hover、:focus、:before、:after 等。

nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  li { display: inline-block; }

  a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
    &:hover {
      color: red;
    }
  }
}

相当于原生 css 如下:

nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
nav li {
  display: inline-block;
}
nav a {
  display: block;
  padding: 6px 12px;
  text-decoration: none;
}
nav a:hover {
  color: red;
}

@mixin 与 @include

将经常被重复使用的程式码独立撰写,以@mixin 语法包装起来,需要时透过@include 引用,即可根据不同参数来设定相似的样式,常用于 width、height、flex-center 等。

// 经常重复使用的样式
@mixin transform($property) {
  -webkit-transform: $property;
  -ms-transform: $property;
  transform: $property;
}

// 需要套用的样式代码
.box { 
  @include transform(rotate(30deg));
}
.avatar { 
  @include transform(rotate(90deg));
}

相当于原生的 css 如下:

.box {
  -webkit-transform: rotate(30deg);
  -ms-transform: rotate(30deg);
  transform: rotate(30deg);
}
.avatar {
  -webkit-transform: rotate(90deg);
  -ms-transform: rotate(90deg);
  transform: rotate(90deg);
}

@extend

使用说明:当许多选择器具有相同样式时,可透过%占位符号宣告,将所有相同样式内容合并,再用@extend引入使用。

第一种使用方法:

/* This CSS will print because %message-shared is extended. */
%message-shared {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
}

// This CSS won't print because %equal-heights is never extended.
%equal-heights {
  display: flex;
  flex-wrap: wrap;
}

.message {
  @extend %message-shared;
}

.success {
  @extend %message-shared;
  border-color: green;
}

.error {
  @extend %message-shared;
  border-color: red;
}

.warning {
  @extend %message-shared;
  border-color: yellow;
}

相当于原生的 css 如下:

/* This CSS will print because %message-shared is extended. */
.message, .success, .error, .warning {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
}

.success {
  border-color: green;
}

.error {
  border-color: red;
}

.warning {
  border-color: yellow;
}

第二种使用方法:

.error {
  border: 1px #f00;
  background-color: #fdd;

  &--serious {
    @extend .error;
    border-width: 3px;
  }
}

相当于原生的 css 如下:

.error, .error--serious {
  border: 1px #f00;
  background-color: #fdd;
}
.error--serious {
  border-width: 3px;
}

@mixin 与 @extend 的区别

使用时从下面两点考虑:

  • 是否需传递参数
  • 是否需考虑编译后 CSS 大小

@if/@else

$light-background: #f2ece4;
$light-text: #036;
$dark-background: #6b717f;
$dark-text: #d2e1dd;

@mixin theme-colors($light-theme: true) {
  @if $light-theme {
    background-color: $light-background;
    color: $light-text;
  } @else {
    background-color: $dark-background;
    color: $dark-text;
  }
}

.banner {
  @include theme-colors($light-theme: true);
  body.dark & {
    @include theme-colors($light-theme: false);
  }
}

相当于原生的 css 如下:

.banner {
  background-color: #f2ece4;
  color: #036;
}
body.dark .banner {
  background-color: #6b717f;
  color: #d2e1dd;
}

@each

$sizes: 40px, 50px, 80px;

@each $size in $sizes {
  .icon-#{$size} {
    font-size: $size;
    height: $size;
    width: $size;
  }
}

相当于原生的 css 如下:

.icon-40px {
  font-size: 40px;
  height: 40px;
  width: 40px;
}

.icon-50px {
  font-size: 50px;
  height: 50px;
  width: 50px;
}

.icon-80px {
  font-size: 80px;
  height: 80px;
  width: 80px;
}

map 变量

$icons: ("eye": "\f112", "start": "\f12e", "stop": "\f12f");

@each $name, $glyph in $icons {
  .icon-#{$name}:before {
    display: inline-block;
    font-family: "Icon Font";
    content: $glyph;
  }
}

相当于原生的 css 如下:

.icon-eye:before {
  display: inline-block;
  font-family: "Icon Font";
  content: "\f112";
}

.icon-start:before {
  display: inline-block;
  font-family: "Icon Font";
  content: "\f12e";
}

.icon-stop:before {
  display: inline-block;
  font-family: "Icon Font";
  content: "\f12f";
}

其他写法:

$icons:
  "eye" "\f112" 12px,
  "start" "\f12e" 16px,
  "stop" "\f12f" 10px;

@each $name, $glyph, $size in $icons {
  .icon-#{$name}:before {
    display: inline-block;
    font-family: "Icon Font";
    content: $glyph;
    font-size: $size;
  }
}

相当于 css 如下:

.icon-eye:before {
  display: inline-block;
  font-family: "Icon Font";
  content: "\f112";
  font-size: 12px;
}

.icon-start:before {
  display: inline-block;
  font-family: "Icon Font";
  content: "\f12e";
  font-size: 16px;
}

.icon-stop:before {
  display: inline-block;
  font-family: "Icon Font";
  content: "\f12f";
  font-size: 10px;
}

@for

$base-color: #036;

@for $i from 1 through 3 {
  ul:nth-child(3n + #{$i}) {
    background-color: lighten($base-color, $i * 5%);
  }
}

相当于 css 如下:

ul:nth-child(3n+1) {
  background-color: #004080;
}

ul:nth-child(3n+2) {
  background-color: #004d99;
}

ul:nth-child(3n+3) {
  background-color: #0059b3;
}

@debug

使用说明:写入@debug <expression>,并打印该表达式的值以及文件名和行号。

@mixin inset-divider-offset($offset, $padding) {
  $divider-offset: (2 * $padding) + $offset;
  @debug "divider offset: #{$divider-offset}";

  margin-left: $divider-offset;
  width: calc(100% - #{$divider-offset});
}
调试消息的具体格式因实现而异。在 Dart Sass 中,它如下所示:
test.scss:3 Debug: divider offset: 132px

@use

使用说明:该规则从其他 Sass 样式表中@use加载mixins函数变量,并将来自多个样式表的CSS 组合在一起

// src/_corners.scss
$radius: 3px;

@mixin rounded {
  border-radius: $radius;
}
// style.scss
@use "src/corners";

.button {
  @include corners.rounded;
  padding: 5px + corners.$radius;
}

也可以:

// style.scss
@use "src/corners" as c;

.button {
  @include c.rounded;
  padding: 5px + c.$radius;
}

区别@import

@use规则旨在取代旧@import规则,但它被有意设计为以不同的方式工作。以下是两者之间的一些主要区别:

  • @use仅在当前文件范围内提供变量、函数和混合。它永远不会将它们添加到全局范围。这使得很容易找出 Sass 文件引用的每个名称的来源,并且意味着您可以使用较短的名称而不会发生任何 冲突的风险。
  • @use每个文件仅加载一次。这可确保您不会意外地多次重复依赖项的 CSS。
  • @use必须出现在文件的开头,并且不能嵌套在样式 规则中。
  • 每个@use规则只能有一个 URL。
  • @use需要用引号括住其 URL,即使使用缩进 语法

单位

css 定义 1in(即 1 inch)等于 96 px

// CSS defines one inch as 96 pixels.
@debug 1in + 6px; // 102px or 1.0625in

@debug 1in + 1s;
//     ^^^^^^^^
// Error: Incompatible units s and in.

运算符

boolean

  • && 运算符相当于 scss 的 and
  • || 运算符相当于 scss 的 or
  • ! 运算符相当于 scss 的 not

内置函数

math

  1. math.div(v1, v2) => v1/v2

nth

语法:nth(list, n) 使用说明:nth() 函数用来指定列表中某个位置的值(n 必须 > 0)

>> nth(10px 20px 30px,1)
10px
>> nth((Helvetica,Arial,sans-serif),2)
"Arial"
>> nth((1px solid red) border-top green,1)
(1px "solid" #ff0000)
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...