关于 CSS 编码规范的思考
一、前言
先说明这是一篇规范类文章,主要是在日常的前端工作中遇到的一些问题做个总结。由于本人前后在多个公司经历过项目的开发,对这几家公司的编码规范都有一定的了解,然而近日在公司进行项目开发的过程中发现关于 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;
}
三、参考资料
- 推荐大家使用的CSS书写规范、顺序
- CSS命名规范-BEM
- [译]谷歌 HTML/CSS 规范
- CSS代码规范
上一篇: 十六进制颜色值 - 金块
推荐阅读
-
关于 CSS 编码规范的思考
-
35 岁实现财务*,腾讯程序员手握2300万提前退休?-1000万房产、1000万腾讯股票、加上300万的现金,一共2300万的财产。有网友算了一笔账,假设1000万的房产用于自住,剩下1300万资产按照平均税后20-50万不等进行计算,大约花上26-60年左右的时间才能赚到这笔钱。也就是说,普通人可能奋斗一辈子,才能赚到这笔钱。在很多人还在为中年危机而惶惶不可终日的时候,有的人的35岁,就已经安全着陆,试问哪个打工人不羡慕?但问题是有这样财富积累必然有像样的实力做靠山。没有人可以不劳而获。 看到这里,肯定有人说,那么对于普通人来说,卷可能真就成了唯一的出路。但是卷也有轻松的卷,“偷懒”的卷法,对于程序员而言,刨除掉一时无法改掉的开会传统占用的大部分时间,如何把有限的时间和精力放在真正重要的架构设计、需求设计上,而不是重复的造*,编码、改bug、手动测试。因此在科技改变生活的今天,学会使用AI工具成为程序员们的必备技能。 以全栈式全自动的软件开发工具飞算SoFlu软件机器人为例,作为全球首款面向微服务架构设计和最佳实践的软件机器人,SoFlu软件机器人改变了原来手工编码的作业模式,通过可视化拖拽方式以及参数配置就能实现等同于编写复杂代码的业务逻辑,在设计业务逻辑时就完成了微服务应用开发,做到“业务即图,图即代码”,实现“软件开发,十倍提效”。 而作为飞算SoFlu软件机器人的一个重要组成部分,FuncGPT(慧函数)支持所有类型函数创建。通过自然语言描述Java函数需求,实时生成高质量、高可读性的Java函数代码。生成代码可直接复制到IDEA,或一键导入Java全自动开发工具函数库。 FuncGPT(慧函数)具有五大核心能力: ● 自然语言:通过自然语言即可生成函数,降低软件开发门槛。 ● 秒级函数开发:全自动秒级开发函数,秒级完成,效率千倍提升。 ● 一站式函数开发应用:函数生成即可直接应用,效率、安全有保障。 ● 质量可靠:生成的函数代码符合业界规范、具备良好的可读性,符合最优解。 ● 灵活生成:可以根据开发人员的具体需求生成并支持调整和修改。 以“将文件流转换为File对象”这个需求为例,以下是FuncGPT(慧函数)秒级生成的代码: / 类名:FileConverter // 函数名:convertStreamToFile // 函数功能:将文件流转换为File对象 // POM依赖包:无 import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; public class FileConverter { /** * 将文件流转换为File对象 * @param inputStream 文件流 * @param filePath 文件路径 * @param fileName 文件名 * @return 转换后的File对象 * @throws IOException 如果发生I/O异常 */ public static File convertStreamToFile(InputStream inputStream, String filePath, String fileName) throws IOException { File file = new File(filePath + File.separator + fileName); // 创建File对象 try (FileOutputStream outputStream = new FileOutputStream(file)) { // 创建文件输出流 byte buffer = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { // 从文件流读取数据并写入文件 outputStream.write(buffer, 0, bytesRead); } } return file; // 返回转换后的File对象 } } // 函数示例 // 将文件流转换为File对象示例 // 入参:inputStream,文件流 // 入参:filePath,文件路径 // 入参:fileName,文件名 // 出参:file,转换后的File对象 // 调用示例: // InputStream inputStream = new FileInputStream("example.txt"); // String filePath = "C:\\Users\\User\\Documents"; // String fileName = "example.txt"; // File file = FileConverter.convertStreamToFile(inputStream, filePath, fileName); // System.out.println(file.getAbsolutePath); // 输出结果:例如,将文件流转换为File对象后,文件的绝对路径为:C:\Users\User\Documents\example.txt // 则输出结果为:C:\Users\User\Documents\example.txt 通过分析,不难发现以上代码:
-
[校园生活] 关于监考的思考 (1)
-
连体网络(双胞胎神经网络)解析 - 关于连体网络的思考
-
新业务建设】关于竞争情报的思考 业务规划与系统建设--以团队为单位
-
关于三体综合征 3 死亡永恒的部分思考
-
关于电影院座位选择的思考
-
像首席技术官一样思考:如何高效管理 30 人的研发团队?-管理越多越轻松。好的研发团队,应该是上拨下用,即下级对上级的向上管理;而不是反过来,总是向下管理,甚至是 CTO 做经理的事,经理做工程师的事,工程师最终会被当成实习生。如果是这样,就会越管越累,不仅团队无法成长,而且团队整天很忙还效率低下,问题一大堆。 有这样一个小故事:一位高级经理下班后帮忙倒垃圾,结果被老板训斥了一顿。这就好比首席技术官做了实习生自己该做的事。事情本身没有对错之分,只是从不同的角度有不同的理解。 古人云:"用人不疑,疑人不用"。在面对自己的研发团队时,应该相信他们能做好,授权一线开发人员充分发挥专业特长,不要限制他们的工作。但在相信他们的同时,也要进行二次确认,始终秉持 "我相信,但我要确认 "的原则和严谨的精神。因为每个人都会犯错和疏忽,通过发挥团队的智慧,团队犯错的机会就会大大减少。比如回归测试、代码审查、开发演示、变更审批等等。 如前所述,每个人都难免会犯错。但作为管理者,你所设计和商定的流程不能出错。管理者的每一个决定和沟通都应该经过深思熟虑。就像红绿灯的交通设计,某辆车不小心闯红灯可能会扣分,但红绿灯的设计一定要正确、人性化、统一。再比如,开发人员可能会因为疏忽大意写出 bug,但研发流程的设计和上线流程的发布不能有任何差错。因此,流程体系的设计,一方面要结合当前团队规模、业务特点和需要重点解决的问题来设计,另一方面也要在人员防错、效率提升、发挥团队集体智慧等维度进行综合考量。应该站在更高更抽象的角度去思考,不断思考一个倍受欢迎的园区应该如何设计,思考一个灵动、经典、永恒的建筑应该遵循怎样的模式,思考一个成功、优秀、卓越的研发团队应该需要怎样的流程和制度。 最后,反馈很重要。向上汇报很重要,向下反馈也很重要。能够保持顺畅的双向反馈和闭环管理,对研发团队的协作和沟通有着非常明显的积极作用。在向上汇报方面,要培养团队在正式汇报、会议汇报、私下沟通、书面总结、非正式场合等方面的沟通能力,提醒下属报喜也要报忧。凡事先记录,再跟进,最后反馈。反馈很重要,主动汇报更难得。 另一方面,同时也不要忽视向下反馈。好的爱,是双向的。团队也是如此,没有严格的上下级之分,只是分工和角色不同而已。作为管理者,不必总保持一种 "神秘感",让人 "捉摸不透 "才是牛。当团队做得好或有人做得好时,要记得在公开或私下场合给予肯定和赞许。业务有增长、业绩有提升时,别忘了给团队一些鼓励,或者安排一次下午茶或聚餐。在例会或正式会议上,也可以同步向大家传达一些重要信息和高层指示。"欲速则不达,欲远则同行"。 当向上汇报、向下反馈的沟通闭环形成后,同时结合前面研发过程的管理闭环,双管齐下,就能形成良性循环。如此反复,持之以恒,优秀卓越的研发团队,必将呈现。 能力、产出和效率 接下来,继续重复关于能力、产出和效率的话题。 站在不同的角色,以及一个企业经营、生存和发展所需要的基础上,我把研发生产力分为三个层次,分别是:一线员工关心的研发能力、管理层关心的软件产出和操作人员关心的企业生产效率。简单概括就是:既要把工作做好,又要能出成果,还要能帮企业赚钱。
-
关于 css :last-child、:first-of-type、:nth-last-of-type 的八个结构伪类选择器
-
关于 ASP.NET Core WebSocket 实现集群的思考