参考:https://www.sasscss.com/sass-guidelines/
一. 语法规范:
1. 语法格式:
使用两个空格代表缩进,而不是使用tab键;
理想上,每行保持为80个字符宽度;
正确书写多行CSS规则;
有意义的使用空格。
2. 字符串:
遵循固定的编程规范处理 Sass 中的字符串
在 Sass 中字符串应该始终被单引号(')所包裹(在 querty 键盘中单引号比双引号更容易输入)
3. 编码
入口文件中第一行通过 @charset 指令使用 UTF-8 编码格式:@charset 'utf-8';
4. 引用:
引用时以字符串用单引号包裹形式引用
包含引号的字符串:字符串内包含了一个或多个单引号,虽然转义也可以,但建议使用双引号包裹整个字符串
// Okay
@warn 'You can\'t do that.';
// Okay
@warn "You can't do that.";
5. urls
URL 最好也用引号包裹起来,原因和上面所描述一样:.foo { background-image: url('/images/kittens.jpg');}
6. 零值
当数字小于 1 时,应该在小数点前写出 0. 永远不要显示小数尾部的 0
// Yep
.foo {
padding: 2em;
opacity: 0.5;
}
// Nope
.foo {
padding: 2.0em;
opacity: .5;
}
7. 单位
- 当定义长度时(只针对长度而言),0 后面不需要加单位。
- 将一个单位添加给数字的时候,实际上是让该数值乘以1个单位,而不是拼接。
$value: 42;
// Yep
$length: $value * 1px;
// Nope
$length: $value + px;
注意:此情况一般+0个单位也可以,但是有时候可能会造成混乱,尽量使用上面方法给数字添加单位:
$value: 42 + 0px;
// -> 42px
$value: 1in + 0px;
// -> 1in
$value: 0px + 1in;
// -> 96px
- 要删除一个值的单位,你需要除以相同类型的 1 单位,而不是截取
$length: 42px;
// Yep
$value: $length / 1px;
// Nope
$value: str-slice($length + unquote(''), 1, 2);
8. 计算
最高级运算应该始终被包裹在括号中
// Yep
.foo {
width: (100% / 3);
}
// Nope
.foo {
width: 100% / 3;
}
9. 颜色格式:
为了尽可能简单地使用颜色,我建议颜色格式要按照以下顺序排列:
除非是为了快速开发出原型,否则不建议使用 CSS 颜色关键字。
使用 HSL 值或者 RGB 值,通常在逗号 (,)后面追加一个空格,而不在前后括号 ((, )) 和值之间添加空格。
// Yep
.foo {
color: rgba(0, 0, 0, 0.1);
background: hsl(300, 100%, 100%);
}
// Nope
.foo {
color: rgba(0,0,0,0.1);
background: hsl( 300, 100%, 100% );
}
10. 颜色值
当一个颜色被多次调用时,最好用一个有意义的变量名来保存它:$sass-pink: hsl(330, 50%, 60%);
如果你是在一个主题中使用,我不建议固定的使用这个变量。相反,可以使用另一个标识方式的变量来保存它:$main-theme-color: $sass-pink;
11. 列表
列表需要遵守以下规范:
- 除非列表太长不能写在 80 字符宽度的单行中,否则应该始终单行显示;
- 除非适用于 CSS,否则应该始终使用逗号作为分隔符;
- 要么使用内联形式,要么使用多行形式;
- 始终使用括号包裹;
- 始终不要添加尾部的逗号。
// Yep
$font-stack: ('Helvetica', 'Arial', sans-serif);
// Yep
$font-stack: (
'Helvetica',
'Arial',
sans-serif,
);
// Nope
$font-stack: 'Helvetica' 'Arial' sans-serif;
// Nope
$font-stack: 'Helvetica', 'Arial', sans-serif;
// Nope
$font-stack: ('Helvetica', 'Arial', sans-serif,);
注意:当要给列表添加一个新列表项时,请遵守提供的 API,不要手动给列表添加列表项。
$shadows: (0 42px 13.37px hotpink);
// Yep
$shadows: append($shadows, $shadow, comma);
// Nope
$shadows: $shadows, $shadow;
12. Maps
在 Sass 中,样式开发者可以使用 map 这种数据结构 —— Sass 团队使 map 可以映射关联数组、哈希表甚至是 Javascript 对象。map 是一种映射任何类型的键值对,包括内嵌类型的 map,但是我不建议使用 map 存储复杂数据类型。
map 的使用应该遵循下述规范:
- 冒号(:)之后添加空格;
- 左开括号(()要和冒号 (:)写在同一行;
- 如果键是字符串(99% 都是字符串),则使用括号包裹起来。
- 每一个键值对单独一行;
- 每一个键值对以逗号(,)结尾;
- 为最后一个键值对添加尾部逗号 (,),方便添加新键值对、删除和重排已有键值对;
- 单独一行书写右闭括号 ());
- 右闭括号 ())和分号(;)之间不使用空格和换行。
// Yep
$breakpoints: (
'small': 767px,
'medium': 992px,
'large': 1200px,
);
// Nope
$breakpoints: ( small: 767px, medium: 992px, large: 1200px );
13. CSS规则集
在这里,极有可能颠覆每个人对书写 CSS 规则集的认知(根据众多规范整理而成,包括CSS Guidelines):
- 相关联的选择器写在同一行;不相关联选择器分行书写;
- 最后一个选择器和左开大括号({)中间书写一个空格;
- 每个声明单独一行;
- 冒号(:)后添加空格;
- 所有声明的尾部都添加一个分号 (;);
- 右闭大括号(})单独一行;
- 右闭大括号(})添加空行。
// Yep
.foo, .foo-bar,
.baz {
display: block;
overflow: hidden;
margin: 0 auto;
}
// Nope
.foo,
.foo-bar, .baz {
display: block;
overflow: hidden;
margin: 0 auto }
注意:
本地变量在其他任何变量之前声明,并和其他声明用空行分隔开;
不需 @content 的混合宏在放在其他声明之前;
嵌套选择器在新行声明;
需要 @content 的混合宏在嵌套选择器后声明;
右闭大括号(})上一行无需空行;
.foo, .foo-bar,
.baz {
$length: 42em;
@include ellipsis;
@include size($length);
display: block;
overflow: hidden;
margin: 0 auto;
&:hover {
color: red;
}
@include respond-to('small') {
overflow: visible;
}
}
14 . 样式声明顺序
CSS 声明顺序各种讨论都,整体看使用最多的是如下两派:
- 坚持以字母顺序排列;
- 以类型(position, display, colors, font, miscellaneous...)顺序排列;
这两派中以类型顺序排列的相对比较多,一般是相关联样式写在一起,具体怎么选看自己吧。
15. 选择嵌套
建议嵌套不要超过三层
在最外层选择器中嵌套伪类和伪元素是被允许,也是受推荐的
.foo {
color: red;
&:hover {
color: green;
}
&::before {
content: 'pseudo-element';
}
}
二. 命名规范:
1. 占位符: Sass 占位符遵循和类名相同的命名模式,因此被视为常规的 CSS 选择器,命名参考CSS命名
2. 变量、函数和混合宏:小写连字符分隔,有意义的命名( CSS-y 的风格)
3. 常量:Sass没有提供常量的说法,但对于众多编程语言,建议使用全大写方式书写常量
$CSS_POSITIONS: (top, right, bottom, left, center);
4. 命名空间:
su-
作为一个命名空间
$su-configuration: ( … );
@function su-rainbow($unicorn) {
// …
}
三. 结构:
结构内容较多,请单独看关于Sass结构的文章
四. 响应式设计和断点:
1.断点命名建议:媒体查询应该关注屏幕尺寸而不是设备类型,即命名不与特定设备关联并表达清晰
2.媒体查询是应该与选择器写在一起还是要彻底地分离开?
因为Sass提供了媒体查询可以嵌套在选择器中,但是生成的css确是分离的,因此建议:媒体查询紧贴选择器
上面只是建议:我们反复测试了贴合与分离两种媒体查询方式对性能的影响,结论是即使在最差情况下也没有明显差异,而在最好情况下差异更是少之又少。
3. 占位符: Sass 占位符遵循和类名相同的命名
五. 变量:
1.什么时候创建Sass变量:
- 该值至少重复出现了两次;
- 该值至少可能会被更新一次;
- 该值所有的表现都与变量有关(非巧合)。
2.变量作用域:
全局变量的影子:当在局部范围内(选择器内、函数内、混合宏内……)声明一个已经存在于全局范围内的变量时,局部变量就成为了全局变量的影子。即局部变量只会在局部范围内覆盖全局变量(如果已经存在同名的全局变量,则在局部范围内局部变量覆盖全局变量)。案例如下:
$variable: 'initial value';
@mixin global-variable-overriding {
$variable: 'mixin value' !global;
}
.local-scope::before {
$variable: 'local value';
@include global-variable-overriding;
content: $variable;
}
.other-local-scope::before {
content: $variable;
}
编译出的css:
.local-scope::before {
content: "local value";
}
.other-local-scope::before {
content: "mixin value";
}
3.!default
标识符:防止引入的其他文件中同名变量覆盖掉原变量值,注:如果变量是 null 值时,将视为未赋值,案例如下:
$content: null;
$content: 'Non-null content' !default;
#main {
content: $content;
}
编译成css:
#main {
content: "Non-null content";
}
六. 扩展:
谨慎使用 @extend
指令:
@extend
有助于减少文件体积大小,因为它的操作本质上是合并选择器而不是赋值样式。话虽如此,当你使用 Gzip 压缩文件时,@extend
对于文件压缩的好处几乎是可以忽略的。这也就是说,如果你不能使用类似 Gzip 的工具,那么就可以考虑使用 @extend
来减少不必要的重复.
注意:Sass 不可以将 @media 层外的 CSS 规则 @extend 给指令层内的 CSS,这样会生成大量的无用代码,除非是使用了@at-root的元素。案例如下:
- 优先继承
%placeholders
,而不是具体的选择器; - 当继承
.class
时,只继承单一的.class
,不要使用[复杂选择器]complex selector; - 尽可能少的继承自
%placeholders
; - 避免继承常见的父类选择器(比如:
.foo .bar
)或者是常见的相邻选择器(比如:.foo ~ .bar
),否则会让选择器的数量急速增加。
.foo {
content: 'foo';
}
// Nope
@media print {
.bar {
// This doesn't work. Worse: it crashes.
@extend .foo;
}
}
// Yep
@media print {
.bar {
@at-root (without: media) {
@extend .foo;
}
}
}
七. 混合宏:
1.无参数混合宏:为了简洁起见,无参数混合宏的调用可以删除圆括号
2.处理数量不明的参数:单一参数名+ '...'
@mixin box-shadow($shadows...) {
-moz-box-shadow: $shadows;
-webkit-box-shadow: $shadows;
box-shadow: $shadows;
}
.shadows {
@include box-shadow(0px 4px 5px #666, 2px 6px 10px #999);
}
3.多参数:只需给函数/混合宏一个列表或 map,传参的时候带'...'
@mixin colors($text, $background, $border) {
color: $text;
background: $background;
border-color: $border;
}
$values-list: #ff0000, #00ff00, #0000ff;
$values-map: (
text: #ff0000,
background: #00ff00,
border: #0000ff,
);
.primary {
@include colors($values-list...);
@include colors($values-map...);
}
注意:@include 混合宏并不会像继承那样合并代码,因此慎重使用混合宏,否则会造成大量的重复(冗余)代码。
八. 条件语句:
除非你的代码中有偏复杂的逻辑,否则没必要在日常开发的样式表中使用条件语句。实际上,条件语句主要适用于库和框架。
使用时请遵守下述准则:
- 除非必要,不然不需要括号;
- 务必在
@if
之前添加空行; - 务必在左开大括号(
{
)后换行; @else
语句和它前面的右闭大括号(}
)写在同一行;- 务必在右闭大括号(
}
)后添加空行,除非下一行还是右闭大括号(}
),那么就在最后一个右闭大括号(}
)后添加空行。
注意:
通常将变量置于语句的左侧,而将结果置于右侧。
测试一个错误值时,通常使用 not
关键字而不是比较与 false
或 null
等值
九. 循环:
1.@each
:迭代列表或 map,同时遵守下述规则,确保可读性:
each
前添加空行;- 除非下一行是右闭大括号(
}
),否则在所有右闭大括号(}
)后面添加新行。
@each $var in <list or map>
@each $var1,$var2, ... in <list>
@each $key,$value in <map>
2.@for:坚持一贯的传统,始终使用 $i
作为变量名,除非有非常好的原因,否则永远不要使用 to
关键字:而是始终使用 through
。迭代尽量选each,除非需要下标循环。
@for $var from <start> through <end> //through包含end
@for $var from <start> to <end> //to不包含end
3.@while:建议在Sass项目中尽量不要使用
十. 警告和错误:
软件应该能够预测风险并提醒使用者。
@debug:
主要是用作调试 SassScript@warn:只是用于提醒用户
@error:致命性的,
可以中断编译器的工作
十一. 工具:
1.Compass:是Sass的一个主要框架,但是已经不建议使用了,因为他会拖慢Sass。
2.栅格系统:可以使用 Bootstrap 和 Foundation 的 CSS 框架中的栅格系统,Sass 支持的栅格引擎:Susy和 Singularity
3.SCSS-lint:一个帮你保持 SCSS 文件简洁而又具有可读性的工具。它是完全可定制化的,并且非常易于和其他工具集成。为了根据 Sass 样式指南配置 SCSS-lint,建议配置参考:https://www.sasscss.com/sass-guidelines/tools/
不建议使用compass,随着技术的向前发展以及相关前端工具的出现,Compass早期所具备的特性也变得更佳弱化了:
- CSS3的前缀不在依赖于CSS预处理器的mixin完成,而是使用类似于PostCSS后处理器的Autoprefixer这样的插件
- Sprites目前也可以使用Grunt或Gulp这样的自动化工具来完成
- Vertical Rhythm可以通过原生的Sass来完成,比如Sass baseline这样的库,其功能就类似于Vertical Rhythm
- mixin和functions的集合也变得不是Compass的特长,只要长期使用Sass的同学,或多或少都会有自己的Mixins/functions/helpers的积累,而且网上类似的集合也非常的多
- Grids系统,目前Susy是最为强大的一种
- 对于三角函数,目前还很少有类似的Sass相关的独立库,不过有部分的三角函数,比如正切函数
总结概要
简而言之,本文主要包括以下几个方面的内容:
核心原则
- 创建编程规范的目的就是为了保证协作开发的一致性。即使你对本文有不同的意见,也要保证整体开发的一致性。↩
- 尽可能让 Sass 代码保持简洁。除非是绝对需要,否则绝没有必要构建复杂的系统。↩
- 请记住,有时候保持简洁(KISS,Keep It Simple, Stupid)比减少重复(Don't Repeat Yourself)更重要。↩
语法 & 格式
- 使用两个空格代表缩进,而不是使用tab键。↩
- 理想上,每行保持为 80 个字符宽度。↩
- 根据 CSS Guidelines 正确书写 CSS 属性。↩
- 有意义的使用空格。↩
字符串
数值
颜色
列表
Maps
声明顺序
- 只要保持开发的一致性,无论哪种声明顺序(根据字母表或者类型排序)都是可以接受的。↩
选择器嵌套
命名约定
- 坚持连字符分隔的命名方式。↩