(点击上方公众号,可快速关注)

英文:Keith J. Grant  译文:众成翻译/KING

zcfy.cc/article/thoughts-on-self-documenting-css

Robert 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 > 65)) {  …}

注释有用么?当然有用,但下面的方式可能更好:

if (employee.isEligibleForFullBenefits()) {  …}

代码需要“言行一致”,注释是能够被命名良好的函数或变量取代的。Martin的意思并不是说永不使用注释,而是应该尽量避免写注释,注释就意味着代码无法自说明。

那么对CSS而言呢?

我非常赞同Martin关于注释的看法。当涉及到声明式的语言如CSS时,就发现了一些有趣的地方。声明式语言式必须符合对应格式的,而CSS选择器基本是由HTML结构决定的。对这种代码结构,我们能做的不多,这是否意味着CSS代码必须注释满天飞?

额,也许吧。有很多的理由使用注释,且注释的写法也有很多。让我们来看一些注释,思考这些注释是否应该添加。先从答案显然的开始吧,然后一步步深入到不那么好判断的。

不好:多此一举的注释

任何语言,多此一举的注释都是多余的,如下的示例出自Bootstrap3的早期版本:

// Addressesaddress {…}

显然,address是关于地址的选择器

// Unordered and Ordered listsul,ol {…}

还有?

// Blockquotesblockquote {…}

赶紧停!

千万不要写那种注释,赶紧删掉这些多余的东西,它仅仅是在重复代码而已。当然,新版本的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: 100%; // 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: 0; // 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: 100%;  text-align: inherit;  background: none;  border: 0;}

这样就非常清晰且易于理解,但副作用就是:专门增加了一个特殊的选择器。

而相反,我认为这种方式非常利于使用mixin混入模式。重构为一个函数,该函数能在其他地方定义,并且让代码更清晰。考虑如下代码:

.dropdown-item {  @include remove-button-styles;

  display: block;  width: 100%;  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: 0; /* 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文件中创建一些样式规范。如下:

/*AlertsAn alert box requires a contextual class to specify its importance.一个警告信息框需要与语境有关的的类来指定其重要性

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关于注释的话时,似乎应该解释一下,但我没有那么做。因为我认为这是一句容易理解的话,若你还在代码中到处写注释,那么请先思考是否合理。

觉得本文对你有帮助?请分享给更多人

关注「前端大全」,提升前端技能

淘口令:复制以下红色内容,再打开手淘即可购买

范品社,使用¥极客T恤¥抢先预览(长按复制整段文案,打开手机淘宝即可进入活动内容)

在 css 中什么是好的注释?相关推荐

  1. HTML中注释写法 CSS中注释写法,css注释怎么写?

    什么是CSS注释?CSS文件中注释怎么写?本篇文章将向你介绍css注释的作用及写法,希望对各位有帮助. css注释怎么写? 一:css注释是什么? css注解(css 注解)又被称作CSS注释(css ...

  2. HTML中注释写法 CSS中注释写法,CSS注解语法,HTML中CSS注释

    CSS注释教程篇 一.CSS注解语法 在CSS代码中进行注解注释语法: /* 注解注释内容 */ 二.HTML中CSS注释 我们在HTML中直接使用style标签进行设置CSS样式,那CSS注释注解时 ...

  3. html如何给文字添加阴影效果,css中怎么给字体添加阴影效果

    css中可以使用text-shadow属性给字体添加阴影效果,text-shadow是CSS样式属性单词,是设置对象中文本的文字字体是否有阴影及模糊效果的CSS样式. text-shadow属性的语法 ...

  4. css text top,text-align属性(css中文本对齐属性)

    text-align属性 设置h1.h2.h3元素的文本对齐方法: h1{text-align:center} h2{text-align:left} h3{text-align:right} 亲自试 ...

  5. 再读《精通css》03:引入和注释

    1.3 规划,组织和维护样式表 1.将外部样式表附到页面上有两个方法:     a.链接:<link type="text/css" rel="stylesheet ...

  6. div+css中命名规范

    上次给别人演示div的效果时,写了css样式却一直不能呈现,最后不小心发现自己在写css样式时候,给一个class命名为数字开头的名称,才想起来自己去年刚学习样式表时候也出现此问题,最后被我解决掉的, ...

  7. 【CSS中width、height的默认值】

    对于初学者来说,CSS中的width.height的默认值是很神奇的,因为经常看到如下这样的代码:明明只给一个#father标签(红色的div)设置了一个width,为啥它在浏览器中显示出来是有一个固 ...

  8. php水平线代码,在HTML中水平线标注与代码注释应该如何使用

    这次给大家带来在HTML中水平线标注与代码注释应该如何使用,在HTML中使用水平线标注与代码注释的注意事项有哪些,下面就是实战案例,一起来看一下. 水平线 使用 标签在当前位置绘制一条水平分割线. 例 ...

  9. html中index.css里面写什么,css中z-index是什么意思?

    css中z-index属性的意思:设置元素的堆叠顺序.拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面. 简单的说就是利用这个属性可以把一段文字置于一张图片之上,或者把图片置于文字之上,只要设 ...

最新文章

  1. linux常用文本编辑器nano/vi/vim
  2. qq讨论组显示连接服务器异常,QQ讨论组出现大面积故障 腾讯回应:因服务器异常 已紧急修复...
  3. 年底清理垃圾了,整理了一整套python学习资料无偿送给大家
  4. python连接mysql失败_python连接mysql失败怎么解决
  5. 2 追踪光线=》2.6 反射光线
  6. php-php异步网络通信引擎-服务发现-消息队列 案例
  7. gaster字体转换器_gautami字体
  8. Ubuntu安装配置tftp服务器
  9. C#使用欧姆龙PLC的Fins协议读写PLC地址(基本封装)
  10. 知乎热议 | 何恺明 新作 如何?
  11. R语言 如何合并csv文件(批量读取csv文件)
  12. java 手动触发gc_java触发full gc的几种情况整理
  13. UART、I2C、USB、SPI、CAN、Jtag、PCI/PCIE协议汇总
  14. 统计软件是其他计算机软件吗,电脑统计软件,statistical computing software,音标,读音,翻译,英文例句,英语词典...
  15. Date类型接收空字符串(@InitBinder注解实现)
  16. IMS应用领域|IMS连接器系统使自动驾驶成为可能
  17. Mysql 中的日期时间函数汇总
  18. 直播APP开发时需要注意的问题!
  19. 范蠡《陶朱公生意经》
  20. linux wps 微软雅黑字体,WPS文字技巧—如何在微软雅黑的字体下运用宋体双引号...

热门文章

  1. 学会origin这20个操作,作图快速又完美
  2. 设计模式之 装饰模式
  3. 知识付费网课项目操作模式+精准引流方法分享
  4. 艾达瓦”,变成了“艾达瓦”。是什么解码方式
  5. 唯美的古风句子——喜欢
  6. 英雄联盟哪个服务器最稳定,LOL新人进哪个服务器比较好?当然最后一个啦!个个人善嘴又甜...
  7. web前端页面性能优化(提升页面加载速度)
  8. 有6个人,分成3组,每组2人,共有多少种组合方法?
  9. 2018福建省“百越杯”CTF初赛writeup
  10. rust拆自己家门_rust游戏门怎么拆不掉 | 手游网游页游攻略大全