@ozo/react-rock
Version:
React 移动端开发脚手架,基于CRA3,通用、开箱即用。
550 lines (354 loc) • 13.4 kB
Markdown
# CSS/SCSS编码规范
推荐通过 SASS、LESS 等预处理器语言来编写 CSS,利用其语言特性书写起来要简单很多。且能保证CSS代码的结构化和可维护性。
## 代码组织
以组件为单位组织代码段。
制定一致的注释规范。
使用一致的空白符将代码分隔成块,这样利于扫描较大的文档。
如果使用了多个 CSS 文件,将其按照组件而非页面的形式分拆,因为页面会被重组,而组件只会被移动。
模块内部的样式,建议在一百条内。
目录层次上,相同文件夹的import不换行,不同文件夹的导入要换行(建议参考bootstrap的sass写法)。可以把[bootstrap-sass目录结构](https://github.com/twbs/bootstrap-sass/tree/master/assets/stylesheets) `clone`下来,研究一番。

## 命名规范
+ 通俗易懂,尽量保持不重复(冲突),尽量不要用id。
+ `class` 名称中只能出现小写字符和破折号(dashe)(不是下划线,也不是驼峰命名法)。破折号应当用于相关 class 的命名(类似于命名空间)(例如,.btn 和 .btn-danger)。
```css
.demo-test,
#test-demo {
width: 100%;
}
```
+ 避免过度任意的简写。.btn 代表 button,但是 .s 不能表达任何意思。
+ `class` 名称应当尽可能短,并且意义明确。
+ 使用有意义的名称。使用有组织的或目的明确的名称,不要使用表现形式(presentational)的名称。
+ 基于最近的父 `class` 或基本(base) class 作为新 class 的前缀。
+ 使用 `.js-*` class 来标识行为(与样式相对),并且不要将这些 class 包含到 CSS 文件中。
+ 在为 SASS 和 LESS 变量命名是也可以参考上面列出的各项规范。
```css
/* Bad example */
.t { ... }
.red { ... }
.header { ... }
/* Good example */
.tweet { ... }
.important { ... }
.tweet-header { ... }
```
### BEM
经常在css代码中看到“--”和“__”是什么意思?它们的出现是源于[BEM](http://bem.info/)和[Nicolas Gallagher](http://twitter.com/necolas)...
BEM的意思就是块(block)、元素(element)、修饰符(modifier),是由[Yandex](http://yandex.ru/)团队提出的一种前端命名方法论。这种巧妙的命名方法让CSS类对其他开发者来说更加透明而且更有意义。
BEM命名约定更加严格,而且包含更多的信息,它们用于一个团队开发一个耗时的大项目。目前流行的基于BEM的命名方式是经过[Nicolas Gallagher修改过的](http://nicolasgallagher.com/about-html-semantics-front-end-architecture)。
命名约定的模式如下:
```css
.block{}
.block__element{}
.block--modifier{}
```
`.block` 代表了更高级别的抽象或组件。
`.block__element` 代表.block的后代,用于形成一个完整的.block的整体。
`.block--modifier`代表.block的不同状态或不同版本。
之所以使用两个连字符和下划线而不是一个,是为了让你自己的块可以用单个连字符来界定,如:
```css
.site-search{} /* 块 */
.site-search__field{} /* 元素 */
.site-search--full{} /* 修饰符 */
```
[参考原文](https://www.w3cplus.com/css/mindbemding-getting-your-head-round-bem-syntax.html)
BEM的关键是,可以获得更多的描述和更加清晰的结构,从其名字可以知道某个标记的含义。于是,通过查看 HTML 代码中的 class 属性,就能知道元素之间的关联。
[BEM命名规范](https://juejin.im/post/5b925e616fb9a05cdd2ce70d)
### CSS-Modules
通过对当前引入的css class的命名增加hash来避免命名冲突。
### CSS-In-JS
CSS-in-JS 是一种使用 JavaScript来设置组件样式的技术。在解析此 JavaScript时,会生成 CSS(通常作为 `<style>` 元素)并附加到 DOM 中。这个功能由第三方库实现。例如,下面是使用 [Aphrodite](https://github.com/Khan/aphrodite) 实现的上一个示例:
```js
import { StyleSheet, css } from 'aphrodite';
const styles = StyleSheet.create({
myStyle: {
fontSize: 24,
lineHeight: '1.3em',
fontWeight: 'bold',
}
});
<span className={css(styles.myStyle)}>Hello World!</p>
```
其他第三方库推荐:
- [Emotion](https://emotion.sh/)
- [JSS](http://cssinjs.org/)
- [Radium](https://formidable.com/open-source/radium/)
- [Styled-components](https://www.styled-components.com/)
搭配用于在JavaScript中编写样式的轻量级工具集[polished](https://polished.js.org/),可以获得更好的体验。
参考文章
https://www.jianshu.com/p/d30d0b0705db
https://segmentfault.com/a/1190000017543565
https://segmentfault.com/p/1210000011172751/read
在这个 [页面](https://css-in-js-playground.com/) 中,您可以测试和比较许多 CSS-in-JS 的库。
> 还有其他库正在进一步采用 CSS,JavaScript和类型的概念。其中一个库是 [stylable](https://github.com/wix/stylable),一个基于组件的库,带有一个预处理器,可以将 stylable 的 CSS 转换成最小的跨浏览器的 vanilla CSS。
目前大多数项目都采用了CSS-Modules来避免命名冲突,适合的才是最好的。
- 通用UI模式,适合采用BEM规范或类网易的单字母前缀命名。推荐`bootstrap`样式框架的编码规范,同时结合`BEM`命名规范,灵活使用。
- 独立组件模式,适合采用CSS-Modules或css-in-js。
> BEM使用应该适量,适用于模块化的html结构。
>
> 避免全篇使用,会导致class命名冗余。并且用预处理器拼接出来的class名称,在维护代码时,不方便定位。
## 代码风格
### 编码
统一字符编码utf-8
```css
charset 'utf-8';
```
### 缩进
使用 `4` 个空格作为一个缩进层级,不允许使用 `2` 个空格或 `tab` 字符。
```css
.selector {
margin: 0;
padding: 0;
}
```
### 分号
每个属性声明末尾都要加分号
```css
.selector {
width: 100%;
height: 100%;
}
```
### 空格
- `:` 与属性值之间需要空格,与属性名之间不需要空格
- 属性值中的 `,` 后需要空格,`,` 前不需要空格
- 选择器 `> + ~` 等前后需要空格
- 选择器与 `{` 之间需要空格
- `/` 前后需要空格
- 注释 `/*` 后和 `*/` 前需要空格
```css
.selector > .wrapper {
font-family: "Hiragino Sans GB", sans-serif;
background: rgba(0, 0, 0, 0.5) url(logo.png) no-repeat center / contain;
height: 100%;
}
```
### 空行
- 两个选择器属性块之间保留一个空行
- 代码块注释前与代码块后保留一个空行
```css
.wrapper {
height: 100%;
/* 字体相关 */
font-family: 'DINPro';
font-size: 16px;
font-weight: 700;
background: #000;
}
.selector {
height: 100%;
}
```
### 换行
- 当一个规则包含多个选择器时,每个选择器声明必须独占一行
- 每个属性定义必须另起一行,且必须带上分号
- `{` 后需要换行,`}` 前需要换行
```css
.wrapper,
.selector {
width: 100%;
height: 100%;
}
```
### 引号
- 引号统一使用双引号
- 属性选择器中的属性值需要引号
```css
[class="demo"]::after {
content: "";
}
```
### 颜色
- 16 进制颜色使用小写字母
- 16 进制颜色尽量使用简写
```css
/* good */
.selector {
color: #abc;
}
/* bad */
.selector {
color: #AABBCC;
}
```
### 简写
属性可以简写时,尽量采用简写方式,可以精简代码且提高阅读体验。
(1)如padding,margin,font,color等等
(2)小数点前面的'0'建议去除
(3)使用十六进制表示颜色值, 在可能的情况下,可以进行缩写,比如:#abf,#ccc
```css
/* better */
.selector {
background: rgba(0, 0, 0, 0.5) url(logo.png) no-repeat center / contain;
}
/* bad */
.selector {
background-color: rgba(0, 0, 0, 0.5);
background-image: url(logo.png);
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}
```
### 顺序
遵循 :布局属性-->自身属性-->文本属性-->其他属性。
1. 布局属性,如定位、层级、显示等,影响文档流(比如:`display / position / float / clear / visibility / top / right / z-index` 等)
2. 自身属性,盒模型等(比如:`width / height / margin / padding / border` 等)
3. 文本属性,排版相关(比如:`font / line-height / letter-spacing / text-align / vertical-align` 等)
4. 装饰属性(比如:`color / background / opacity / cursor` 等)
5. CSS3 新特性(比如:`transform / transition / animation` 等)
### 嵌套
(1)嵌套层级不超过3个层级。
```css
.outer .inner .innercontent{
// no more!
}
```
### 注释
- css文件必须书写顶部注释,标明该文件隶属模块
- 统一使用 `/* */` 进行注释
- 缩进与下一行代码保持一致
- 可位于一个代码行的末尾,与代码间隔一个空格
- 一个规则中有多条声明时,每条声明应独占一行;只有一条声明,整个规则可以写为一行
```css
.wrapper,
.selector {
/* 字体相关 */
font-family: 'DINPro';
font-size: 16px;
font-weight: 700; /* 字重 */
}
```
### 引用
**引用样式文件:**避免在css中用@import,使用sass或less等时除外,less使用@import,需避免在css中生成@import代码。
**引用图片:**使用PNG格式时,使用场景为单色背景、图中主要颜色不超过3种的,应采用PNG-8编码保存。其它场合下,采用PNG-24保存。推荐单个图片体积在10kb以下时,应考虑在css中以base64编码内联提供,不单独提供图片文件。
### 特性
根据项目的兼容性选择采用适合的特性。如移动端可使用 `flexbox` 布局,需兼容低版本 IE 项目除外。
```scss
.selector {
display: flex;
justify-content: center;
align-items: center;
}
```
### 其他
- 不允许有空的规则
- 元素选择器用小写字母
- 属性值 `0` 后面不要加单位
- 无前缀的标准属性应该写在有前缀的属性后面
- 不要在一个文件里出现两个相同的规则
- 发布的代码中不要有 `@import`
- 尽量不用 `*` 选择器
- 非特殊场景尽量少使用 ,如果使用须添加必要的注释
- 字符串和超链接使用单引号包裹,内部出现其他冲突符号建议使用转义字符
- 运算上,使用通用计算思维考虑,最高级别的用小括号包裹
- 尽量少使用将样式的定义写在标签中(如内联样式:style="color:red;"),或用js为元素添加内联样式
## SCSS规范
[SCSS入门](https://www.sass.hk/)
[Sass进阶](https://www.jianshu.com/p/bd2b221260b8)
### 结构
建议使用模块化写法,每个组件单独写个scss文件,通过@import来汇总成一个主scss文件,这样非常有利于维护;
### 变量
变量上,有可能复用的引用,应该赋值给变量;对于偶尔使用的,推荐使用%placeholder占位符变量;
### 注释
通用样式必须注明作用
```scss
.overlay {
// modals are 6000, saving messages are 5500, header is 2000
z-index: 5000;
}
```
### mixin
混合宏(mixin),在传入CSS3阴影这类多参数的值时,应该使用
```scss
@mixin shadows($shadows...) {
}
```
### 条件
循环条件判断可以参考JS的规范写法
```scss
@if (true){
} @else (){
}
```
### 顺序
@extend在前,@include,常规样式在后,伪类在最后
```scss
.test {
@extend %module;
@include transition(all 0.3s ease-out);
background: #000;
&:hover {
background: DarkCyan;
}
&::before {
content: "";
display: block;
}
...
}
```
### map
map上,推荐json的写法;
```scss
'name': 'CRPER', //冒号后空格再写值,逗号结尾
'mage': 22, //每个值对独占一行
```
### 嵌套
在scss中可以嵌套选择器,可以提升代码的简洁性和可读性,但是应该尽量避免使用没有任何内容的选择器。
应遵循scss嵌套顺序:
- 当前选择器的@extend和@include
- 当前选择器的样式属性
- 父级选择器的伪类选择器(:first-child,:active等)
- 伪类元素(:before,:after)
- 父级选择器的声明样式
- 用 scss 的上下文媒体查询
- 子选择器
嵌套最好不过三,有利于阅读,也有利于维护
```scss
.outer {
.inner {
innercontent {
// no more!
}
}
}
```
嵌套中,不仅仅考虑使用CSS的写法,跟应该使用新属性&来减少变量名的书写,方便阅读和引用正确
```scss
a{
&:link,
&:visited{
color:#000;
}
&:hover{
color:#000;
}
}
```
嵌套中,属性根据类型进行排序(position, display, colors, font, miscellaneous…),类型之间隔行
```scss
.container{
/定位/
position:absolute;
left:50%;
top:50%;
transform:translate(-50%,-50%);
/盒子类型/
display:block;
/颜色控制/
color:#000;
background-color:#f00;
border-color:#ff0;
/字体设置/
font-family:"微软雅黑";
font-size:15px;
font-weight:700;
line-height:30px;
text-decoration:none;
work-break:break-all;
/阴影设置/
text-shadow: 1px 1px 1px rgba(0,0,0,.5);
box-shadow: 1px 1px 1px rgba(0,0,0,.5);
```