Scss 基础
[TOC]
Vue3 + Vite + typescript 使用 Scss
安装
npm install sass sass-loader --save-dev
如果使用 vite 则可以忽略sass-loader
,因为 vite 内置支持 sass在 vue 文件中即可使用
<style scope lang="scss"></style>
定义全局 scss 文件(不需要可以忽略)
- 新建文件(假如目录为:
./src/assets/style/global.scss
) - 在
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});
}
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
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)