一、前言
先说明这是一篇规范类文章,主要是在日常的前端工作中遇到的一些问题做个总结。由于本人前后在多个公司经历过项目的开发,对这几家公司的编码规范都有一定的了解,然而近日在公司进行项目开发的过程中发现关于 CSS 编码规范上的一些问题,借此文记录一下。(持续补充。。。)
问题描述
一个项目在一般情况下是由多人协同完成的,常常会因为个人的编码习惯导致项目代码写法参差不齐,主要反映出以下几个问题:
- 在阅读 CSS 代码的过程中,由于 CSS 属性较多,如果遇到一个选择器中有大量的 CSS 属性的情况下,阅读起来是非常吃力的;
- CSS 预处理器不统一,导致的编码方式会有偏差;
- CSS 编码风格不统一,有很多种写法,比如说是否写大括号、是否写冒号、是否写分号等等;
- CSS 命名不规范,导致定位难、难理解等等;
二、编码规范
这里会结合自己的一些理解以及工作经验上给出的一些编码规范。
命名规范
虽然工程化的前端项目中可以通过 scoped 设置样式的作用域,但还是建议采用 BEM 的命名规范,主要考虑到代码的可读性,并且在 CSS 预处理器内,减小层级嵌套,可有效的减少项目打包体积。
BEM
分别代表 Block (块), Element (元素)和 Modifier (修饰状态)。
- Block 是页面中独立存在的区块,可以在不同场合下被重用;每个页面都可以看做是多个 Block 组成。
- Element 是构成 Block 的元素,只有在对应 Block 内部才具有意义,是依赖于 Block 的存在。
- Modifier 是描述 Block 或 Element 的属性或状态;同一个 Block 或 Element 可以有多个 Modifier 。
在选择器中,由以下三种连接符号来表示扩展的关系:
-
中划线:仅作为连字符使用,表示某个块、某个子元素或状态的多单词之间的连接记号。__
双下划线:双下划线用来连接块和块的子元素。--
双横线:双横线用来描述一个块或者块的子元素的一种状态。
模板:type-block__element--modifier
解决问题:组件之间的完全解耦,不会造成命名空间的污染,如:.mod-xxx ul li 的写法带来的潜在的嵌套风险。
性能相关:BEM 命名会使得 Class 类名变长,但经过 gzip 压缩后这个带宽开销可以忽略不计
1.常用的CSS命名规则
头:header;内容:content/container;尾:footer;导航:nav;侧栏:sidebar;栏目:column;页面外围控制整体佈局宽度:wrapper;左右中:left right center;登录条:loginbar;标志:logo;广告:banner;页面主体:main;热点:hot;新闻:news;下载:download;子导航:subnav;菜单:menu;子菜单:submenu;搜索:search;友情链接:friendlink;页脚:footer;版权:copyright;滚动:scroll;内容:content;标签:tags;文章列表:list;提示信息:msg;小技巧:tips;栏目标题:title;加入:joinus;指南:guide;服务:service;注册:regsiter;状态:status;投票:vote;合作伙伴:partner
2. ID 的命名
(1)页面结构
容器: container;页头:header;内容:content/container;页主体:main;页尾:footer;导航:nav;侧栏:sidebar;栏目:column;页面外围控制整体佈局宽度:wrapper;左右中:left right center
(2)导航
导航:nav;主导航:mainnav;子导航:subnav;顶导航:topnav;边导航:sidebar;左导航:leftsidebar;右导航:rightsidebar;菜单:menu;子菜单:submenu;标题: title;摘要: summary
(3)功能
标志:logo;广告:banner;登陆:login;登录条:loginbar;注册:register;搜索:search;功能区:shop;标题:title;加入:joinus;状态:status;按钮:btn;滚动:scroll;标籤页:tab;文章列表:list;提示信息:msg;当前的: current;小技巧:tips;图标: icon;注释:note;指南:guild;服务:service;热点:hot;新闻:news;下载:download;投票:vote;合作伙伴:partner;友情链接:link;版权:copyright
属性顺序
相关的属性声明应当归为一组,并按照下面的顺序排列:
- Positioning - 定位属性
- Box model - 盒模型属性
- Typographic - 排版属性
- Visual - 视觉属性
- Misc - 其它属性
由于定位(positioning)可以从正常的文档流中移除元素,并且还能覆盖盒模型(box model)相关的样式,因此排在首位。
盒模型排在第二位,因为它决定了组件的尺寸和位置。
其他属性只是影响组件的内部(inside)或者是不影响前两组属性,因此排在后面。
/* 示例 */
.selector {
/* Positioning */
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 100;
/* Box-model */
display: block;
float: right;
width: 100px;
height: 100px;
/* Typography */
font: normal 13px "Helvetica Neue", sans-serif;
line-height: 1.5;
color: #333;
text-align: center;
/* Visual */
background-color: #f5f5f5;
border: 1px solid #e5e5e5;
border-radius: 3px;
/* Misc */
opacity: 1;
}
书写规范
1. 缩写属性
尽量使用 CSS 中可以简写的属性 (如 font),可以提高编码效率以及代码可读性。
/* 示例 */
.demo {
border-top: 0;
font: 100%/1.6 palatino, georgia, serif;
padding: 0 1em 2em;
}
2. 值的写法
- 去掉小数点前的“0”;
- 值为0时不需要添加单位;
- 16进制颜色代码缩写;
/* 示例 */
.demo {
margin: 0;
padding: 0;
font-size: .8em;
color: #ebc;
}
3. 不随意使用 ID 选择器
由于 ID 选择器的命名唯一的原因,大量频繁使用容易导致命名冲突的情况。
4. 代码格式
- 为了反映层级关系和提高可读性,块级内容都应缩进;
- 每行 CSS 都应以分号结尾;
- 属性名和值之间都应有一个空格;
- 在选择器和 {} 之间用空格隔开;
- 每个选择器都应该另起一行;
- 规则之间都用空行隔开;
- 属性选择器和属性值用单引号,URI 的值不需要引号;
- 在使用 CSS 预处理 Less、Stylus等情况下,尽量将嵌套层级控制在3层以内;
/* 示例 */
@import url(//www.google.com/css/maia.css);
h1,
h2,
.demo1 {
background: #fff;
color: #444;
}
.demo2 {
background: #fff;
color: #444;
}