关于CSS自文档的思考使用指南css声明式语言式代码注释_css小白攻略

原文出处 Thoughts on Self-Documenting CSS作者:Keith J. Grant,翻译来源:http://www.zcfy.ccRobert C. Martin写的《Clean Code》是我读过的最好的编程书籍之一,若没有读过,推荐你将它加入书单。注释就意味着代码无法自说明 —— Robert C. MartinMartin在文

关于CSS自文档的思考使用指南css声明式语言式代码注释

作者:Keith J. Grant,翻译来源:http://www.zcfy.cc

关于CSS自文档的思考使用指南css声明式语言式代码注释_css小白攻略

Robert C. Martin写的《Clean Code》是我读过的最好的编程书籍之一,若没有读过,推荐你将它加入书单。

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的早期版本:

// 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: 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文件中创建一些样式规范。如下:

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

海计划公众号
(0)
上一篇 2020/04/05 01:58
下一篇 2020/04/05 01:58

您可能感兴趣的内容

  • input type=file 上传文件,同一个文件第二次上传无反应基础指南_文件小白常识

    用input file上传文件,掉用onchange方法时,多次上传同一个文件时功能失效,不会发送ajax请求input[type=file]使用的是onchange去做,onchange监听的为input的value值,只有再内容发生改变的时候去触发,而value在上传文件的时候保存的是文件的内容,你只需要在上传成功的回调里面,将当前input的value

    2020/03/26
  • javascript是哪个公司设计的?使用指南_语言指南攻略

    javascript是Netscape(网景)公司的Brendan Eich,在网景导航者浏览器上首次设计实现而成。因为Netscape与Sun合作,Netscape管理层希望它外观看起来像Java,因此取名为JavaScript。但实际上它的语法风格与Self及Scheme较为接近。1995年,Netscape招募了Brendan Eich,目标是把Sch

    2020/03/24
  • 吾道新手入门_强大的PPT幻灯片协作工具,轻松创建优秀作品

    吾道新手入门 官方网址:http://www.woodo.cn/ 简介描述:强大的PPT幻灯片协作工具,轻松创建优秀作品 一款全新的office生产力工具,支持演示文稿、PPT模板…

    2020/03/10
  • CssMatic菜鸟教程在线CSS网页设计工具

    CssMatic入门指南 官方网址:https://www.cssmatic.com/ 简介描述:在线CSS网页设计工具 在线CSS网页设计工具是一个非营利性的网站设计师在线开发工…

    2020/03/06
  • JavaScript中fetch接口的用法使用指南攻略_fetch指南教程

    如果看网上的fetch教程,会首先对比XMLHttpRequest和fetch的优劣,然后引出一堆看了很快会忘记的内容(本人记性不好)。因此,我写一篇关于fetch的文章,为了自己看着方便,毕竟工作中用到的也就是一些很基础的点而已。fetch,说白了,就是XMLHttpRequest的一种替代方案。如果有人问你,除了Ajax获取后台数据之外,还有没有其他的替

    2020/04/03
  • nginx负载均衡配置小白攻略_负载均衡小白教程

    本章给大家带来nginx负载均衡的相关配置讲解,首先大家先看下面的示意图:如上图所示;当客户端发起http请求时,先经过nginx服务器处理并重新分发请求;并下发给不同的服务器,从而实现nginx的负载均衡的简单应用。nginx配置 upstream www.xyqmw.com {server 111.231.197.74:8080 weight=

    2020/03/24
  • Webpack知识点小白攻略_Webpack小白知识

    Webpack从基础概念到项目配置,涉及知识点较多,现将学习使用过程中遇到内容记录下来,方便以后速查。1.Webpack是什么?Webpack是一个模块打包工具,在Webpack里一切文件皆模块。通过loader转换文件,通过plugin注入钩子,最后输出由多个模块组合的文件。Webpack专注构建模块化项目。Webpack可以看作是模块打包机:它做的事情是

    2020/03/26
  • Flutter For Web基础指南_Flutter基础入门

    用来构建漂亮、定制化应用的跨平台的 UI 框架 Flutter 现在已经支持 Web 开发了。我们很高兴推出了一个预览版的 SDK 可以让开发者直接使用 Flutter UI 和业务逻辑代码构建 web 应用在浏览器中运行起来。Flutter 在 Web端的雄心自从去年第一个公测版本推出之后,开发者使用 Flutter 构建跨 IOS 和 Android 的

    2020/03/29
  • CSS简介小白知识_简介菜鸟攻略

    什么是CSS层叠样式表(英文全称:Cascading Style Sheets)是一种用来表现HTML(标准通用标记语言的一个应用)或XML(标准通用标记语言的一个子集)等文件样式的计算机语言。CSS不仅可以静态地修饰网页,还可以配合各种脚本语言动态地对网页各元素进行格式化。CSS 能够对网页中元素位置的排版进行像素级精确控制,支持几乎所有的字体字号样式,拥

    2020/03/23
  • Promise对象 3 种妙用指南攻略_Promise指南攻略

    作为一个前端,说不了解 Promise 对象用法的基本不存在,这里就不对功能用法进行介绍了。但本文将会讲述你可能不知道的 Promise 3 种奇妙用法。当然,每种用法都会有其适用的特殊场景。Promise 对象是可以缓存需求对于一个对象而言,能够被缓存并不是一件难以理解的事情。缓存使用的意义往往是为了解决性能问题。而对于一个特定请求的 Promise 对象

    2020/03/20
  • 解决webapck多页面内存溢出零基础入门_页面入门百科

    因为自己的项目是基于vue-cli3进行开发,所以这里只讨论这种情况下的解决办法 ,在进行多页面开发的时候,项目刚开始阶段,因为文件较少,所以代码编译速度还行,但是随着项目逐渐增大,webpack编译的速度越来越慢,并且经常出现内存溢出的情况。下面就是几种尝试的方法,加快编译的速度增加Node运行内存在Node中通过JavaScript使用内存时只能使用部分

    2020/03/26
  • CSS垂直翻转/水平翻转菜鸟知识_效果入门指南

    一、CSS下兼容性的元素水平/垂直翻转实现随着现代浏览器对CSS3的支持愈发完善,对于实现各个浏览器兼容的元素的水平翻转或是垂直翻转效果也就成为了可能。相关的CSS代码如下:/*水平翻转*/
    .flipx {-moz-transform:scaleX(-1);-webkit-transform:scaleX(-1);-o-transform:scaleX(-

    2020/04/05
  • Vue基于snabbdom做了哪些事攻略教程_vue入门百科

    前言之前有简单看过 Vue patch 部分的源码,了解了是基于 Snabbdom 库实现的。最近想详细了解下 Vue 处理 vnode patch 的整个过程,想知道它在 Snabbdom 之上做了哪些事情?所以带着这个问题,写了这篇文章来记录。Snabbdom 做了哪些事?A virtual DOM library with focus on simpl

    2020/03/29
  • 一年前端职业生涯总结入门百科_职业小白教程

    步入前端已经一年了,是时候写个总结了。一个自不量力的承诺,我步入了前端。去年的10月份来到北京寻找工作,在面试中,总经理问我,能否仿照某网站做出一个官网来,我那个时候连jquery都写不熟练,甚至都不会写,css没有学过,html也知道的可怜,但由于我特别喜欢这个公司,所以当时自不量力的说我可以,于是开始了我人生的前端开发。现在回想起来,真的很庆幸当时的自不

    2020/03/30
  • 12款优秀的 jQuery 动画库入门攻略_动画指南教程

    Textillate.js介绍:Textillate.js 是一个简单的CSS3文本动画插件。结合了一些非常棒的库,把CSS3 动画轻松应用到任何文本。只需要在项目中简单地引入 textillate.js 和它的依赖文件到你的项目中,就可以开始建立独特的效果。Lazy Line Painter介绍:Lazy Line Painter 这款jQuery插件使

    2020/03/29
  • React Developers的10个超实用神奇工具基础知识_工具基础知识教程

    React是一个用于构建用户界面的JavaScript库。但是,很多人都不知道,其实有非常多的有助于我们更好地使用React,提升用户开发体验的优秀工具。如果您还没有使用过React,或者有可能对使用它感兴趣,当他们问你为什么要使用这个库时,你会怎么说?除了告诉他们React的库有多棒(这应该是第一件事)之外,我还想提到开源社区创建的工具这部分,它将极大地提

    2020/03/26