SASS(scss)
Scss
1.认识Scss
Sass 支持两种不同的语法,每个都可以加载另一个。
scss其实是Sass
的一种语法。SCSS 语法使用.scss
文件扩展名 。除了一些小的例外,它是CSS的超集,这意味着基本上所有有效的CSS也是有效的SCSS。
scss
示例:
$view-width: 500px;
$base-color: #c6538c;
$border-dark: rgba($base-color, 0.88);
.content {
width: $view-width;
height: 200px;
color: $border-dark;
}
sass原始的语法为缩进语法,使用.sass
作为文件扩展名。习惯将其成为sass语法,缩进语法支持与 SCSS 相同的所有功能,但它使用缩进而不是大括号和分号来描述文档的格式(不好阅读,所以scss比较受欢迎)。
sass
示例:
$view-width: 500px
$base-color: #c6538c
$border-dark: rgba($base-color, 0.88)
.content
width: $view-width;
height: 200px;
color: $border-dark;
Sass 支持标准的 CSS 多行注释
/* */
,以及单行注释//
,前者会 被完整输出到编译后的 CSS 文件中,而后者则不会。
2.嵌套规则
在编写 HTML 时,它有一个清晰的嵌套和可视化层次结构。另一方面,CSS 则没有。
Sass 允许以遵循 HTML 相同视觉层次结构的方式嵌套 CSS 选择器。请注意,过度嵌套的规则将导致过度限定的 CSS,这可能难以维护,并且通常被认为是不好的做法。
nav {
ul {
margin: 0;
padding: 0;
list-style: none;
}
li { display: inline-block; }
a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
}
转换为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;
}
2.1 处理选择器列表
scss样式
:
.alert, .warning {
ul, p {
margin-right: 0;
margin-left: 0;
padding-bottom: 0;
}
}
转换的css
.alert ul, .alert p, .warning ul, .warning p {
margin-right: 0;
margin-left: 0;
padding-bottom: 0;
}
2.2 选择器组合
scss样式
:
ul > {
// 直接子元素
li {
list-style-type: none;
}
}
h2 {
// 兄弟元素
+ p {
border-top: 1px solid gray;
}
}
p {
// p标签之后出现的span元素
~ {
span {
opacity: 0.8;
}
}
}
转换的css
ul > li {
list-style-type: none;
}
h2 + p {
border-top: 1px solid gray;
}
p ~ span {
opacity: 0.8;
}
2.3 父选择器&
父选择器 ,是 Sass 发明的一种特殊选择器,用于嵌套选择器中指代外部选择器。它使得以更复杂的方式重用外部选择器成为可能,例如添加伪类或在父类之前添加选择器。标识符:&
。
.alert {
&:hover {
font-weight: bold;
}
&::before {
content: '';
display: block;
width: 200px;
height: 200px;
background-color: red;
}
}
转换的css
.alert:hover {
font-weight: bold;
}
.alert::before {
content: '';
display: block;
width: 200px;
height: 200px;
background-color: red;
}
2.3.1 添加后缀
可以使用父选择器向外部选择器添加额外的后缀。
.accordion {
margin: 4rem auto;
width: 90%;
background: #f4f4f4;
&__copy {
display: none;
padding: 1rem 1.5rem 2rem 1.5rem;
color: gray;
line-height: 1.6;
font-size: 14px;
font-weight: 500;
&--open {
display: block;
}
}
}
转换的css
.accordion {
margin: 4rem auto;
width: 90%;
background: #f4f4f4;
}
.accordion__copy {
display: none;
padding: 1rem 1.5rem 2rem 1.5rem;
color: gray;
line-height: 1.6;
font-size: 14px;
font-weight: 500;
}
.accordion__copy--open {
display: block;
}
2.4 属性嵌套
有些 CSS 属性遵循相同的命名空间 (namespace),比如 font-family, font-size, font-weight
都以 font
作为属性的命名空间。为了便于管理这样的属性,同时也为了避免了重复输入。
.funky {
font: {
family: fantasy;
size: 30em;
weight: bold;
}
}
// 编译的CSS
.funky {
font-family: fantasy;
font-size: 30em;
font-weight: bold;
}
又如:
nav {
border: {
style: solid;
width: 1px;
color: #ccc;
}
}
// 编译的CSS
nav {
border-style: solid;
border-width: 1px;
border-color: #ccc;
}
2.4.1 命名空间的属性值
命名空间也可以包含自己的属性值:
.funky {
font: 20px/24px {
family: fantasy;
weight: bold;
}
}
// 编译后
.funky {
font: 20px/24px;
font-family: fantasy;
font-weight: bold;
}
2.4.2 缩写后指明例外规则
对于属性的缩写形式,你甚至可以像下边这样来嵌套,指明例外规则
nav {
border: 1px solid #ccc {
left: 0px;
right: 0px;
}
}
// 编译的CSS
nav {
border: 1px solid #ccc;
border-left: 0px;
border-right: 0px;
}
3. 数据类型
Sass支持许多值类型,其中大多数直接来自CSS。每个表达式产生一个值,变量保存值。大多数值类型直接来自CSS:
Numbers
数字,可能有或者没有单位, 像12
、100px
.Strings
字符串,可能有或者没有双引号,像"Helvetica Neue"
、bold
.Colors
颜色,它们可以通过十六进制表示或名称来引用,如#c6538c
或blue
,或从函数返回,如rgb(107, 113, 127)
或hsl(210, 100%, 20%)
.Lists
数组,可以用空格或逗号分隔,可以用方括号括起来,也可以根本不用括号,比如1.5em 1em 0 2em
,Helvetica, Arial, sans-serif
, or[col1-start]
还有一些 Sass特有的:
boolean
布尔型,包括true/false
- 单一实例空值
null
- 值与键的关联
Maps
,如("background": red, "foreground": pink)
- 由get-function()返回并由call()调用的函数引用。
4. 变量
Sass变量很简单:将值赋给以$
开头的名称,然后可以引用该名称而不是值本身。
在声明变量时,变量值也可以引用其他变量。
$base-color: #c6538c;
$border-dark: rgba($base-color, 0.88);
.alert {
border: 1px solid $border-dark;
}
转换的css
.alert {
border: 1px solid rgba(198, 83, 140, 0.88);
}
4.1 作用域
变量支持块级作用域,嵌套规则内定义的变量只能在嵌套规则内使用(局部变量),不在嵌套规则内定义的变量则可在任何地方使用(全局变量)。将局部变量转换为全局变量可以添加 !global
声明:
$variable: 6em;
.content {
$variable: 3em;
$width: 5em !global;
height: $variable;
}
.sidebar {
width: $width;
height: $variable;
}
转换的css
.content {
height: 3em; /* local value */
}
.sidebar {
width: 5em; /* global value */
height: 6em; /* global value */
}
4.2 默认变量值
一般情况下,你反复声明一个变量,只有最后一处声明有效且它会覆盖前边的值。
$link-color: blue;
$link-color: red;
a {
color: $link-color;
}
// 超链接的color会被设置为red。
如果有个需求是当你写了一个可被他人通过@import
导入的sass
库文件,你可能希望导入者可以定制修改sass
库文件中的某些值。那就可以使用sass
的!default
标签实现这个目的。含义是:如果这个变量被声明赋值了,那就用它声明的值,否则就用这个默认值。
$fancybox-width: 400px !default;
.fancybox {
width: $fancybox-width;
}
5. 运算/计算
所有数据类型均支持相等运算 ==
或 !=
,此外,每种数据类型也有其各自支持的运算方式。
圆括号可以用来影响运算的顺序
p {
width: 1em + (2em * 3);
}
// 转换为
p {
width: 7em;
}
5.1 数字运算
sass支持数字的加减乘除、取整等运算 (+, -, *, /, %
),如果必要会在不同单位间转换值。
关系运算 <, >, <=, >=
也可用于数字运算,相等运算 ==, !=
可用于所有数据类型。
div {
$width: 300px;
$height: 100px;
width: $width + $height;
height: $width - $height;
}
// 编译后
div {
width: 400px;
height: 200px;
}
5.1.1 除法运算/
/
在 CSS 中通常起到分隔数字的用途,Sass 作为 CSS 语言的拓展当然也支持这个功能,同时也赋予了 /
除法运算的功能。
以下三种情况 /
将被视为除法运算符号:
- 如果值,或值的一部分,是变量或者函数的返回值
- 如果值被圆括号包裹
- 如果值是算数表达式的一部分
p {
font: 10px/8px; // 纯CSS,不做除法运算
$width: 1000px;
width: $width/2; // 使用变量做除法运算
width: round(1.5)/2; // 利用函数做除法运算
height: (500px/2); // 被括号包括做除法运算
margin-left: 5px + 8px/2px; // 作为+算术表达式的一部分,做除法运算
}
5.1.2 使用计算函数
计算是 Sass 表示
calc()
函数的方式。相似的函数还有如clamp()
、min()
和max()
。
5.1.2.1 calc()
不能将calc
函数计算与普通的 Sass 运算操作一起使用,例如 +
and *
。如果你想写一些允许计算的数学函数,只需将它们写在它们自己的calc()
表达式中。
$width: calc(400px + 10%);
.sidebar {
width: $width;
// $width * 2 // Error!
// calc($width * 2)
padding-left: calc($width / 4);
}
转换的css
.sidebar {
width: calc(400px + 10%);
padding-left: calc($width / 4);
}
5.1.2.1 min()
和max()
$padding: 12px;
$normalSize: 16px;
.post {
padding-left: max($padding, normalSize);
padding-right: max($padding, 10px);
}
.sidebar {
padding-left: max($padding % 10, 20px);
padding-right: max($padding % 10, 20px);
}
转换的css
.post {
padding-left: 16px;
padding-right: 12px;
}
.sidebar {
padding-left: 20px;
padding-right: 20px;
}
5.2 颜色值运算
颜色值的运算是分段计算进行的,也就是分别计算红色,绿色,以及蓝色的值:
p {
color: #010203 + #040506;
}
计算 01 + 04 = 05
、02 + 05 = 07
、03 + 06 = 09
,然后编译为
p {
color: #050709;
}
数字与颜色值之间也可以进行算数运算,同样也是分段计算的
p {
color: #010203 * 2;
}
// 转换为
p {
color: #020406;
}
5.3 字符串运算
+
可用于连接字符串
p {
cursor: e + -resize;
}
// 编译为
p {
cursor: e-resize;
}
注意,如果有引号字符串(位于 +
左侧)连接无引号字符串,运算结果是有引号的,相反,无引号字符串(位于 +
左侧)连接有引号字符串,运算结果则没有引号。
p:before {
content: "Foo " + Bar;
font-family: sans- + "serif";
}
// 编译为
p:before {
content: "Foo Bar";
font-family: sans-serif;
}
运算表达式与其他值连用时,用空格做连接符:
p {
margin: 3px + 4px auto;
}
// 编译为
p {
margin: 7px auto;
}
5.4 布尔运算
Sass 支持布尔型的 and
or
以及 not
运算。分别对应JavaScript中的&&
与、||
或、!
取反
@debug not true; // false
@debug not false; // true
@debug true and true; // true
@debug true and false; // false
@debug true or false; // true
@debug false or false; // false
6. mixin 混合器
当需要大段大段的重用样式的代码,可以通过sass
的mixin
混合器实现大段样式的重用。混合器使用@mixin
标识符定义。
@mixin rounded-corners {
// 添加跨浏览器的圆角边框
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
@mixin no-bullets {
list-style: none;
li {
list-style-image: none;
list-style-type: none;
margin-left: 0px;
}
}
然后就可以在你的样式表中通过@include
来使用这个混合器,放在你希望的任何地方。@include
调用会把混合器中的所有样式提取出来放在@include
被调用的地方。
.notice {
background-color: green;
border: 2px solid #00aa00;
@include rounded-corners;
}
转换的CSS
.notice {
background-color: green;
border: 2px solid #00aa00;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
6.1 给混合器传参
混合器并不一定总得生成相同的样式。可以通过在@include
混合器时给混合器传参,来定制混合器生成的精确样式。当@include
混合器时,参数其实就是可以赋值给css
属性值的变量。
@mixin link-colors($normal, $hover, $visited) {
color: $normal;
&:hover { color: $hover; }
&:visited { color: $visited; }
}
当混合器被@include
时,你可以把它当作一个css
函数来传参。如果你像下边这样写:
a {
@include link-colors(blue, red, green);
}
//Sass最终生成的是:
a { color: blue; }
a:hover { color: red; }
a:visited { color: green; }
6.2 默认参数值
为了在@include
混合器时不必传入所有的参数,我们可以给参数指定一个默认值。参数默认值使用$name: default-value
的声明形式,默认值可以是任何有效的css
属性值,甚至是其他参数的引用。
@mixin link-colors(
$normal,
$hover: $normal,
$visited: $normal
)
{
color: $normal;
&:hover { color: $hover; }
&:visited { color: $visited; }
}
使用:
a {
// $hover和$visited也会被自动赋值为red。
@include link-colors(red)
}
7. 插值语句#{}
插值总是返回一个不带引号的字符串
几乎可以在 Sass 样式表的任何地方使用插值,将Sass 表达式的结果嵌入到 CSS 块中。
@mixin corner-icon($name, $top-or-bottom, $left-or-right) {
.icon-#{$name} {
background-image: url("/icons/#{$name}.svg");
position: absolute;
#{$top-or-bottom}: 0;
#{$left-or-right}: 0;
}
}
@include corner-icon("mail", top, left);
转换的CSS
.icon-mail {
background-image: url("/icons/mail.svg");
position: absolute;
top: 0;
left: 0;
}
7.1 避免/
运算
#{}
插值语句也可以在属性值中插入,大多数情况下,这样可能还不如使用变量方便,但是使用 #{}
可以避免 Sass 运行运算表达式,直接编译 CSS。
p {
$font-size: 12px;
$line-height: 30px;
font: #{$font-size}/#{$line-height};
}
// 编译为
p {
font: 12px/30px;
}
7.2 在注释中使用
插值语句 也可写进多行注释中输出变量值:
$version: "1.2.3";
/* This CSS is generated by xxx version #{$version}. */
编译为:
/* This CSS is generated by xxx version 1.2.3. */
7.3 在文本字符串中使用
在有引号的文本字符串中使用 #{}
插值语句可以添加动态的值:
p:before {
content: "I am #{5 + 10} years old!";
}
// 编译为
p:before {
content: "I am 15 years old!";
}
空的值被视作插入了空字符串:
$value: null;
p:before {
content: "I ate #{$value} pies!";
}
// 编译为
p:before {
content: "I ate pies!";
}