npm install -g sass
css中重复写选择器是非常恼人的。尤其是html结构嵌套非常深的时候,scss的选择器嵌套可以避免重复输入父选择器,可以有效的提高开发效率,减少样式覆盖可能造成的异常问题。这也是我们最常用的功能。很多人用scss就只用了这个功能,然后觉得自己会了。
css中的样式
.container {
width: 1200px;
margin: 0 auto;
}
.container .header .img {
width: 100px;
height: 60px;
}
scss的写法,这边我感觉像less
.container {
width: 1200px;
margin: 0 auto;
.header {
.img {
width: 100px;
height: 60px;
}
}
}
有些css属性遵循相同的命名空间 (相同的开头),比如font-family,font-size,font-weight都以font作为属性的命名空间。为了便于管理这样的属性,也为了避免重复输入。
css中的写法
.container {
font-family: fantasy;
font-size: 30em;
font-weight: bold;
}
scss中的样式
.container {
font: {
family: fantasy;
size: 30em;
weight: bold;
}
}
也可以携带自己的属性
.container {
color: red {
adjust: fantasy;
}
}
在嵌套 css规则时,有时会需要使用嵌套外层的父选择器,例如,当给某个元素设定 hover 样式时,可以用& 代表嵌套规则外层的父选择器,scss在编译时会把&替换成父选择器名。
css中的样式
.container a {
color:#333;
}
.container a:hover {
text-decoration:underline;
color:#F00;
}
scss中的样式
.container {
a {
color: #333;
&:hover {
text-decoration: underline;
color: #f00;
}
}
}
也可以做选择器名称拼接,此时写在父类中的“&-名称”将不会携带父类
css中的样式
.main {
color: black;
}
.main-sidebar {
border: 1px solid;
}
scss中的写法
.main {
color:black;
&-sidebar {
border: 1px solid;
}
}
//变量的定义,语法:$变量名:变量值
$color:black;
p {
//变量的使用:$变量名
color:$color
}
如果当前在使用!default前没有定义此变量则使用该!default定义的默认值,否则使用定义的值
$col: black !default;
<
>
<=
>=
+
也可以连接字符串-
*
/
%
类似于mybatis中的#{},也是将变量插入到语法中,只不过scss要用$声明变量
$size:10px;
.box {
margin: #{$size} 0;
}
$theme:0;
.box {
@if($theme == 0) {
color: black;
} @else if($theme == 1) {
color: blue;
} @else {
color: red;
}
}
//语法 @for $变量名 from 起始位置 through 终止位置, $变量名的范围是[起始位置,终止位置]
@for $i from 1 through 3 {
.box span:nth-child(#{$i}) {
font-size: 10px * $i;
}
}
//语法 @for $变量名 from to through 终止位置,$变量名的范围是[起始位置,终止位置);
@for $i from 1 to 3 {
.box span:nth-child(#{$i}) {
font-size: 10px * $i;
}
}
//语法:@each $变量名 in 数组,类似于js中的for in
$items:[1, 2, 3, 4, 5];
@each $i in $items {
.box span:nth-child(#{$i}) {
font-size: $i * 10px;
}
}
//语法:$while 布尔表达式
$column:12;
@while $column>0 {
.col-sm-#{$column} {
width: $column / 12 * 100%;
}
$column:$column - 1;
}
@import算是一个比较简易的模块系统。scss拓展了@import 的功能,允许其导入 scss或 sass文件。被导入的文件将合并编译到同一个 css文件中,被导入的文件中所包含的变量或者混合指令 (mixin) 都可以在导入的文件中使用。
@import "./common";
.box {
color:$color
}
如果需要导入 scss或者 sass文件,但又不希望将其编译为 css,只需要在文件名前添加下划线,这样会告诉 scss不要编译这些文件。注意:
大多数情况下,一般在文件的最外层(不在嵌套规则内)使用@import,其实,也可以将@import 嵌套进内层选择器或者 @media 中,与平时的用法效果相同,只是这样导入的样式只能出现在嵌套的层中,存在作用域。
#main {
@import "example";
}
混合指令(Mixin)用于定义可重复使用的样式。混合指令可以包含所有的css规则,绝大部分 scss规则,甚至可以通过参数功能引入变量,输出多样化的样式。
//语法:@mixin 混入名 {样式}
@mixin block {
color: black;
font: {
size: 100px;
}
}
//引入混入
@import "base";
//使用混入
.box {
@include block;
}
//语法:@mixin 混入名 {样式}
@mixin block {
color: black;
.div {
font: {
size: 100px;
}
}
}
//引入混入
@import "base";
//使用混入
.box {
@include block;
}
.box {
color: black;
}
.box .div {
font-size: 100px;
}
/*# sourceMappingURL=index.css.map */
// 定义块元素内边距
@mixin block-padding($top, $right, $bottom, $left) {
padding-top: $top;
padding-right: $right;
padding-bottom: $bottom;
padding-left: $left;
}
// 按照参数顺序赋值
.container1 {
@include block-padding(10px, 20px, 30px, 40px);
}
// 可指定参数赋值
.container2 {
@include block-padding($left: 20px, $top: 10px, $bottom: 10px, $right: 30px);
}
// 可指定参数赋值,但是必须指定4个值,不能缺失
.container3 {
@include block-padding($left: 10px, $top: 10px, $bottom: 0, $right: 0);
}
.container1 {
padding-top: 10px;
padding-right: 20px;
padding-bottom: 30px;
padding-left: 40px;
}
.container2 {
padding-top: 10px;
padding-right: 30px;
padding-bottom: 10px;
padding-left: 20px;
}
.container3 {
padding-top: 10px;
padding-right: 0;
padding-bottom: 0;
padding-left: 10px;
}
// 定义块元素内边距,参数指定默认值
@mixin block-padding($top:0, $right:0, $bottom:0, $left:0) {
padding-top: $top;
padding-right: $right;
padding-bottom: $bottom;
padding-left: $left;
}
// 可指定参数赋值
.container {
/** 不带参数 */
@include block-padding;
/** 按顺序指定参数值 */
@include block-padding(10px,20px);
/** 给指定参数指定值 */
@include block-padding($left: 10px, $top: 20px)
}
@function用于封装复杂的操作,可以很容易地以一种可读的方式抽象出通用公式和行为,函数提供返回值,常用来做计算方面的工作。
//语法:@function 函数名(参数列表) {函数体}
@function square($base) {
@return $base * $base * 1px;
}
.sidebar {
float: left;
margin-left: square(4);
}
//语法:@function 函数名(参数列表) {函数体}
@function square($base: 10) {
@return $base * $base * 1px;
}
.sidebar {
float: left;
margin-left: square();
}
.sidebar {
float: left;
margin-left: 100px;
}
@return只允许在@function内使用,和js一样,遇到return就会返回。类似于java中的return
@function red() {
$is: true;
@if $is {
@return 'is';
}
@return red;
}
.con{
color: red();
}
.con {
color: "is";
}
和java中的extend的意思相同,这里是用来继承样式的,相对于java,scss是多继承,这一点就很好,一个儿子可以有好多个爹
.box1 {
font-size: 10px;
}
.box {
bakcgroud-color: red;
}
.box2 {
@extend: .box;
@extend .box1;
color: black;
}
编译
.box1, .box2 {
font-size: 10px;
}
.box2 {
color: black;
}
/*# sourceMappingURL=index.css.map */
算是对css选择器的扩展,但是只能用在@extend后
//语法:css原生选择器 %占位符选择器名
%a {
font-size: 10px;
}
.box2 {
//使用 @extend %占位符选择器名
@extend %a;
color: black;
}
注意: 占位符选择器%所属的样式未使用时,不会被编译到css文件中,算是一个小优化吧。
相较于@import,@use可以为当前路径设置一个别名,像sql中的as一样,不过这里叫做命名空间
//语法:@user "路径" as 别名
@use "../style1/test1" as test1;
@use "../style2/test2" as test2;
.box {
@include test2.color;
}
普通的命名空间,使用时要用命名空间.样式名,使用全局命名空间后,可以直接使用样式名,当然了就和@import一样了,失去了@use的优势了
//语法:@user "路径" as *
@use "../style1/test1" as *;
.box {
@include color;
}
类似于java中的private,私有模块只能在当前scss文件中使用
//语法:$_变量名:变量值
$_rel:black;
.box {
color: $_rel;
}
@forward语句可以引入另一个模块的所有变量、mixins和函数,将它们直接作为当前模块的API暴露出去,不会真的在当前模块增加代码。不同于 @use, @forward不能给变量添加命名空间。@forward类似与servlet中的forward,当我们用@forward引入当前scss文件,就可以直接用该文件中的样式。
通过控制 show和 hide,可以决定模块中的哪些成员对引入后的模板可见。对隐藏的变量,在下游文件中不可以使用,相当于模块私有成员。
@forward "a" show rounded;
@forward "b" hide $radius;
大多数情况下,一个样式库会存在一个入口文件index.scss,然后在index.scss中引入其他的子文件。这种结构类似于一个多合一模块。那么,如果要在某一文件中 @forward多个子模块,就可以使用as -*语句,为子模块下的成员自动带上前缀以区分。
@forward "a" as mixin-*;
@forward "b" as var-*;
@import "c.scss";
.button {
@include mixin-rounded;
padding: $var-radius;
}
@at-root用来跳出多级嵌套,在多级嵌套时比较常用,包含without和with。
.box1 {
.box2 {
.box3 {
color: red;
@at-root .box4 {
font-size: 10px;
}
}
}
}
编译
.box1 .box2 .box3 {
color: red;
}
.box4 {
font-size: 10px;
}
/*# sourceMappingURL=index.css.map */
@use 'sass:扩展模块名‘
```
## 17.2color
>scss包含很多操作颜色的函数。例如lighten()与 darken()可用于调亮或调暗颜色,opacify()使颜色透明度减少,transparent()使颜色透明度增加,mix()用来混合两种颜色。
```js
.p1 {
// 让颜色变亮
color:scale-color(#5c7a29, $lightness: +30%);
}
.p2 {
// 让颜色变暗
color:scale-color(#5c7a29, $lightness: -15%);
}
.p3 {
// 降低颜色透明度
color:scale-color(#5c7a29, $alpha: -40%);
}
```
## 17.3String
>scss有许多处理字符串的函数,比如向字符串添加引号的quote()、获取字符串长度的string-length()和将内容插入字符串给定位置的string-insert()。
```js
p {
&:after {
content: quote(这是里面的内容);
}
background-color: unquote($string: "#F00");
z-index:str-length("scss学习");
}
```
## 17.4Math
>数值函数处理数值计算,例如:percentage()将无单元的数值转换为百分比,round()将数字四舍五入为最接近的整数,min()和max()获取几个数字中的最小值或最大值,random()返回一个随机数。
```js
p {
z-index: abs(-15); // 15
z-index: ceil(5.8); //6
z-index: max(5, 1, 6, 8, 3); //8
opacity: random(); // 随机 0-1
}
```
## 17.5List
>List函数操作List,length()返回列表长度,nth()返回列表中的特定项,join()将两个列表连接在一起,append()在列表末尾添加一个值。
```js
p {
z-index: length(12px); //1
z-index: length(12px 5px 8px); //3
z-index: index(a b c d, c); //3
padding: append(10px 20px, 30px); // 10px 20px 30px
color: nth($list: red blue green, $n: 2); // blue
}
```
## 17.6Map
>Map函数操作Map,map-get()根据键值获取map中的对应值,map-merge()来将两个map合并成一个新的map,map-values()映射中的所有值。
```js
$font-sizes: ("small": 12px, "normal": 18px, "large": 24px);
$padding:(top:10px, right:20px, bottom:10px, left:30px);
p {
font-size: map-get($font-sizes, "normal"); //18px
@if map-has-key($padding, "right") {
padding-right: map-get($padding, "right");
}
&:after {
content: map-keys($font-sizes) + " "+ map-values($padding) + "";
}
}
```
## 17.7Seletor
>选择符相关函数可对选择css进行一些相应的操作,例如:selector-append()可以把一个选择符附加到另一个选择符,selector-unify()将两组选择器合成一个复合选择器。
```js
@use 'sass:selector';
@debug selector.is-superselector("a", "a"); // true
// 可以直接使用@forward下的前缀
@debug selector-append("a", ".disabled"); // a.disabled
@debug selector-extend("a.disabled", "a", ".link"); // a.disabled, .link.disabled
.header {
content: selector-append(".a", ".b", ".c") + '';
content: selector-unify("a", ".disabled") + '';
}
```