Sass 进阶
控制命令
@if
@if指令是一个SassScript, 它可以根据条件来处理样式块, 如果条件为true返回一个样式块, 反之false返回另一个样式块
在Sass中除了@if之外, 还可以配合@else if和@else一起使用
假设要控制一个元素隐藏或显示, 我们就可以定义一个混合宏, 通过
@if...@else...来判断进行参数的值来控制display的值
// SCSS 代码
@mixin blockOrHidden($boolean: true) {
@if $boolean {
@debug "$boolean is #{$boolean}"
display: block;
} @else {
@debug "$boolean is #{$boolean}"
display: none;
}
}
.block {
@include blockOrHidden;
}
.hidden {
@include blockOrHidden(false);
}
// 编译的 CSS
.block {
display: block;
}
.hidden {
display: none;
}@for
理解
在制作网格系统的时候, 应该对.col1~col12这样的印象较深
在CSS中你需要一个一个去书写, 但在Sass中, 可以使用@for循环来完成
在Sass的@for循环中有两种方式:
@for $i from <start> through <end>
@for $i from <start> to <end>$i表示变量start表示起始值end表示结束值
区别:
through表示包括end这个数
// SCSS 代码
@for $i from 1 through 3 {
.item-#{$i} { width: 2em * $i; }
}
// 编译的 CSS
.item-1 { width: 2em; }
.item-2 { width: 4em; }
.item-3 { width: 6em; }to表示不包括end这个数
// SCSS 代码
@for $i from 1 to 3 {
.item-#{$i} { width: 2em * $i; }
}
// 编译的 CSS
.item-1 { width: 2em; }
.item-2 { width: 4em; }应用实例
@for应用在网格系统生成各个格子class:
// SCSS 代码
$grid-prefix: span !default;
$grid-width: 60px !default;
$grid-gutter: 20px !default;
%grid {
float: left;
margin-left: $grid-gutter / 2;
margin-right: $grid-gutter / 2;
}
@for $i from through 6 {
.#{$grid-prefix}#{$i} {
width: $grid-width * $i + $grid-gutter * ($i - 1);
@extend %grid;
}
}
// 编译的 CSS
.span1, .span2, .span3, .span4, .span5, .span6 {
float: left;
margin-left: 10px;
margin-right: 10px;
}
.span1 {
width: 60px;
}
.span2 {
width: 140px;
}
.span3 {
width: 220px;
}
.span4 {
width: 300px;
}
.span5 {
width: 380px;
}
.span6 {
width: 460px;
}@while
@while指令也需要SassScript表达式, 并且会生成不同的样式代码块, 直到表达式值为false时停止循环
@while和@for指令很相似, 只要@while后面的条件为true就会执行
// SCSS 代码
$types: 4;
$type-width: 20px;
@while $types > 0 {
.while-#{$types} {
width: $type-width + $types;
}
$types: $types - 1;
}
// 编译的 CSS
.while-4 { width: 24px; }
.while-3 { width: 23px; }
.while-2 { width: 22px; }
.while-1 { width: 21px; }@each
@each循环就是去遍历一个列表, 然后从列表中取出对应的值
@each循环指令的形式:
@each $var in <list>$var表示一个变量名, <list>表示一个SassScript表达式, 它将返回一个列表值, 变量$var会在列表中做遍历, 并且遍历出与$var对应的样式块
- 示例:
// SCSS 代码
$list: adam john wynn mason kuroir;
@mixin author-images {
@each $author in $list {
.photo-#{$author} {
background: url("/images/#{$author}.png") no-repeat;
}
}
}
.author-bio {
@include author-images;
}
// 编译的 CSS
.author-bio .photo-adam { background: url("/images/avatars/adam.png") no-repeat; }
.author-bio .photo-john { background: url("/images/avatars/john.png") no-repeat; }
.author-bio .photo-wynn { background: url("/images/avatars/wynn.png") no-repeat; }
.author-bio .photo-mason { background: url("/images/avatars/mason.png") no-repeat; }
.author-bio .photo-kuroir { background: url("/images/avatars/kuroir.png") no-repeat; }函数
在Sass中除了可以定义变量, 具有@extend、%placeholder和mixins等特性外, 还自备了一系列的函数功能:
- 字符串函数
- 数字函数
- 列表函数
- 颜色函数
Introspection函数- 三元函数等
除了自备的函数功能之外, 我们还可以根据自己的需求定义函数功能, 常常称之为自定义函数
字符串函数
用来处理字符串的函数
unquote($string): 删除字符串中的引号quote($string): 给字符串添加引号to-upper-case(): 将字符串小写字母转换成大写字母to-lower-case(): 将字符串大写字母转换成小学字母
unquote
用来删除一个字符串中的引号, 如果这个字符串没有带引号, 将返回原生的字符串
- 只能删除字符串最前面的和最后面的引号, 无法删除字符串中间的引号
- 字符串没有带引号将返回字符串本身
// SCSS 代码
.test1 {
content: unquote('Hello Sass!');
}
.test2 {
content: unquote("'Hello Sass!'");
}
.test3 {
content: unquote('"Hello Sass!"');
}
.test4 {
content: unquote("I'm Web Designer");
}
.test5 {
content: unquote(Hello Sass!);
}
// 编译的 CSS
.test1 {
content: Hello Sass!;
}
.test2 {
content: 'Hello Sass!';
}
.test3 {
content: "Hello Sass!";
}
.test4 {
content: I'm Web Designer;
}
.test5 {
content: Hello Sass!;
}quote
与unquote()函数功能相反, 主要用来给字符串添加引号
如果字符串自身带有引号会统一换成双引号""
// SCSS 代码
.test1 {
content: quote('Hello Sass!');
}
.test2 {
content: quote("Hello Sass!");
}
.test3 {
content: quote(Hello);
}
.test4 {
content: quote(' ');
}
// 编译的 CSS
.test1 {
content: "Hello Sass!";
}
.test2 {
content: "Hello Sass!";
}
.test3 {
content: "Hello";
}
.test4 {
content: "";
}注意
使用quote()函数只能给字符串增加双引号, 而且字符串中间有单引号、特殊符号或者空格时, 需要用单引号或者双引号括起, 否则编译的时候将会报错
.test1 {
content: quote(Hello Sass);
}
// error style.scss (Line 13: $string: ("Hello""Sass") is not a string for `quote')to-upper-case
将字符串小写字母转换成大写字母
// SCSS 代码
.test {
text: to-upper-case(aaa);
text: to-upper-case(a-Aa-aAa);
}
// 编译的 CSS
.test {
text: AAA;
text: A-AA-AAA;
}to-lower-case
将字符串转换成小写字母
// SCSS 代码
.test {
text: to-lower-case(AAA);
text: to-lower-case(A-Aa-AaA);
}
// 编译的 CSS
.test {
text: aaa;
text: a-aa-aaa;
}数字函数
Sass中的数字函数主要针对数字方面提供一系列的函数功能
percentage($value): 将一个不带单位的数转换成百分比值round($value): 将数值四舍五入, 转换成一个最接近的整数ceil($value): 向上取整floor($value): 向下取整abs($value): 返回一个数的绝对值min($num...): 几个数值中取最小值max($num...): 几个数值中取最大值random(): 获取随机数
percentage
将一个不带单位的数字转换成百分比的形式
percentage(.2) // 20%
percentage(2px / 10px) // 20%
percentage(2em / 10em) // 20%
percentage(2em / 10px) // 报错
// SCSS 代码
.footer {
width: percentage(.2);
}
// 编译的 CSS
.footer {
width: 20%;
}round
将一个数四舍五入为一个最接近的整数
可以携带单位的任何数值
round(12.3) // 12
round(2px / 3px) // 1
round(3px / 2em) // 2px/em
// SCSS 代码
.footer {
width: round(12.3px);
}
// 编译的 CSS
.footer {
width: 12px;
}ceil
将一个数向上取整
ceil(2.0) // 2
ceil(2.1) // 3
// SCSS 代码
.footer {
width: ceil(12.3px);
}
// 编译的 CSS
.footer {
width: 13px;
}floor
向下取整
floor(2.1) // 2
floor(2.9) // 2
// SCSS 代码
.footer {
width: floor(12.3px);
}
// 编译的 CSS
.footer {
width: 12px;
}abs
返回一个数的绝对值
abs(-10) // 10
abs(-1px) // 1px
// SCSS 代码
.footer {
width: abs(-12.3px);
}
// 编译的 CSS
.footer {
width: 12.3px;
}min/max
min()函数: 在多个数之中找到一个最小值
max()函数: 在多个数值中找到一个最大值
- 可设置任意多个参数
- 函数中同时出来两种不同类型的单位将会报错
// min
min(1, 2, 12px, 10, 30px) // 1
// max
max(1%, 100, 66%, 10, 3) // 100random
获取一个随机数
random() // 0.56231列表函数
列表函数主要包括一些对列表参数的函数使用, 分为:
length($list): 返回一个列表的长度值nth($list, $n): 返回一个列表中指定的某个标签值join($list1, $list2, [$separator]): 将两个列连接在一起, 变成一个列表append($list1, $val, [$separator]): 将某个值放在列表的最后zip($lists...): 将几个列表结合成一个多维的列表index($list, $value): 返回一个值在列表中的位置值
length
length()函数主要用来返回一个列表中有几个值
注意
函数中的列表参数直接使用空格隔开, 不能使用逗号
length(10px) // 1
length(10px 20px (border 1px solid) 2em) // 4nth
nth()函数用来指定列表中某个位置的值
不过在Sass中, nth()函数和其他语言不同, 列表中第一个标签值是从1开始, 以此类推
语法: nth($list, $n)
注意
$n必须是大于0的整数
nth(10px 20px 30px, 1) // 10px
nth((A, B, C), 2) // Bjoin
join()函数是将两个列表连接合并成一个列表
注意
只能将两个列表连接成一个列表, 两个以上将会报错
join(10px 20px, 30px 40px) // (10px 20px 30px 40px)
join((blue,red), (#abc #def)) // (#0000ff, #ff0000, #aabbcc, #ddeeff)- 需要连接多个列表时可将多个
join()函数合并在一起使用
join((blue, red), join((#abc #def), (#dee, #eff)))join()中可设置$separator参数, 用来给列表函数设置分隔符号, 默认值是auto, 可设置comma(逗号)和space(空格)
join(blue, red, comma) // (#0000ff, #ff0000)注意
不设置$separator参数, 会有多种情况发生:
- 如果第一个列表中每个值直接使用的是逗号分隔, 那么
join()函数合并的列表中使用逗号分隔 - 如果第一个列表中只有一个列表项, 那么
join()函数合并的列表分隔符会根据第二个列表项的分隔符分隔 - 当两个列表项都只有一位时, 使用空格分隔
append
append()函数是用来将某个值插入到列表中, 并且处于最末位
可设置$separator参数:
comma以逗号分隔列表项space以空格分隔列表项
append(10px 20px, 30px) // (10px, 20px, 30px)
append((10px, 20px), 30px) // (10px, 20px, 30px)
append(green, red) // (#008000 #ff0000)
append(red, (green, blue)) // (#ff0000 (#008000, #0000ff))
append((blue, green), red, comma) // (#0000ff, #008000, #ff0000)
append((blue, green), red, space) // (#0000ff #008000 #ff0000)没有明确指定$sepatator参数值, 其默认值是auto
- 如果列表只有一个列表项时, 那么插入进来的值将和原来的值会以空格的方式分隔
- 如果列表中列表项时以空格分隔列表项, 那么插入进来的列表项也将已空格分隔
- 如果列表中列表项是以逗号分隔, 那么插入进来的列表项也将以逗号分隔
zip
zip()函数将多个列表值转成一个多维的列表
- 在使用
zip()函数时, 每个单一的列表个数值必须是相同的 zip()函数中每个单一列表的值对应的取其相同位置值
zip(1px 2px 3px, solid, dashed, dotted, green, blue, red)
// ((1px "solid" #008000), (2px "dashed" #0000ff), (3px "dotted", #ff0000))index
index()函数类似于索引一样, 主要让你找到某个值在列表中所处的位置
在Sass中, 第一个值就是1, 第二个值就是2, 以此类推
如果指定的值不在列表中, 那么返回的值将是false
index(1px solid red, 1px) // 1
index(1px solid red, solid) // 2
index(1px solid red, red) // 3
index(1px solid red, blue) // falseIntrospection函数
Introspection函数包括了几个判断型函数:
type-of($value): 返回一个值的类型unit($number): 返回一个值的单位unitless($number): 判断一个值是否带有单位comparable($number-1, $number-2): 判断连个值是否可以做加、减和合并
type-of
type-of()函数主要用来判断一个值是属于什么类型
number为数值型string为字符串型bool为布尔型color为颜色型
type-of(100) // "number"
type-of(100px) // "number"
type-of("asdf") // "string"
type-of(asdf) // "string"
type-of(true) // "bool"
type-of(#fff) // "color"
type-of(blue) // "color"unit
unit()函数主要是用来获取一个值所使用的单位, 碰到复杂的计算时, 其能根据运算得到一个"多单位组合"的值, 不过只允许乘/除运算
unit(100) // ""
unit(100px) // "px"
unit(20%) // "%"
unit(1em) // "em"
unit(10px * 3em) // "px*em"
unit(10px / 3em) // "px/em"
unit(10px * 2em / 3cm / 1rem) // "em/rem"- 加/减碰到不同单位时,
unit()函数将会报错, 除px/cm/mm运算之外
unit(1px + 1cm) // "px"
unit(1px - 1cm) // "px"
unit(1px + 1mm) // "px"
unit(10px * 2em - 3cm / 1rem) // SyntaxError: Incompatible units: 'cm' and 'px*em'.unit()函数对于单位运算相对来说也是没有规律, 而且有些单位无法整合成一个单位, 对于我们在CSS中运用中并不合适
unit(10px * 3em) // "em*px"
unit(10px / 3em) // "px/em"
unit(10px * 2em / 3cm / 1rem) // "em/rem"
// 以上运算出来的单位, 对于在 CSS 中使用将是没有任何意义的unitless
unitless相对来说简单明了, 只是用来判断一个值是否带有单位, 如果不带单位返回的值为true, 带单位返回的值为false
unitless(100) // true
unitless(100px) // false
unitless(100em) // false
unitless(100%) // false
unitless(1 / 2) // true
unitless(1 / 2 + 2) // true
unitless(1px / 2 + 2) // false
@mixin adjust-location($x, $y) {
@if unitless($x) {
$x: $x * 1px;
}
@if unitless($y) {
$y: $y * 1px;
}
position: relative;
left: $x;
top: $y;
}
.button {
@include adjust-location(20px, 30);
}comparable
comparable()函数主要用来判断两个数是否可以进行加/减/合并, 如果可以返回true, 否则返回false
comparable(2px, 1px) // true
comparable(2px, 1%) // false
comparable(2px, 1em) // falseMiscellaneous函数
Miscellaneous函数称为三元条件函数, 主要因为和JavaScript中的三元判断非常的相似, 它有两个值, 当条件不成立时返回另一种值
if($condition, $if-true, $if-false)
// 当 $condition 成立时, 返回的值为 $if-true, 否则返回的是 $if-false 值
if(true, 1px, 2px) // 1px
if(false, 1px, 2px) // 2pxMap函数
Sass的map常常被称为数据地图, 也有人称其为数组, 因为是以key: value成对出现的, 但其更像是一个JSON数据
JavaScript JSON数据:
{
"employees": [
{ "firstName": "John", "lastName": "Doe" },
{ "firstName": "Anna", "lastName": "Smith" },
{ "firstName": "Peter", "lastName": "Jones" }
]
}Sass map数据:
首先有一个类似于
Sass的变量一样, 用个$加上命名空间来声明map, 后面紧接是一个小括号(), 将数据以key: value的形式赋予, 其中key和value是成对出现的, 并且每对之间使用逗号分隔
$map: (
$key1: value1,
$key2: value2,
$key3: value3
);- 其中键
key是用来查找相关联的值value, 使用map可以很容易收集键的值和动态插入
// Sass 中常用这种方式定义变量:
$default-color: #fff !default;
$primary-color: #22ae39 !default;
// 使用 map 可以更好的管理:
$color: (
default: #fff,
primary: #22ae39,
negative: #d9534f
);- 还可以让
map嵌套map
$map: (
key1: value1,
key2: (
key2-1: value2-1,
key2-2: value2-2
),
key3: value3
);
$theme-color: (
default: (
bgcolor: #fff,
text-color: #444,
link-color: #39f
),
primary:(
bgcolor: #000,
text-color:#fff,
link-color: #93f
),
negative: (
bgcolor: #f36,
text-color: #fefefe,
link-color: #d4e
)
);
// 一些 map 老教程中会有这种格式:
$map: (
key1 value1,
key2 value2,
key3 value3
);
// 可以正常编译但不建议使用除了使用map来管理变量, 还使用map函数来获取变量, 或者对map做更多有意义的操作
map-get($map, $key): 根据给定的key值, 返回map中相关的值map-merge($map1, $map2): 将两个map合并成一个新的mapmap-remove($map, $key): 从map中删除一个key, 返回一个新mapmap-keys($map): 返回map中所有的keymap-values($map): 返回map中所有的valuemap-has-key($map, $key): 根据给定的key值判断map是否有对应的value值, 如果有返回true, 否则返回falsekeywords($args): 返回一个函数的参数, 这个参数可以动态的设置key和value
map-get
map-get($map, $key)函数的作用是根据$key参数, 返回$key在$map中对应的value值
如果$key不存在$map中, 将返回null值, 此函数包括两个参数:
$map: 定义好的map$key: 需要遍历的key示例: 假定一个 $colors 的 map
// SCSS 代码: 假定一个 $colors 的 map
$colors: (
c1: #ea4c89,
c2: #3b5998,
c3: #171515,
c4: #db4437,
c5: #55acee
);
// 获取 c3 键值对应的值 #171515 就可以通过 map-get() 函数实现:
.btn1 {
color: map-get($colors, c3);
}
// 编译的 CSS:
.btn1 {
color: #171515;
}
// SCSS 代码: 假设要在 $colors 这个 map 上取没有的键值
.btn2 {
font-size: 12px;
color: map-get($colors, c6);
}
// 编译的 CSS:
.btn2 {
font-size: 12px;
}由此示例的知, 如果$key不在$map中, 便不会编译CSS, 但其实在Sass返回一个null值, 如有特殊情况可定义函数加个判断
map-has-key
map-has-key($map, $key)函数将返回一个布尔值, 当$map中有这个$key返回true, 否则返回false
在map-get($map, $key)函数中, 当$key不在$map中时将返回一个null值, 但对于开发人员, 并看不到任何提示信息
如果使用map-has-key($map, $key)函数就可以改变这一状态, 如:
// SCSS 代码
$colors: (...);
@if map-has-key($colors, c3) {
.btn {
color: map-get($colors, c3);
}
} @else {
@warn "No color found for faceboo in $social-colors map. Property ommitted.";
}
// 编译的 CSS
.btn {
color: #171515;
}
// 如果没有便会执行 @else- 将上例简单封装一下:
// 封装函数
@function getColor($c) {
@if not map-has-key($colors, $c) {
@warn "No color found for faceboo in $social-colors map. Property ommitted.";
}
@return map-get($colors, $c);
}
// 调用
.btn1 {
color: getColor(c1);
}
.btn2 {
color: getColor(c2);
}map-keys
map-keys($map)函数将返回$map中所有的key, 这些值赋予给一个值, 就是一个列表
$colors: (
c1: #ea4c89,
c2: #3b5998,
c3: #171515,
c4: #db4437,
c5: #55acee
);
$list: map-key($colors);
// $list: c1, c2, c3, c4, c5;- 可以配合
Sass的list做很多事情, 如获取颜色的示例:
// 封装
@function getColor($c) {
$names: map-get($colors);
@if not index($names, $c) {
@warn "Waring: `#{$c} is not a valid color name.`";
}
@return map-get($colors, $c);
}
// 调用
.btn {
color: getColor(c2);
}
// @each
@each $name in map-keys($colors) {
.btn-#{$name} {
color: getColor($name);
}
}
// @for
@for $i from 1 through length(map-get($colors)) {
.btn-#{nth(map-keys($colors), $i)} {
color: getColor(nth(map-keys($colors), $i));
}
}
// 编译的 CSS
.btn-c1 {
color: #ea4c89;
}
.btn-c2 {
color: #3b5998;
}
.btn-c3 {
color: #171515;
}
.btn-c4 {
color: #db4437;
}
.btn-c5 {
color: #55acee;
}map-values
map-values($map)函数类似于map-keys($map)函数的功能, 不同的是map-values($map)是$map中所有value值取出来, 也是一个列表
map-values($map)中如果有相同的值, 也将会全部取出来
$colors: (...);
$list: map-value($colors);
// $list: #ea4c89, #3b5998, #171515, #db4437, #55acee 值与值之间同样使用逗号分隔map-merge
map-merge($map1, $map2)函数是将$map1和$map2合并, 然后得到一个新的$map, 如果要快速将新的值插入到$map中, 可以使用此方法
如果$map1与$map2有相同的key, 那么$map2中的key会取代$map1中的key
$colors: (
text: #f36,
link: #f63,
border: #ddd,
background: #fff
);
$typo: (
font-size: 12px,
line-height: 1.6,
background: #000
);
$newmap: map-merge($colors, $typo);
// 将会生成一个新map:
$newmap: (
text: #f36,
link: #f63,
border: #ddd,
font-size: 12px,
line-height: 1.6,
background: #000
);map-remove
map-remove($map, $key)函数是删除$map中某一个$key值, 返回一个新的map
若删除的key并不存在$map中, 那么返回的map与之前的一样
$colors: (
c1: #ea4c89,
c2: #3b5998,
c3: #171515,
c4: #db4437,
c5: #55acee
);
$map: map-remove($colors, c2);
// 得到一个新map:
$map: (
c1: #ea4c89,
c3: #171515,
c4: #db4437,
c5: #55acee
);keywords
keywords($arg)函数可以动态创建map, 可以通过混合宏或者函数的参数创建map
参数需要成对出现, $args变成key(会自动去掉$符号), 而$args对应的值就是value
@mixin map($args...) {
@debug keywords($args);
}
@include map(
$dribble: #ea4c89,
$facebook: #3b5998,
$github: #171515,
$google: #db4437,
$twitter: #55acee
);
// 在命令终端可以看到输出的@debug信息:
// DEBUG: (dribble: #ea4c89, facebook: #3b5998, github: #171515, google: #db4437, twitter: #55acee)颜色函数
在Sass的官方文档中, 列出了Sass的颜色函数清单, 常用的主要分为RGB, HSL和Opcity三大函数
RGB
RGB颜色只是颜色的一种表达式, 分别代表Red、Green和Blue
在Sass中RGB颜色提供六种函数:
rgb($red, $green, $blue): 根据红、绿、蓝三个值创建一个颜色rgba($red, $green, $blue, $alpha): 根据红、绿、蓝和透明度值创建一个颜色red($color): 获取一个颜色中的红色值green($color): 获取一个颜色中的绿色值blue($color): 获取一个颜色中的蓝色值mix($color1, $color2, [$weight]): 把两种颜色混合在一起
RGBA
rgba()函数主要用来将一个颜色根据透明度转换成rgba颜色
语法有两种格式:
rgba($red, $green, $blue, $alpha): 将一个rgba颜色转译出来rgba($color, $alpha): 将一个Hex颜色转换成rgba颜色
其中rgba($color, $alpha)函数作用更大, 假如在实际开发中有一个f36或者red颜色值, 给颜色设置透明度时需要分别拿到它的R、G、B值, 而不能直接使用, 这时候便可使用rgba($color, $alpha)函数来处理
// CSS 代码
color: rgba(#f36, .5); // 在 CSS 中是无效写法
// SCSS 代码
$color: #f36;
.rgba {
color: rgba($color, .5);
}Red/Green/Blue
red($color)、green($color)和blue($color)这三个函数非常简单, 用来获取一个颜色中的值是多少
$color: #f36;
red($color); // 255
green($color); // 51
blue($color); // 102Mix
mix($color1, $color2, $weight)是将两种颜色根据一定的比例混合在一起, 生成另一种颜色
$color1和$color2是需要合并的颜色, 可以是任何表达式或者变量$weight是合并的比例, 根据每个RBG的百分比来衡量, 默认值是50%, 意味着两个颜色各占一半, 如果指定是25%, 这意味着第一个颜色比例为25%, 第二个颜色为75%
mix(#f00, #00f); // #7f007f
mix(#f00, #00f, 25%); // #3f00bf
mix(rgba(255, 0, 0, .5), #00f); // rgba(63, 0, 191, .75)HSL
在Sass中提供了一系列有关于HSL的颜色函数, 其中常用的有:
hsl($hue, $saturation, $lightness): 通过色相($hue)、饱和度($saturation)和亮度($lightness)的值创建一个颜色hsla($hue, $saturation, $lightness, $alpha): 通过色相($hue)、饱和度($saturation)、亮度($lightness)和透明度($alpha)的值创建一个颜色hue($color): 从一个颜色中获取色相(hue)值saturation($color): 从一个颜色中获取饱和度(saturation)值lightness($color): 从一个颜色中获取亮度(lightness)值adjust-hue($color, $degress): 改变一个颜色的色相值, 创建一个新颜色lighten($color, $amount): 改变一个颜色的亮度值, 让颜色变亮, 创建一个新颜色darken($color, $amount): 改变一个颜色的亮度值, 让颜色变暗, 创建一个新颜色saturate($color, $amount): 改变一个颜色的饱和度, 让颜色饱和度增加, 创建一个新颜色desaturate($color, $amount): 改变一个颜色的饱和度, 让颜色饱和度减少, 创建一个新颜色grayscale($color): 将一个颜色变成灰色, 相当于desaturate($color, 180deg)complement($color): 返回一个补充色, 相当于对adjust-hue($color, 180deg)invert($color): 返回一个反相色, 红、绿、蓝色值倒过来, 而透明度不变
在HSL函数中, hsl()和hsla()函数主要是通过颜色的H、S和L或者A几个参数获取一个rgb或rgba表达的颜色, 这两个函数与CSS中的无太大区别, 只是使用这两个函数能帮助你知道颜色的十六进制表达式和rgba表达式
而hue()、saturation()和lightness()函数主要是用来获取指定颜色中的色相值、饱和度和亮度值, 对于颜色表达没有太多的实际作用
HSL函数中lightness()、darken()、saturate()、desaturate()、grayscale()、complement()和invert()几个函数是最常见的
lighten
lighten($color, $amount)是围绕颜色的亮度值做调整的, 会让颜色变得更亮, 亮度值在0~1之间, 常用3%~20%之间
$baseColor: #ad141e;
// SCSS 代码
.lighten {
background: lighten($baseColor, 10%);
}
// 编译的 CSS
.lighten {
background: #db1926;
}darken
darken($color, $amount)是围绕颜色的亮度值进行调整的, 会让颜色变得更暗, 亮度值在0~1之间, 常用3%~20%之间
$baseColor: #ad141e;
// SCSS 代码
.darken {
color: darken($baseColor, 10%);
}
// 编译的 CSS
.darken {
color: #7f0f16;
}总结
lighten()和darken()函数只是在原始颜色的基础上对亮度值进行运算操作, 但是生成出来的新颜色在色相和饱和度上会有略微的变化
不管什么颜色, 当其亮度值趋近于0时, 颜色会越来越暗, 直到变成黑色;反之趋近于100%时, 颜色会越来越亮, 直到变成白色
saturate / desaturate
saturate()、desaturate()是通过改变颜色的饱和度来得到一个新的颜色, 当饱和度超过100%时按100%计算
$bg: #ad141e;
.saturate {
background: saturate($bg, 30%); // 在原色饱和度基础上增加饱和度
}
.desaturate {
background: desaturate($bg, 39%); // 在原色饱和度基础上减少饱和度
}adjust-hue
adjust-hue()是通过调整颜色的色相换算出一个新颜色, 它需要一个颜色和色相度数值
度数值通常在-360deg ~ 360deg之间, 也可以使用百分比
$bg: #ad141e;
.adjust-hue-deg {
color: adjust-hue($bg, 30deg);
}
.adjust-hue-per {
color: adjust-hue($bg, 30%);
}grayscale
grayscale()函数会将颜色的饱和度值直接调至0%, 所以此函数与desaturate($color, 100%)的功能是一样的
一般这个函数能将彩色转换成不同程度的灰色, 处理过的颜色最大特征就是颜色的饱和度为0
$bg: #ad141e;
.grayscale {
background: grayscale($bg);
}
.desaturate {
background: desaturate($bg, 100%);
}Opacity
在CSS中除了可以使用rgba、hsla、和transform来控制颜色透明度之外, 还可以使用opacity来控制, 只不过前者只是针对颜色上的透明通道处理, 而opacity是控制整个元素的透明度
在SCSS中也提供了系列透明函数, 主要用来处理颜色的透明度
alpha($color) / opacity($color): 获取颜色透明度值rgba($color, $alpha): 改变颜色的透明度值opacify($color, $amount) / fade-in($color, $amount): 使颜色更不透明transpatentize($color, $amount) / fade-out($color, $amount): 使颜色更加透明
@ 规则
Sass支持CSS3的@规则以及一些Sass专属的规则, 也被称为“指令(directive)”, 这些规则在Sass中具有不同的功效
@import
Sass扩展了CSS的@import规则, 让它能够引入SCSS和CSS文件
所有引入的SCSS和Sass文件都会被合并并输出到一个单一的CSS文件, 被导入的文件中所定义的变量或者mixins都可以在主文件中使用
Sass会在当前目录下寻找其他Sass文件, 如果是Rack、Rails或Merb环境中则是Sass文件目录
也可以通过:load_paths选项或者在命令行中使用--load-path选项来指定额外的搜索目录
@import根据文件名引入
默认情况下, 它会寻找Sass文件并直接引入, 但是在一下几种情况下, 它会编译成CSS的@import规则:
- 如果文件的扩展名是
.css - 如果文件名是以
http://开头 - 如果文件名是
url() - 如果
@import包含了任何媒体查询media queries
如果上述情况都没有出现, 并且扩展名是.scss或.sass, 该名称的Sass或Scss文件就会被引入
如果没有扩展名, Sass将试着找出具有.sass或.scss扩展名的同名文件并将其引入, 如:
@import "foo.scss";@import "foo";
两者都将引入foo.scss文件
// 此情况下编译为 CSS 不变
@import "foo.css";
@import "foo" screen;
@import "http://foo.com/bar";
@import url(foo);- 使用
@import引入多个文件:
@import "rounded-corners", "text-shadow";假如你有一个SCSS或Sass文件需要引入, 但是你又不希望它被编译为一个CSS文件, 可以在文件名前加一个_下划线, 将告诉Sass不要编译成CSS文件, 就能避免被编译, 可以像往常一样引入这个文件, 而且可以省略文件名前面的_下划线
假如有个文件叫做_color.scss, 这样就不会编译生成_color.css文件;而且引入不需要加下划线:
@import "_color.scss";注意
在同一目录下不能同时存在带下划线和不带下划线的同名文件
嵌套
@import除了在顶层文件中使用
@import引入文件, 还可以把它们包含在CSS规则和@media规则中:
// example.scss 文件
.example {
color: red;
}
// 引用
#main {
@import "example";
}
// 编译的 CSS
#main .example {
color: red;
}@media
Sass中的@media指令和CSS的使用规则一样, 但它有另外的功能, 可以嵌套在CSS规则中
有点类似JS的冒泡功能, 如果在样式中使用@media指令, 它将冒泡到外面
- 示例:
// SCSS 代码
.sidebar {
width: 300px;
@media screen and (orientation: landspace) {
width: 500px;
}
}
// 编译的 CSS
.sidebar {
width: 300px;
}
@media screen and (orientation: landspace) {
.sidebar {
width: 500px;
}
}@media可以嵌套@media:
// SCSS 代码
@media screen {
.sidebar {
@media (orientation: landspace) {
width: 500px;
}
}
}
// 编译的 CSS
@media screen and (orientation: landspace) {
.sidebar {
width: 500px;
}
}@media可以使用插件#{}:
// SCSS 代码
$media: screen;
$feature: -webkit-min-device-pixel-ratio;
$value: 1.5;
@media #{$media} and ($feature: $value) {
.sidebar {
width: 500px;
}
}
// 编译的 CSS
@media screen and (-webkit-min-device-pixel-ratio: 1.5) {
.sidebar {
width: 500px;
}
}@extend
SCSS中的@extend是用来扩展选择器或占位符的, 可理解为继承
// SCSS 代码
.error {
border: 1px #f00;
background-color: #fdd;
}
.error .intrusion {
background-image: url("/image/bg.png");
}
.seriousError {
@extend .error;
border-width: 3px;
}
// 编译的 CSS
.error, .seriousError {
border: 1px #f00;
background-color: #fdd;
}
.error .intrusion, .seriousError .intrusion {
background-image: url("/image/bg.png");
}
.seriousError {
border-width: 3px;
}扩展选择器
@extend不止扩展类选择器, 还可以扩展任何选择器
// SCSS 代码
.hoverlink {
@extend a:hover;
}
a:hover {
text-decoration: underline;
}
// 编译的 CSS
a:hover, .hoverlink {
text-decoration: underline;
}- 复杂型:
// SCSS 代码
.hoverlink {
@extend a:hover;
}
.comment a.user:hover {
font-weight: bold;
}
// 编译的 CSS
.comment a.user:hover, .comment .user.hoverlink {
font-weight: bold;
}多个扩展
假如某个样式要继承多个地方的样式, 那么可以使用
@extend来继承多个选择器或占位符的样式
// SCSS 代码
.error {
border: 1px #f00;
background-color: #fdd;
}
.attention {
font-size: 3em;
background-color: #ff0;
}
.seriousErroe {
@extend .error;
@extend .attention;
border-width: 3px;
}
// 编译的 CSS
.error, .seriousError {
border: 1px #f00;
background-color: #fdd;
}
.attention, .seriousError {
font-size: 3em;
background-color: #ff0;
}
.seriousError {
border-width: 3px;
}扩展单一选择器
%placeholder不使用@extend显示调用是不会生成任何样式代码的, 在选择器中使用占位符也一样
// SCSS 代码
// 这段代码在不调用之前不产生任何代码, 只有 @extend 调用之后才生成代码
#context a%extreme {
color: blue;
font-weight: bold;
font-size: 2em;
}
// 调用
.notice {
@extend %extreme;
}
// 编译的 CSS
#context a.notice {
color: blue;
font-weight: bold;
font-size: 2em;
}@at-root
@at-root跳出根元素
当选择器嵌套多层之后, 想让某个选择器跳出嵌套就可以使用@at-root
// SCSS
.a {
color: red;
.b {
color: orange;
.c {
color: yellow;
@at-root .d {
color: green;
}
}
}
}
// 编译后的 CSS
.a {
color: red;
}
.a .b {
color: orange;
}
.a .b .c {
color: yellow;
}
.d {
color: green;
}@debug
@debug在Sass中是用来调试的, 当在Sass的源码中使用了@debug指令之后, Sass代码在编译时会在命令终端输出你设置的提示Bug
// SCSS
@debug 10em + 12em;
// 会在命令终端输出: Line 1 DEBUG: 22em@warn
@warn和@debug功能类似, 用来帮助我们更好的调试Sass
@mixin adjust-location($x, $y) {
@if unitless($x) { //unitless是内置函数, 判断数值是否有“单位”
@warn "Assuming #{$x} to be in pixels";
$x: 1px * $x;
}
@if unitless($y) {
@warn "Assuming #{$y} to be in pixels";
$y: 1px * $y;
}
position: relative; left: $x; top: $y;
}
.botton{
@include adjust-location(20px, 30);
}@error
@error与@debug、@warn功能相同
// SCSS
@mixin error($x){
@if $x < 10 {
width: $x * 10px;
} @else if $x == 10 {
width: $x;
} @else {
@error "你需要将#{$x}值设置在10以内的数";
}
}
.test {
@include error(15);
}
// 编译时输出: 你需要将15值设置在10以内的数 on line 7 at column 5