# Sass预处理语言
# 变量($
符号)
$nav-color: #F90;
$attr:width;
nav {
$width: 100px;
width: $width;
color: $nav-color;
}
// 编译后
nav {
width: 100px;
color: #F90;
}
// 可以使用块级作用域并使用局部变量,
#main {
$width: 5em !global; // 将局部变量转换为全局变量可以添加 !global 声明
#{$attr}: $width; // 通过 #{} 插值语句可以在选择器或属性名中使用变量
}
// 编译后
#main {
width:5em
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 嵌套CSS
#content {
article {
h1 { color: #333 }
p { margin-bottom: 1.4em }
}
aside { background-color: #EEE }
}
2
3
4
5
6
7
# 父选择器的标识符&
article a {
color: blue;
&:hover { color: red }
}
//编译后
article a { color: blue }
article a:hover { color: red }
2
3
4
5
6
7
8
9
# 群组选择器的嵌套
nav, aside {
a {color: blue}
}
//编译后
nav a, aside a {color: blue}
2
3
4
5
6
7
# 子组合选择器和同层组合选择器:>、+和~
其用法和 css3
一致。
选择器 | 说明 |
---|---|
div > p | 选择父元素是 <div> 的所有 <p> 元素。 |
div + p | 选择紧跟 <div> 元素的首个 <p> 元素。 |
p ~ ul | 选择前面有 <p> 元素的每个 <ul> 元素。 |
可以把它们放在外层选择器后边,或里层选择器前边:
article {
~ article { border-top: 1px dashed #ccc }
> section { background: #eee }
dl > {
dt { color: #333 }
dd { color: #555 }
}
nav + & { margin-top: 0 }
}
2
3
4
5
6
7
8
9
sass
会如愿地将这些嵌套规则一一解开组合在一起:
article ~ article { border-top: 1px dashed #ccc }
article > footer { background: #eee }
article dl > dt { color: #333 }
article dl > dd { color: #555 }
nav + article { margin-top: 0 }
2
3
4
5
# 嵌套属性
nav {
border: {
style: solid;
width: 1px;
color: #ccc;
}
}
2
3
4
5
6
7
结果为
nav {
border-style: solid;
border-width: 1px;
border-color: #ccc;
}
2
3
4
5
# 导入SASS文件
通过@import
来处理多个sass
文件,且其中的变量依然可以使用。
# 使用SASS部分文件
在文件名的开头添加一个下划线。这将告诉 Sass 不要将其编译到 CSS 文件,这样,sass
就不会在编译时单独编译这个文件输出css
。
_filename;
引入时可以忽略下划线。
@import "filename";
**注意:**请不要将带下划线与不带下划线的同名文件放置在同一个目录下,比如,_colors.scss 和 colors.scss 不能同时存在于同一个目录下,否则带下划线的文件将会被忽略。
# 默认变量值
$new-width: 400px !default
类似于 !import
的对立面。含义是:如果这个变量被重复声明赋值了,那就用它声明的值,否则就用这个默认值。
# 嵌套导入
允许嵌套导入,将@import
命令写在css
规则内
//blue-theme 文件
aside {
background: blue;
color: white;
}
2
3
4
5
然后把它导入到一个CSS规则内,如下所示:
.blue-theme {@import "blue-theme"}
//生成的结果跟你直接在.blue-theme选择器内写_blue-theme.scss文件的内容完全一样。
.blue-theme {
aside {
background: blue;
color: #fff;
}
}
2
3
4
5
6
7
8
9
10
# 原生的CSS导入
不能用sass
的@import
直接导入一个原始的css
文件,因为sass
会认为你想用css
原生的@import
。但是,因为sass
的语法完全兼容css
,所以可以把原始的css
文件改名为.scss
后缀,即可直接导入。
# 混合器
# @mixin
混合器使用@mixin
标识符定义,以实现大段样式的重用,且兼容 css
规则。
下边的这段sass
代码,定义了一个非常简单的混合器,目的是添加跨浏览器的圆角边框。
@mixin rounded-corners {
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
2
3
4
5
然后通过@include
来使用这个混合器。@include
会把混合器中的所有样式提取出来放在@include
被调用的地方。如果像下边这样写:
notice {
background-color: green;
border: 2px solid #00aa00;
@include rounded-corners;
}
//sass最终生成:
.notice {
background-color: green;
border: 2px solid #00aa00;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# 带参数的混合器
@mixin link-colors($normal, $hover, $visited ,$selector) {
color: $normal;
&:hover { color: $hover; }
&:visited { color: $visited; }
#{$selector}{ // 使用 #{} 时,有引号字符串将被编译为无引号字符串,这样便于在 mixin 中引用选择器名
color: $visited;
}
}
2
3
4
5
6
7
8
当混合器被@include
时,你可以把它当作一个css
函数来传参。如果你像下边这样写:
a {
@include link-colors(blue, red, green, ".header");
}
//Sass最终生成的是:
a { color: blue; }
a:hover { color: red; }
a:visited { color: green; }
a .header{ color: green; }
2
3
4
5
6
7
8
9
10
可以通过语法$name: value
来指定参数的值,
a {
@include link-colors(
$normal: blue,
$visited: green,
$hover: red
);
}
2
3
4
5
6
7
# 设置默认参数
默认值可以是任何有效的css
属性值,甚至是其他参数的引用,如下代码:
@mixin link-colors(
$normal,
$hover: $normal,
$visited: blue
)
{
color: $normal;
&:hover { color: $hover; }
&:visited { color: $visited; }
}
p{@include link-colors(red)}
// 编译为
p{color:red;}
p:hover { color:red; }
p:visited { color: blue; }
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 使用参数变量(...)
@mixin colors($text, $background, $border) {
color: $text;
background-color: $background;
border-color: $border;
}
$values: #ff0000, #00ff00, #0000ff;
.primary {
@include colors($values...); // 参数变量声明 … (注意:要写在参数的最后方)
}
// 编译为
.primary {
color: #ff0000;
background-color: #00ff00;
border-color: #0000ff;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 混合器中导入额外内容
@mixin apply-to-ie6-only {
* html {
@content; // 类似于一个占位符,即传入的额外内容的放置位置
}
}
@include apply-to-ie6-only {
#logo {
background-image: url(/logo.gif);
}
}
// 编译为
* html #logo {
background-image: url(/logo.gif);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
注意
当 @content
在指令中出现过多次或者出现在循环中时,额外的代码将被导入到每一个地方。
# 继承
# @extend
@extend:
一个选择器可以继承为另一个选择器定义的所有样式,一般用于同一个类样式的继承,即语义化样式的重用。
例如:当一个元素拥有的类(比如说.seriousError
)表明它属于另一个类(比如说.error
),这时使用继承再合适不过了。
类似效果 class="seriousError error"
//通过选择器继承继承样式
.error {
border: 1px solid red;
background-color: #fdd;
}
.seriousError {
@extend .error;
border-width: 3px;
}
2
3
4
5
6
7
8
9
此外.seriousError
不仅会继承.error
自身的所有样式,任何跟.error
有关的组合选择器样式也会被.seriousError
以组合选择器的形式继承,如下代码:
//.seriousError从.error继承样式
.error a{ //应用到.seriousError a
color: red;
font-weight: 100;
}
h1.error { //应用到hl.seriousError
font-size: 1.2rem;
}
//如上所示,在class="seriousError"的html元素内的超链接也会变成红色和粗体。
2
3
4
5
6
7
8
9
# 多重继承
.error {
border: 1px #f00;
background-color: #fdd;
}
.attention {
font-size: 3em;
background-color: #ff0;
}
.seriousError {
@extend .error;
@extend .attention;
border-width: 3px;
}
// 编译为
.error, .seriousError {
border: 1px #f00;
background-color: #fdd; }
.attention, .seriousError {
font-size: 3em;
background-color: #ff0; }
.seriousError {
border-width: 3px; }
// 这时,后定义的样式享有优先权:.seriousError 的背景颜色是 #ff0 而不是 #fdd,因为 .attention 在 .error 之后定义。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 控制指令
# @if
$type: monster;
p {
@if $type == ocean {
color: blue;
} @else if $type == matador {
color: red;
} @else if $type == monster {
color: green;
} @else {
color: black;
}
}
// 编译为
p {
color: green; }
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# @for
这个指令包含两种格式:@for $var from <start> through <end>
,或者 @for $var from <start> to <end>
。
使用 through 时:[start,end]。
使用 to 时:[start,end) 即不包含 end 的值。
@for $i from 1 through 3 {
.item-#{$i} { width: 2em * $i; }
}
// 编译为
.item-1 {
width: 2em; }
.item-2 {
width: 4em; }
.item-3 {
width: 6em; }
2
3
4
5
6
7
8
9
10
11
12
# @each
@each $animal in puma, sea-slug, egret, salamander {
.#{$animal}-icon {
background-image: url('/images/#{$animal}.png');
}
}
// 编译为
.puma-icon {
background-image: url('/images/puma.png'); }
.sea-slug-icon {
background-image: url('/images/sea-slug.png'); }
.egret-icon {
background-image: url('/images/egret.png'); }
.salamander-icon {
background-image: url('/images/salamander.png'); }
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# @while
@while
指令重复输出格式直到表达式返回结果为 false
。这样可以实现比 @for
更复杂的循环,只是很少会用到。
$i: 6;
@while $i > 0 {
.item-#{$i} { width: 2em * $i; }
$i: $i - 2;
}
// 编译为
.item-6 {
width: 12em; }
.item-4 {
width: 8em; }
.item-2 {
width: 4em; }
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 自定义函数指令
$grid-width: 40px;
$gutter-width: 10px;
@function grid-width($n) {
@return $n * $grid-width + ($n - 1) * $gutter-width;
}
#sidebar { width: grid-width(5); }
2
3
4
5
6
7
8
参数规则同 minix 相同,同样支持关键词参数和默认参数。
#sidebar { width: grid-width($n: 5); }
提示
建议在自定义函数前添加前缀避免命名冲突,其他人阅读代码时也会知道这不是 Sass 或者 CSS 的自带功能。
# 封装示例
示例
/* 颜色变量 */
/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-primary-inverse: rgba(51, 120, 255, 0.1);
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
/* 文字基本颜色 */
$uni-text-color: #333; //基本色
$uni-text-color-inverse: #fff; //反色
$uni-text-color-grey: #999; //辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable: #c0c0c0;
/* 背景颜色 */
$uni-bg-color: #ffffff;
$uni-bg-color-grey: #f8f8f8;
$uni-bg-color-hover: #f1f1f1; //点击状态颜色
$uni-bg-color-mask: rgba(0, 0, 0, 0.4); //遮罩颜色
$bg-color-info: #f5f8ff;
/* 边框颜色 */
$uni-border-color: #c8c7cc;
/* 尺寸变量 */
/* 文字尺寸 */
$uni-font-size-sm: 12px;
$uni-font-size-base: 14px;
$uni-font-size-lg: 16px;
/* 图片尺寸 */
$uni-img-size-sm: 20px;
$uni-img-size-base: 26px;
$uni-img-size-lg: 40px;
/* Border Radius */
$uni-border-radius-sm: 2rpx;
$uni-border-radius-base: 3px;
$uni-border-radius-lg: 6px;
$uni-border-radius-circle: 50%;
/* 水平间距 */
$uni-spacing-row-sm: 5px;
$uni-spacing-row-base: 10px;
$uni-spacing-row-lg: 15px;
/* 垂直间距 */
$uni-spacing-col-sm: 4px;
$uni-spacing-col-base: 8px;
$uni-spacing-col-lg: 12px;
/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
/* 文章场景相关 */
$uni-color-title: #2c405a; // 文章标题颜色
$uni-font-size-title: 20px;
$uni-color-subtitle: #555555; // 二级标题颜色
$uni-font-size-subtitle: 26px;
$uni-color-paragraph: #3f536e; // 文章段落颜色
$uni-font-size-paragraph: 15px;
$directionMap: (
l: left,
r: right,
t: top,
b: bottom,
);
$borderStyle: solid dashed dotted double hidden none;
@each $style in $borderStyle {
.border-#{$style} {
border-style: $style;
}
}
.border-primary {
border-color: $uni-color-primary;
}
.border-main {
border-color: $uni-border-color;
}
.last-border-none {
&:last-child {
border: none;
}
}
.bc-primary {
background-color: $uni-color-primary;
}
.bc-primary-inverse {
background-color: $uni-color-primary-inverse;
}
.bc-mask {
background-color: $uni-bg-color-mask;
}
.bc-info {
background-color: $bg-color-info;
}
.text-grey {
color: $uni-text-color-grey;
}
.text-white {
color: #fff;
}
.text-primary {
color: $uni-color-primary;
}
@each $key, $value in $directionMap {
.m#{$key}-auto {
margin-#{$value}: auto;
}
.p#{$key}-auto {
margin-#{$value}: auto;
}
}
@for $i from 0 through 200 {
.w-#{$i} {
width: ($i * 1rpx);
}
.w-2-#{$i} {
width: ($i * 2rpx);
}
.h-#{$i} {
height: ($i * 1rpx);
}
.h-2-#{$i} {
height: ($i * 2rpx);
}
.ml-#{$i} {
margin-left: ($i * 1rpx);
}
.ml--#{$i} {
margin-left: -($i * 1rpx);
}
.mr-#{$i} {
margin-right: ($i * 1rpx);
}
.mr--#{$i} {
margin-right: -($i * 1rpx);
}
.mx-#{$i} {
margin-left: ($i * 1rpx);
margin-right: ($i * 1rpx);
}
.mt--#{$i} {
margin-top: -($i * 1rpx);
}
.mt-#{$i} {
margin-top: ($i * 1rpx);
}
.mb-#{$i} {
margin-bottom: ($i * 1rpx);
}
.mb--#{$i} {
margin-bottom: -($i * 1rpx);
}
.my-#{$i} {
margin-top: ($i * 1rpx);
margin-bottom: ($i * 1rpx);
}
.pl-#{$i} {
padding-left: ($i * 1rpx);
}
.pr-#{$i} {
padding-right: ($i * 1rpx);
}
.px-#{$i} {
padding-left: ($i * 1rpx);
padding-right: ($i * 1rpx);
}
.pt-#{$i} {
padding-top: ($i * 1rpx);
}
.pb-#{$i} {
padding-bottom: ($i * 1rpx);
}
.py-#{$i} {
padding-top: ($i * 1rpx);
padding-bottom: ($i * 1rpx);
}
.fs-#{$i} {
font-size: ($i * 1rpx);
}
.lh-#{$i} {
line-height: ($i * 1rpx);
}
.rounded-#{$i} {
border-radius: ($i * 1rpx);
}
.rounded-t-#{$i} {
border-top-left-radius: ($i * 1rpx);
border-top-right-radius: ($i * 1rpx);
}
.rounded-r-#{$i} {
border-top-right-radius: ($i * 1rpx);
border-bottom-right-radius: ($i * 1rpx);
}
.rounded-b-#{$i} {
border-bottom-right-radius: ($i * 1rpx);
border-bottom-left-radius: ($i * 1rpx);
}
.rounded-l-#{$i} {
border-top-left-radius: ($i * 1rpx);
border-bottom-left-radius: ($i * 1rpx);
}
.border-#{$i} {
border-width: ($i * 1rpx);
}
.top-#{$i} {
top: ($i * 1rpx);
}
.top--#{$i} {
top: ($i * -1rpx);
}
.right-#{$i} {
right: ($i * 1rpx);
}
.left-#{$i} {
left: ($i * 1rpx);
}
.bottom-#{$i} {
bottom: ($i * 1rpx);
}
.gap-#{$i} {
gap: ($i * 1rpx);
}
.flex-#{$i} {
flex: ($i * 1);
}
.shrink-#{$i} {
flex-shrink: ($i * 1);
}
.grow-#{$i} {
flex-grow: ($i * 1);
}
}
@for $i from 1 through 7 {
.fw-#{$i} {
font-weight: ($i * 100);
}
}
.box-border {
box-sizing: border-box;
}
.box-content {
box-sizing: content-box;
}
.w-screen {
width: 100vw;
}
.w-full {
width: 100%;
}
.h-full {
height: 100%;
}
.h-screen {
height: 100vh;
}
.h-min-screen {
min-height: 100vh;
}
.h-lvh {
height: 100lvh;
}
.h-min-lvh {
min-height: 100lvh;
}
.h-dvh {
height: 100dvh;
}
.h-min-dvh {
min-height: 100dvh;
}
.h-auto {
height: auto;
}
.flex-row {
display: flex;
flex-direction: row;
}
.flex-row-reverse {
display: flex;
flex-direction: row-reverse;
}
.flex-col {
display: flex;
flex-direction: column;
}
.flex-col-reverse {
display: flex;
flex-direction: column-reverse;
}
.justify-between {
justify-content: space-between;
}
.justify-center {
justify-content: center;
}
.items-start {
align-items: flex-start;
}
.items-center {
align-items: center;
}
.items-stretch {
align-items: stretch;
}
.flex-wrap {
flex-wrap: wrap;
}
.flex-nowrap {
flex-wrap: nowrap;
}
.fixed {
position: fixed;
}
.relative {
position: relative;
}
.absolute {
position: absolute;
}
.overflow-auto {
overflow: auto;
}
.overflow-x-auto {
overflow-x: auto;
}
.overflow-hidden {
overflow: hidden;
}
.overflow-y-auto {
overflow-y: auto;
}
.whitespace-normal {
white-space: normal;
}
.whitespace-nowrap {
white-space: nowrap;
}
.whitespace-break-spaces {
white-space: break-spaces;
}
.break-normal {
overflow-wrap: normal;
word-break: normal;
}
.break-words {
overflow-wrap: break-word;
}
.break-all {
word-break: break-all;
}
.text-center {
text-align: center;
}
.text-start {
text-align: start;
}
.text-end {
text-align: end;
}
.one-line-ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463