关于CSS自文档的思考_css声明式语言式代码注释
obert C. Martin写的《Clean Code》是我读过的最好的编程书籍之一,若没有读过,推荐你将它加入书单。
注释就意味着代码无法自说明 —— Robert C. Martin
Martin在文中详细讨论了代码注释,我不会完全重复他的话。简而言之,他的意思就是,这些注释是注定会过时的。程序执行时会忽视注释,所以无法保证这些说明注释会准确的描述代码作用。所以最好的方式是让代码自说明,如此,按照代码逻辑,程序员和程序获取到的信息是一致的。
思考如下代码:
// Check to see if the employee is eligible for full benefits
// 检查员工是否有资格获取全部福利
if ((employee.flags & HOURLY_FLAG) && (employee.age > )) {
…
}
注释有用么?当然有用,但下面的方式可能更好:
if (employee.isEligibleForFullBenefits()) {
…
}
代码需要“言行一致”,注释是能够被命名良好的函数或变量取代的。Martin的意思并不是说永不使用注释,而是应该尽量避免写注释,注释就意味着代码无法自说明。
那么对CSS而言呢?
我非常赞同Martin关于注释的看法。当涉及到声明式的语言如CSS时,就发现了一些有趣的地方。声明式语言式必须符合对应格式的,而CSS选择器基本是由HTML结构决定的。对这种代码结构,我们能做的不多,这是否意味着CSS代码必须注释满天飞?
额,也许吧。有很多的理由使用注释,且注释的写法也有很多。让我们来看一些注释,思考这些注释是否应该添加。先从答案显然的开始吧,然后一步步深入到不那么好判断的。
不好:多此一举的注释
任何语言,多此一举的注释都是多余的,如下的示例出自Bootstrap3的早期版本:
// Addresses
address {…}
显然,address是关于地址的选择器
// Unordered and Ordered lists
ul,
ol {…}
还有?
// Blockquotes
blockquote {…}
赶紧停!
千万不要写那种注释,赶紧删掉这些多余的东西,它仅仅是在重复代码而已。当然,新版本的Bootstrap已经删除掉大部分多此一举的无用注释了。
不好: 块分隔注释
对CSS而言,块分隔注释是非常特殊的,如下:
/* -----------------
* TOOLTIPS
* ----------------- */
这种注释能把我逼疯。我能想到为什么会写下这种注释:有时候我们的CSS会写得非常长,当在超过千行的文件内查找时,就需要这种带特殊标志的注释来帮助快速搜索。
但事实上,很长很长的CSS文件已经不再流行了。若你的项目确实需要这种很大的CSS文件,它应该是由多个小的部分,通过CSS预处理工具组合而成的。
不好:解释语法
又要用Bootstrap举例了,以下代码出自 _tooltips.scss:
// Allow breaking very long words so they don't overflow the tooltip's bounds
// 设置长单词换行
word-wrap: break-word;
这种方式和“多此一举的注释”类似,注释解释word-wrap属性的作用。这里有一篇文章讲到这种注释为什么不需要的原因,注释应该解释“为什么”,而不是“是什么”,即说明原因而不是说明作用(Why, not what)。
此处有一个例外,由于CSS有很多属性,也许有些属性是你完全不知道的,那么你用这种注释是正常的。
不好:对库进行介绍
如下是Bootstrap tooltips.scss文件的另一段注释:
// Our parent element can be arbitrary since tooltips are by default inserted as a
// sibling of their target element. So reset our font and text properties to avoid
// inheriting weird values.
// 由于提示框会被默认插入到目标元素后作为一个兄弟元素,
// 所以需要重置提示框的字体属性避免从父元素继承样式影响。
@include reset-text();
font-size: $font-size-sm;
这条注释很有意思,看起来似乎并不违反“说明原因而不是说明作用?”规则,它表明由于可能会被一些意料之外的继承字体属性影响,所以用导入的方式来重置字体属性。
但进一步来看,显然在文件头导入重置样式的唯一的解释就是担心被继承样式影响。
所以,我认为这种注释也是不需要的,因为导入函数名字已经说明用途了,尽量让函数名切合作用,如reset-inherited-font或类似的名字,不仅清晰说明了用途还是说明了原因。这个是一个函数调用,函数名已经足够解释了。优先用这种方式来说明用途可以替代一些注释。
CSS预处理器让CSS更接近传统编程语言。尽可能使用命名良好且有意义的变量和函数,这样能让代码更清晰。
不好: 过时的注释
.dropdown-header {
…
white-space: nowrap; // as with > li > a
}
“as with > li > a”是什么意思?我第一反应就是也许在文件中还有一个> li > a的选择器,而这行代码就是指那个选择器。也许文件中有一段注释会专门解释为何这样写,但我将文件重头到尾都看了一边,发现并没有这个选择器。文件只有一个.dropdown-item选择器下有一个nowrap属性,也许是就是指这个?或者也许这段注释是指某行已经被删除的代码或引入其他文件中的代码?若想要彻底弄清楚这个注释的作用,唯一的方法就是翻遍整个git记录了吧。
这是一个过时的注释,也许它以前是有用的,但却长时间没有用到,所以过时了。这也许就是为什么Robert Martin对注释的看法:若注释对应的代码更新了注释就没用了,甚至更糟糕,注释可能会将你引到错误的方向。若发现这样的注释,一定要删掉。它完全没用,而且会浪费时间去思考到底有啥用?
有时有用的:有特殊意义的注释
如下是一段带注释的代码:
.dropdown-item {
display: block;
width: %; // For `<button>`s
padding: $dropdown-item-padding-y $dropdown-item-padding-x;
clear: both;
font-weight: $font-weight-normal;
color: $dropdown-link-color;
text-align: inherit; // For `<button>`s
white-space: nowrap;
background: none; // For `<button>`s
border: ; // For `<button>`s
}
这样的注释就是有用的,它们能告诉我们,这些特定的属性是为覆盖<button>样式而写的。这样的注释就是有用的,因为有时候代码的意图不是那么显而易见的。
但此时也需要问一个问题:有什么办法能让代码自说明呢?需要可以考虑将这些特定的属性移到第二个选择器中,专门为这些按钮设置的选择器。
.dropdown-item {
display: block;
padding: $dropdown-item-padding-y $dropdown-item-padding-x;
clear: both;
font-weight: $font-weight-normal;
color: $dropdown-link-color;
white-space: nowrap;
} button.dropdown-item {
width: %;
text-align: inherit;
background: none;
border: ;
}
这样就非常清晰且易于理解,但副作用就是:专门增加了一个特殊的选择器。
而相反,我认为这种方式非常利于使用mixin混入模式。重构为一个函数,该函数能在其他地方定义,并且让代码更清晰。考虑如下代码:
.dropdown-item {
@include remove-button-styles; display: block;
width: %;
padding: $dropdown-item-padding-y $dropdown-item-padding-x;
clear: both;
font-weight: $font-weight-normal;
color: $dropdown-link-color;
white-space: nowrap;
}
这段代码没有用任何注释,但其功用很清晰,因为它使用的公用函数在其他模块也能用到。我将width:100%保留下来而不是移到函数中,因为若将函数混和代码时,width:100%可能会引起一些其他问题。
在我开始发现“代码异味(Code Smell)”之前,一开始.dropdown-item代码有十行,我非常喜欢用mixin,mixin是一个能极大减少代码行数的好东西,它能让我们快速的知道代码的大致用途。
虽然使用函数重构代码并不是都这样有效,但尽量多用。
好:注解难懂的补丁性的代码
我对注释也不是总那么苛刻的,比如我就很难找到下面的注释的问题,若你曾看过normalize.css的源码,你一定会注意到它满满的注释,不得不说,真是“极好的”注释。
欣赏一番:
/**
* 1. Add the correct box sizing in Firefox.
* FF下正常的盒子模型
* 2. Show the overflow in Edge and IE.
* 在Edge和IE下overflow为visble
*/
hr {
box-sizing: content-box; /* 1 */
height: ; /* 1 */
overflow: visible; /* 2 */
}
若没有这些注释,你永远不知道为何这样写。修复特定浏览器bug的代码往往是晦涩难懂的,常常会被当做无用代码删掉。
由于Normalize库的目标是提供一个完全一致样式环境,所以需要很多这样的注释。选择器都是类型和属性选择器,没有任何class名,同时由于不是可命名的class名,所以自文档非常困难。
如下为另一段Bootstrap的注释:
/* Chrome (OSX) fix for https://github.com/twbs/bootstrap/issues/11245 */
select {
background: #fff !important;
}
一个Github链接,非常有用。即使不打开连接也能知道这儿是一个bug,而且有可能是一个非常难定位的bug。若有需要,可以通过链接获取更多信息。最棒的是,因为没有大段大段的文本去解释bug,所以它并不会打乱代码逻辑,同时也告诉我们哪里可以获取更多信息。若使用项目与事务跟踪工具如JIRA,那么可以直接在注释中与编号关联起来。
当然,不是每个打补丁的代码都要这样注释,但若bug不是那么容易发现,而且与浏览器怪癖有关,那么还是这样注释吧。
好:指令式注释
一些工具如KSS , 会在CSS文件中创建一些样式规范。如下:
/*
Alerts
An alert box requires a contextual class to specify its importance.
一个警告信息框需要与语境有关的的类来指定其重要性
熊猫办公 https://www.wode007.com/sites/73654.html
Markup:
<div>
Take note of this important alert message.
</div> alert-success - Something good or successful 好的或成功的
alert-info - Something worth noting, but not super important 不那么重要的
alert-warning - Something to note, may require attention 需要被提示并记录,需要引起注意的
alert-danger - Something important. Usually signifies an error. 非常重要的,常用于错误 Styleguide Alerts
*/
这不仅仅是注释,这是规范,它能被KSS解析并用于生成HTML。这已经算是项目文档的一部分了,而且不得不说,这比手动创建一个分离的HTML文件要好很多,因为其在同一个文件内且始终与代码相匹配。
另外一种指令式注释为许可信息,当使用第三方库并在注释中注明许可信息时,一般都需要包含。
而我贴出Robert Martin关于注释的话时 Robert Martin 的话 ,似乎应该解释一下,但没有那么做。因为我认为这是一句容易理解的话,若你还在代码中到处写注释,那么请先思考是否合理。
关于CSS自文档的思考_css声明式语言式代码注释的更多相关文章
- css参考文档; 官方英文说明!! 1 margin padding 百分比参照物 2 margin值为auto时的说明 3 div在div里垂直居中方法 4 dispaly:flex说明
css参考文档 http://css.doyoe.com/ 两篇很好的文章:(下面的css官方英文说明链接 有时间可以研究下 http://www.w3.org/TR/css3-box/ ...
- [中文版] 可视化 CSS References 文档
本文分享了我将可视化 CSS References 文档翻译成中文版的介绍,翻译工作还在陆续进行中,供学习 CSS 参考. 1. 可视化 CSS References 文档介绍 许多 CSS 的文档都 ...
- css标准文档流
css标准文档流 所谓的标准文档流指的是网页当中的一个渲染顺序,就如同人类读书一样,从上向下,从左向右.网页的渲染顺序也是如此.而我们使用的标签默认都是存在于标准文档流当中. 标准文档流当中的特性 空 ...
- 3 、操作元素 (属性 CSS 和 文档处理)
3 操作元素-属性 CSS 和 文档处理 3.1 属性操作 $("p").text() $("p").html() $(":check ...
- HTML&CSS基础-文档声明
HTML&CSS基础-文档声明 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.HTML的发展 1993年6月: HTML第一个版本 1995年11月: HTML2.0 ...
- Ext JS 6学习文档-第8章-主题和响应式设计
Ext JS 6学习文档-第8章-主题和响应式设计 主题和响应式设计 本章重点在 ExtJS 应用的主题和响应式设计.主要有以下几点内容: SASS 介绍和入门 主题 响应式设计 SASS 介绍和入门 ...
- 前端(八)—— 高级布局:文档流、浮动布局、流式布局、定位布局、flex布局、响应布局
高级布局:文档流.浮动布局.流式布局.定位布局.flex布局.响应布局 一.文档流 1.什么是文档流 将窗体自上而下分成一行一行,块级元素从上至下.行内元素在每行中从左至右的顺序依次排放元素 2.本质 ...
- css脱离文档流
作者:张秋怡链接:http://www.zhihu.com/question/24529373/answer/29135021来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出 ...
- CSS脱离文档流&浮动
什么是文档流? 将窗体从上至下分成一行一行,并在每行中按从左至右依次排放元素,称为文档流,也称为普通流.这个应该不难理解,HTML中全部元素都是盒模型,盒模型占用一定的空间,依次排放在HTML中,形成 ...
随机推荐
- 【JavaScript】原生js实现:强制保留2位小数(由于toFixed()报错)
function decimal(x) { var f = parseFloat(x); if (isNaN(f)) { alert("请输入数字!"); return; } va ...
- Hive的压缩存储和简单优化
一.Hive的压缩和存储 1,MapReduce支持的压缩编码 压缩格式 工具 算法 文件扩展名 是否可切分 对应的编码/解码器 DEFLATE 无 DEFLATE .deflate 否 org.ap ...
- js实现点击切换checkbox背景图片
在制作网页的过程中,经常需要实现点击切换背景图片的效果,本文关注的是表单中checkbox背景图片切换的实现.如图,在输入用户名和密码后,用户需要选择是否记住密码 图片背景为白色表示未勾选状态 ,背景 ...
- Crypto++ AES 加密解密流程
// aesdemo.cpp : 定义控制台应用程序的入口点. // #include <stdio.h>#include <tchar.h>#include <iost ...
- .net core 部署到windows服务上的方法
前言 Net core 项目部门在Windows有很多种方式,大致有以下几种, dotnet 命令, iis(windowshosts), 一些开源的应用容器(docker ) 基于一些exe 程序, ...
- 漏洞复现-Office远程代码执行漏洞 (CVE-2017-11882&CVE-2018-0802)
漏洞原理 这两个漏洞本质都是由Office默认安装的公式编辑器(EQNEDT32.EXE)引发的栈溢出漏洞(不要问什么是栈溢出,咱也解释不了/(ㄒoㄒ)/~~) 影响版本 Office 365 Mic ...
- Python在Linux下编译安装
[准备环境] Linux centos [前言] 1 linux下默认带Python,带的是2.7版本的 ,如果需要升级版本,需要把系统的自带的Python改名或者卸载,再次安装你所需要的Python ...
- python测试标准库doctest
引言: doctest是python的一个测试用标准库. 顾名思义,这个模块会寻找程序里面看起来像交互式Python会话的文本片段,然后运行这个会话,来判断实际运行结果和你希望的结果是否一致. 这个模 ...
- OS_页面置换算法:C++实现
一.实验目的: 通过模拟实现请求页式存储管理的几种基本页面置换算法,了解虚拟存储技术的特点,掌握虚拟存储请求页式存储管理中几种页面置换算法的基本思想和实现过程,并比较它们的效率. 二.实验内容: 本实 ...
- 004.OpenShift命令及故障排查
一 CLI访问OpenShift资源 1.1 资源操作 OCP将OpenShift集群中的为由主节点管理的对象统称为资源,如:node.service.pod.project.deployment.u ...