关于 CSS 编码规范的思考

877 阅读5分钟

一、前言

先说明这是一篇规范类文章,主要是在日常的前端工作中遇到的一些问题做个总结。由于本人前后在多个公司经历过项目的开发,对这几家公司的编码规范都有一定的了解,然而近日在公司进行项目开发的过程中发现关于 CSS 编码规范上的一些问题,借此文记录一下。(持续补充。。。)

问题描述

一个项目在一般情况下是由多人协同完成的,常常会因为个人的编码习惯导致项目代码写法参差不齐,主要反映出以下几个问题:

  1. 在阅读 CSS 代码的过程中,由于 CSS 属性较多,如果遇到一个选择器中有大量的 CSS 属性的情况下,阅读起来是非常吃力的;
  2. CSS 预处理器不统一,导致的编码方式会有偏差;
  3. CSS 编码风格不统一,有很多种写法,比如说是否写大括号、是否写冒号、是否写分号等等;
  4. 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;
}

三、参考资料