css/sass编码规范
一、前言
CSS 作为网页样式的描述语言,一直有着广泛的应用。本文档的目标是使 CSS 代码风格保持一致,容易被理解和被维护。虽然本文档是针对 CSS 设计的,但是在使用各种 CSS 的预编译器(如 less、sass 等)时,适用的部分也应尽量遵循本文档的约定。
二、命名规范
2.1 文件命名
- css文件采用utf-8编码,css属性值中尽量少出现中文,以免乱码;
- css文件名存在多个单词使用中横线分割,单词均为小写;
示例 case-index.css
- 一些通用文件名
重置样式:reset.css
基本样式:base.css
全局样式:global.css
框架布局:layout.css
字体样式:font.css
链接样式:link.css
2.2 ID
和 CLASS
命名
- 类名使用小写字母,以中横线分隔
/* class */
.element-content {
...
}
- id采用小驼峰式命名
/* id */
#myDialog {
...
}
- 一个功能模块的子节点类名需加功能前缀,孙节点不加
.list {
}
.list .list-item {
}
.list .list-item .title {
}
- 使用有意义的或通用的ID和类名称
- 在表述明确的情况下,尽可能的使用短的
ID
和CLASS
命名
/* bad */
.fw-800 {
font-weight: 800;
}
/* good */
.heavy {
font-weight: 800;
}
- 合理的使用ID
一般情况下ID不应该被用于样式,并且ID的权重很高,所以不使用ID解决样式的问题,而是使用class
/* bad */
#content .title {
font-size: 2em;
}
/* good */
.content .title {
font-size: 2em;
}
扩展阅读:一些常见的class类名单词
2.3 其他命名
- scss中的变量、函数、混合、placeholder采用驼峰式命名
/* 变量 */
$colorBlack: #000;
/* 函数 */
@function pxToRem($px) {
...
}
/* 混合 */
@mixin centerBlock {
...
}
三、缩进
3.1 使用 4
个空格做为一个缩进层级,不允许使用 2
个空格 或 tab
字符。
.element {
margin: 0;
padding: 0;
}
四、分号
4.1 属性定义后必须以分号结尾。
.element {
width: 20px;
height: 20px;
background-color: red;
}
五、空格
5.1 不需要空格
属性名
与之后的:
之间不允许包含空格
margin: 0;
- 多个规则的分隔符
,
前 - !important
!
后 - 属性值中
(
后和)
前 - 行末不要有多余的空格
.element {
color: red !important;
background-color: rgba(0, 0, 0, .5);
}
5.2 需要空格
:
与属性值
之间必须包含空格>
、+
、~
选择器的两边各保留一个空格。
/* good */
main > nav {
padding: 10px;
}
/* bad */
main>nav {
padding: 10px;
}
{
前
.element {
...
}
- !important
!
前
.element {
color: red !important;
background-color: rgba(0, 0, 0, .5);
}
- @else 前后
/* good */
@if {
...
} @else {
...
}
列表型属性值
书写在单行时,,
后必须跟一个空格。
font-family: Arial, sans-serif;
- 注释’/‘后和’/'前
六、空行
- 文件最后保留一个空行
- '}'后最好跟一个空行,包括scss中嵌套的规则
- 属性之间需要适当的空行,具体见属性声明顺序
.element {
...
}
.dialog {
color: red;
&:after {
...
}
}
七、选择器
7.1 当一个 rule 包含多个 selector 时,每个选择器声明必须独占一行
/* good */
.post,
.page,
.comment {
line-height: 1.5;
}
/* bad */
.post, .page, .comment {
line-height: 1.5;
}
7.2 [建议] 选择器的嵌套层级应不大于 3
级,位置靠后的限定条件应尽可能精确。
/* good */
#username input {}
.comment .avatar {}
/* bad */
.page .header .login #username input {}
.comment div * {}
7.3 css选择器中避免使用标签名
从结构、表现、行为分离的原则来看,应该尽量避免css中出现HTML标签,并且在css选择器中出现标签名会存在潜在的问题。
7.4 使用子选择器
很多前端开发人员写选择器链的时候不使用 直接子选择器(注:直接子选择器和后代选择器的区别)。
有时,这可能会导致疼痛的设计问题并且有时候可能会很耗性能。
然而,在任何情况下,这是一个非常不好的做法。
如果你不写很通用的,需要匹配到DOM末端的选择器, 你应该总是考虑直接子选择器。
/* bad */
.content .title {
font-size: 2rem;
}
/* good */
.content > .title {
font-size: 2rem;
}
扩展阅读:
Scope CSS classes with prefixes
Stop the cascade
八、换行
8.1 不需要换行
{
前
8.2 需要换行
- '{‘后和’}'前
- 每个属性独占一行
- 多个规则的分隔符’,'后
/* bad */
.element
{color: red; background-color: black;}
/* good */
.element {
color: red;
background-color: black;
}
/* bad */
.element, .dialog {
...
}
/* good */
.element,
.dialog {
...
}
九、注释
- 注释统一用’/* */’(scss中也不要用’//’);
- 缩进与下一行代码保持一致;
- 可位于一个代码行的末尾,与代码间隔一个空格。
/* Modal header */
.modal-header {
...
}
/*
* Modal header
*/
.modal-header {
...
}
.modal-header {
/* 50px */
width: 50px;
color: red; /* color red */
}
十、引号
- 最外层统一使用双引号;
- url的内容要用引号;
.element:after {
content: "";
background-image: url("logo.png");
}
- 属性选择器中的属性值需要引号;
不允许使用单引号,不允许不使用引号。
/* good */
article[character="juliet"] {
voice-family: "Vivien Leigh", victoria, female;
}
/* bad */
article[character='juliet'] {
voice-family: "Vivien Leigh", victoria, female;
}
十一、颜色
- 颜色16进制用小写字母;
- 颜色16进制尽量用简写.
/* bad */
.element {
color: #ABCDEF;
background-color: #001122;
}
/* good */
.element {
color: #abcdef;
background-color: #012;
}
十二、属性简写
在需要显示地设置所有值的情况下,应当尽量限制使用简写形式的属性声明。常被滥用的简写属性如下:
- padding
- margin
- font
- background
- border
- border-radius
大部分情况下,我们不需要为简写形式的属性声明指定所有值。例如,HTML 的标题元素只需要设置上、下边距(margin)的值,因此,在必要的时候,只需覆盖这两个值就可以了。
0
值表示对浏览器默认值或以前指定的值的覆盖。
过多地使用属性的简写形式会导致代码出现不必要的覆盖和意外的副作用。
/* Bad */
.element {
margin: 0 0 10px;
background: red;
background: url("image.jpg");
border-radius: 3px 3px 0 0;
}
/* good */
.element {
margin-bottom: 10px;
background-color: red;
background-image: url("image.jpg");
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}
在 MDN(Mozilla Developer Network)上一篇非常好的关于 shorthand properties 的文章,对于不太熟悉简写属性声明及其行为的用户很有用。
十三、属性书写顺序
同一 rule set 下的属性在书写时,应按功能进行分组,并以 Formatting Model(布局方式、位置) > Box Model(尺寸) > Typographic(文本相关) > Visual(视觉效果) 的顺序书写,以提高代码的可读性。
- Formatting Model 相关属性包括:position / top / right / bottom / left / float / display / overflow 等
- Box Model 相关属性包括:border / margin / padding / width / height 等
- Typographic 相关属性包括:font / line-height / text-align / word-wrap 等
- Visual 相关属性包括:background / color / transition / list-style 等
另外,如果包含 content 属性,应放在最前面。
.sidebar {
/* formatting model: positioning schemes / offsets / z-indexes / display / ... */
position: absolute;
top: 50px;
left: 0;
overflow-x: hidden;
/* box model: sizes / margins / paddings / borders / ... */
width: 200px;
padding: 5px;
border: 1px solid #ddd;
/* typographic: font / aligns / text styles / ... */
font-size: 14px;
line-height: 20px;
/* visual: colors / shadows / gradients / ... */
background: #f5f5f5;
color: #333;
-webkit-transition: color 1s;
-moz-transition: color 1s;
transition: color 1s;
}
完整的属性列表及其排列顺序请参考 Bootstrap property order for Stylelint。
十四、兼容性
- 带私有前缀的属性由长到短排列,按冒号位置对齐。
标准属性放在最后,按冒号对齐方便阅读,也便于在编辑器内进行多行编辑。
.box {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
十五、媒体查询
尽量将媒体查询的规则靠近与他们相关的规则,不要将他们一起放到一个独立的样式文件中,或者丢在文档的最底部,这样做只会让大家以后更容易忘记他们。
.element {
...
}
.element-avatar{
...
}
@media (min-width: 480px) {
.element {
...
}
.element-avatar {
...
}
}
十六、Less 和 Sass相关
16.1 Less 和 Sass 中的嵌套
避免不必要的嵌套。这是因为虽然你可以使用嵌套,但是并不意味着应该使用嵌套。只有在必须将样式限制在父元素内(也就是后代选择器),并且存在多个需要嵌套的元素时才使用嵌套。
.table > thead > tr > th { … }
.table > thead > tr > td { … }
/* With nesting */
.table > thead > tr {
> th { … }
> td { … }
}
16.2 Less 和 Sass 中的操作符
为了提高可读性,在圆括号中的数学计算表达式的数值、变量和操作符之间均添加一个空格。
/* bad */
.element {
margin: 10px 0 @variable*2 10px;
}
/* good */
.element {
margin: 10px 0 (@variable * 2) 10px;
}
十七、其他
-
不允许有空的规则;
-
元素选择器用小写字母;
-
去掉小数点前面的0;
-
去掉数字中不必要的小数点和末尾的0;
-
属性值’0’后面不要加单位;
-
同个属性不同前缀的写法需要在垂直方向保持对齐
-
无前缀的标准属性应该写在有前缀的属性后面;
-
不要在同个规则里出现重复的属性,如果重复的属性是连续的则没关系;
-
不要在一个文件里出现两个相同的规则;
-
用 border: 0; 代替 border: none;;
-
发布的代码中不要有 @import;
-
尽量少用’*'选择器。
/* bad */
.element {
}
/* bad */
LI {
...
}
/* good */
li {
...
}
/* bad */
.element {
color: rgba(0, 0, 0, 0.5);
}
/* good */
.element {
color: rgba(0, 0, 0, .5);
}
/* bad */
.element {
width: 0px;
}
/* good */
.element {
width: 0;
}
/* bad */
.element {
border-radius: 3px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
background: linear-gradient(to bottom, #fff 0, #eee 100%);
background: -webkit-linear-gradient(top, #fff 0, #eee 100%);
background: -moz-linear-gradient(top, #fff 0, #eee 100%);
}
/* good */
.element {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
background: -webkit-linear-gradient(top, #fff 0, #eee 100%);
background: -moz-linear-gradient(top, #fff 0, #eee 100%);
background: linear-gradient(to bottom, #fff 0, #eee 100%);
}