# CSS 编码规范
# 命名规范(遵循BEM)
使用小写字母,以中划线分隔; less/scss 中的变量、函数、混合、placeholder 采用驼峰式命名
/* class */
.element-content {
...;
}
/* id */
#myDialog {
...;
}
/* 变量 */
$colorBlack: #000;
/* 函数 */
@function pxToRem($px) {
...;
}
/* 混合 */
@mixin centerBlock {
...;
}
/* placeholder */
%myDialog {
...;
}
BEM规范命名eg:
.block { /* styles */ }
.block__element { /* styles */ }
.block--modifier { /* styles */ }
其中的BEM分别对应block , element 和 modifier。
# 什么是块?
在规范中,块表示一个组件的意思,这样看上去有点抽象,我们可以通过例子来学习,假设你要写一个按钮的组件。我们只需要设置了一个 .button 类的按钮,然后可以在任何<button>按钮上使用该类,就可以生成该组件的传统样式。使用.button而不是用button的原因是因为类允许无限的可重用性,而即使是最基本的元素也可能改变样式。但是在实际的项目使用中,我们会发现一个按钮可能是大按钮,可能是小按钮,也可能是红色的,或者黄色的。于是就引申出了BEM的modifier。
# 什么是元素
元素是块的子节点。为了表明某个东西是一个元素,你需要在块名后添加 __element。所以,如果你看到一个像那样的名字,比如 form__row ,你将立即知道 .form 块中有一个 row 元素。
<style>
.form__row { /* styles */ }
</style>
<form class="form" action="">
<div class="form__row">
</div>
</form>
# 什么是修饰符?
修饰符是改变某个块的外观的标志。要使用修饰符,可以将 --modifier 添加到块中。 假如我们要添加一个默认按钮,一个主要按钮,一个大按钮,一个小按钮,一个主要的小按钮。 我们可以这样:
<button class=".button .button--default"></button>
<button class=".button .button--primary"></button>
<button class=".button .button--large"></button>
<button class=".button .button--small"></button>
<button class=".button .button--primary .button--small"></button>
BEM 元素有两个优点 :
- 你可以让 CSS 的优先级保持相对扁平。
- 你能立即知道哪些东西是一个子元素。
# 总结
以上就是简单的BEM规范和使用方法的简单介绍。基本的BEM规范的使用可以解决之前提到的一些问题:
class 的数量必须尽可能少 ,防止了css的优先级竞争。 立即知道一个 class 放在这个伟大工程中的什么地方,以防止大脑过载。 但是还有在实际应用中还有一些问题没有解决。
我必须 立即知道组件是否使用 JavaScript 。 我必须 立即知道编辑一个 class 是否安全,会不会干扰其他 CSS。 剩下的问题,我们就需要命名空间配合BEM来解决。
# 缩进
使用 soft tab(4 个空格)。
.element {
position: absolute;
top: 10px;
left: 10px;
border-radius: 10px;
width: 50px;
height: 50px;
}
# 分号
每个属性声明末尾都要加分号。
.element {
width: 20px;
height: 20px;
background-color: red;
}
# 空格
以下几种情况不需要空格:
- 属性名后
- 多个规则的分隔符','前
- !important '!'后
- 属性值中'('后和')'前
- 行末不要有多余的空格
以下几种情况需要空格:
- 属性值前
- 选择器'>', '+', '~'前后
- '{'前
- !important '!'前
- @else 前后
- 属性值中的','后
- 注释'/*'后和'*/'前
/* not good */
.element {
color: red !important;
background-color: rgba(0, 0, 0, 0.5);
}
/* good */
.element {
color: red !important;
background-color: rgba(0, 0, 0, 0.5);
}
/* not good */
.element,
.dialog {
...;
}
/* good */
.element,
.dialog {
}
/* not good */
.element > .dialog {
...;
}
/* good */
.element > .dialog {
...;
}
/* not good */
.element {
...;
}
/* good */
.element {
...;
}
/* not good */
@if{
...;
} @else {
...;
}
/* good */
@if{
...;
} @else {
...;
}
# 空行
以下几种情况需要空行:
文件最后保留一个空行 '}'后最好跟一个空行,包括 scss 中嵌套的规则 属性之间需要适当的空行,具体见属性声明顺序
/* not good */
.element {
...;
}
.dialog {
color: red;
&:after {
...;
}
}
/* good */
.element {
...;
}
.dialog {
color: red;
&:after {
...;
}
}
# 换行
以下几种情况不需要换行:
'{'前 以下几种情况需要换行:
'{'后和'}'前 每个属性独占一行 多个规则的分隔符','后
/* not good */
// .element { color: red; background-color: black; }
/* good */
.element {
color: red;
background-color: black;
}
/* not good */
//.element,.dialog {
...;
}
/* good */
.element,
.dialog {
...;
}
# !important
不允许使用!important。
# 注释
注释统一用'/* */'(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");
}
li[data-type="single"] {
...;
}
# 属性声明顺序
相关的属性声明按右边的顺序做分组处理,组之间需要有一个空行。
.declaration-order {
display: block;
float: right;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 100;
border: 1px solid #e5e5e5;
border-radius: 3px;
width: 100px;
height: 100px;
font: normal 13px "Helvetica Neue", sans-serif;
line-height: 1.5;
text-align: center;
color: #333;
background-color: #f5f5f5;
opacity: 1;
}
// 下面是推荐的属性的顺序
[
[
"display",
"visibility",
"float",
"clear",
"overflow",
"clip",
"zoom"
],
[
"table-layout",
"empty-cells",
"caption-side",
"border-spacing",
"border-collapse",
"list-style",
],
[
"-webkit-box-orient",
"-webkit-box-direction",
"-webkit-box-decoration-break",
"-webkit-box-pack",
"-webkit-box-align",
"-webkit-box-flex"
],
[
"position",
"top",
"right",
"bottom",
"left",
"z-index"
],
[
"margin",
"box-sizing",
"border",
"border-radius",
"border-image",
"padding",
"width",
"height",
],
[
"font",
"line-height",
"text-align",
"vertical-align",
"white-space",
"text-decoration",
"text-emphasis",
"text-indent",
"text-justify",
"letter-spacing",
"word-spacing",
"-ms-writing-mode",
"text-outline",
"text-transform",
"text-wrap",
"text-overflow",
"-ms-word-wrap",
"word-wrap",
"word-break"
],
[
"color",
"background",
"filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
],
[
"outline",
"opacity",
"filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
"-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha",
"-ms-interpolation-mode",
"box-shadow",
"filter:progid:DXImageTransform.Microsoft.gradient",
"-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient",
"text-shadow"
],
[
"transition",
"transform",
"animation",
],
[
"content",
"quotes",
"counter-reset",
"counter-increment",
"resize",
"cursor",
"user-select",
"nav-index",
"nav-up",
"nav-right",
"nav-down",
"nav-left",
"tab-size",
"hyphens",
"pointer-events"
]
]
# 颜色
颜色 16 进制用小写字母;
颜色 16 进制尽量用简写。
/* not good */
.element {
color: #abcdef;
background-color: #001122;
}
/* good */
.element {
color: #abcdef;
background-color: #012;
}
# 媒体查询
尽量将媒体查询的规则靠近与他们相关的规则,不要将他们一起放到一个独立的样式文件中,或者丢在文档的最底部,这样做只会让大家以后更容易忘记他们。
.element {
...;
}
.element-avatar {
...;
}
@media (min-width: 480px) {
.element {
...;
}
.element-avatar {
...;
}
}
# LESS/SCSS 相关
提交的代码中不要有 @debug;
声明顺序:
@extend 不包含 @content 的 @include 包含 @content 的 @include 自身属性 嵌套规则 @import 引入的文件不需要开头的'_'和结尾的'.scss';
嵌套最多不能超过 4 层;
@extend 中使用 placeholder 选择器;
去掉不必要的父级引用符号'&'。
/* not good */
@import "_dialog.scss";
/* good */
@import "dialog";
/* not good */
.fatal {
@extend .error;
}
/* good */
.fatal {
@extend %error;
}
/* not good */
.element {
& > .dialog {
...;
}
}
/* good */
.element {
> .dialog {
...;
}
}
# 杂项
不允许有空的规则;
元素选择器用小写字母;
去掉小数点前面的 0;
去掉数字中不必要的小数点和末尾的 0;
属性值'0'后面不要加单位;
同个属性不同前缀的写法需要在垂直方向保持对齐,具体参照右边的写法;
无前缀的标准属性应该写在有前缀的属性后面;
不要在同个规则里出现重复的属性,如果重复的属性是连续的则没关系;
不要在一个文件里出现两个相同的规则;
用 border: 0; 代替 border: none;;
选择器不要超过 4 层(在 scss 中如果超过 4 层应该考虑用嵌套的方式来写);
发布的代码中不要有 @import;
尽量少用'*'选择器。
/* not good */
.element {
}
/* not good */
LI {
...;
}
/* good */
li {
...;
}
/* not good */
.element {
color: rgba(0, 0, 0, 0.5);
}
/* good */
.element {
color: rgba(0, 0, 0, 0.5);
}
/* not good */
.element {
width: 50px;
}
/* good */
.element {
width: 50px;
}
/* not good */
.element {
width: 0px;
}
/* good */
.element {
width: 0;
}
/* not good */
.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%);
}
/* not good */
.element {
color: rgb(0, 0, 0);
width: 50px;
color: rgba(0, 0, 0, 0.5);
}
/* good */
.element {
color: rgb(0, 0, 0);
color: rgba(0, 0, 0, 0.5);
}