SCSS Notebook

为了解决 CSS 本身的缺点:

  • 语法不够强大,不能够嵌套书写,难以表达样式逻辑
  • 没有变量和逻辑上的复用机制,难以维护

诞生了一系列的 CSS 预处理器 Sass, Stylus, Less。

Sass从第三代开始,放弃了缩进式风格,并且完全向下兼容普通的CSS代码,这一代的Sass也被称为Scss。

文档

  • 中文文档:https://www.sass.hk
  • 英文文档:https://sass-lang.com/documentation
  • CSS转Scss:https://www.sass.hk/css2sass
  • Scss转CSS:https://www.sassmeister.com

Sass版本

Sass有三个版本Dart Sass、libsass和Ruby Sass:

  1. Dart Sass,用Dart语言写的sass实现,于2016年11月1日发布alpha版本,版本1.23.0之后完全支持模块化机制
  2. libSass也就是俗称的node-sass,用c/c++实现的sass版本,使用非常广泛。node-sass是绑定了 libsass的nodejs库,可以极快的将.scss 文件编译为.css文件
  3. Ruby Sass,是最初的Sass实现,但是2019年3月26日被停止了,以后也不会再支持,使用者需要迁移到别的实现上。

语法嵌套规则

选择器嵌套

css中重复写选择器是非常恼人的。尤其是html结构嵌套非常深的时候,scss的选择器嵌套可以避免重复输入父选择器,可以有效的提高开发效率,减少样式覆盖可能造成的异常问题。这也是我们最常用的功能。

这个是正常的css结构

.container {
	width: 1200px;
	margin: 0 auto;
}
.container .header .img {
	width: 100px;
	height: 60px;
}

在 scss中只需要这么写:

.container {
	width: 1200px;
	margin: 0 auto;
	.header {
		.img {
			width: 100px;
			height: 60px;
		}
	}
}

属性嵌套

有些css属性遵循相同的命名空间 (相同的开头),比如font-familyfont-sizefont-weight都以font作为属性的命名空间。为了便于管理这样的属性,也为了避免重复输入。

.container {
	font: {
		family: fantasy;
		size: 30em;
		weight: bold;  
	}
}

命名空间也可以包含自己的属性值

.container {
	color: red {
		adjust: fantasy;  
	}
}

父选择器&

在嵌套 css 规则时,有时会需要使用嵌套外层的父选择器,例如,当给某个元素设定 hover 样式时,可以用& 代表嵌套规则外层的父选择器,scss在编译时会把&替换成父选择器名。

案例里面的&表示的就是父级a选择器

.container {
	a {
		color: #333;
			&:hover {
				text-decoration: underline; 
				color: #f00;        
		}    
	}
}

转化成css

.container a {
	color:#333;
}
.container a:hover {
	text-decoration:underline;   
	color:#F00;
}

变量

使用

原生css中的变量,使用--变量名:变量值定义,var(--变量名)进行使用。

:root {
	--color: #F00;
}
p {
	color: var(--color);
}

scss中的变量,以美元符号$开头,赋值方法与 css 属性的写法一样。

$color:#F00;

p {
	color: $color;
}

变量作用域

  1. 变量作用域分为全局变量域局部变量域
  • 全局变量:声明在最外层的变量,可在任何地方使用;
  • 局部变量:嵌套规则内定义的变量只能在嵌套规则内使用。

将局部变量转换为全局变量可以添加!global 声明。

$color: red;
.container {
    $height: 500px;
    $font-size: 16px !global;
    font-size: $font-size;
    color: $color;
    height: $height;
}
.footer {
    /**$font-size使用!global 申明成全局变量了*/
    font-size: $font-size; 
}

数据类型

scss 支持 7 种主要的数据类型:

  1. 数字,1rem、2vh、13、 10px
  2. 字符串,分有引号字符串与无引号字符串,"foo"、 'bar'、baz
  3. 颜色,blue, #04a3f9, rgba(255,0,0,0.5)
  4. 布尔型,truefalse
  5. 空值,null是其类型的唯一值。表示缺少值,通常由函数返回以表示缺少结果;
  6. 数组 (list),用空格或逗号作分隔符,1.5em 1em 0 2em,Helvetica,Arial,sans-serif
  7. maps, 相当于 JavaScriptobject(key1: value1, key2: value2)

语句

流程控制

sass中流程控制包含四类,也是我们在js中常见的@if、@for、@each、@while

@if

@if语法和js类似,基本格式是@if...@else if...@else

@for

for在条件范围内重复操作,这个指令包含两种格式:

  1. @for $var from <start> through <end>
  2. @for $var from <start> to <end>

两者区别在于 throughto的含义:

  1. 使用 through时,条件范围包含 <start><end>的值;
  2. 使用 to时条件范围只包含<start>的值不包含<end>的值;
  3. $var 可以是任何变量,比如$i<start><end> 必须是整数值。
@for $i from 1 to 3 {
  #loading span:nth-child(#{$i}) {
      width: 20 * ($i - 1) + px;
  }
}

@each

@each指令的格式是@each $var in $list , $var可以是任何变量名,比如$length 或者$name,而$list是一连串的值,也就是值列表。

$color-list:red green blue turquoise darkmagenta;
@each $color in $color-list {
    $index: index($color-list, $color);
    .p#{$index - 1} {
        background-color: $color;
    }
}

@while

@while 指令循环输出直到表达式返回结果为 false。这样可以实现比@for 更复杂的循环。

$column:12;
@while $column>0 {
   .col-sm-#{$column} {
      width: $column / 12 * 100%;
   }
    $column:$column - 1;
}

@import

@import算是一个比较简易的模块系统。拓展了@import 的功能,允许其导入 scss或 文件。被导入的文件将合并编译到同一个 文件中,被导入的文件中所包含的变量或者混合指令 (mixin) 都可以在导入的文件中使用。

common.scss

$color:red;

index.scss

@import "common.scss";
.container {
	border-color: $color;
}

以下情况下,@import 仅作为普通的语句,不会导入文件:

  1. 文件拓展名是.css
  2. 文件名以 http://开头;
  3. 文件名是url()
  4. @import包含媒体查询。

允许同时导入多个文件,例如同时导入 rounded-cornerstext-shadow 两个文件,不用再单独写个import引入。

@import "rounded-corners", "text-shadow";

@media 媒体查询增强

中,@media 指令与 中用法一样,只是增加了一点额外的功能,允许在规则中嵌套。如果@media 嵌套在 规则内,编译时,@media 将被编译到文件的最外层,包含嵌套的父选择器。这个让 @media 方便不少,不需要重复写选择器,也不会打乱 的书写流程。

.sidebar {
  width: 300px;
  @media screen and (orientation: landscape) {
    width: 500px;
    .item {
      height: auto;
    }
  }
}

@mixin

混合指令(Mixin)用于定义可重复使用的样式。混合指令可以包含所有的规则,绝大部分 规则,甚至可以通过参数功能引入变量,输出多样化的样式。

注意:函数命名和变量命名规则一致。

@mixin mixin-name() {
    /* css 声明 */
}
// 使用
@include mixin-name;
// 定义一个区块基本的样式
@mixin block {
    width: 96%;
    margin-left: 2%;
    border-radius: 8px;
    border: 1px #f6f6f6 solid;
}
// 使用混入 
.container {
    .block {
        @include block;
    }
}

编译为

.container .block {
    width: 96%;
    margin-left: 2%;
    border-radius: 8px;
    border: 1px #f6f6f6 solid;
}

摘抄整理自 前端达人


Last modified on 2023-10-04