在前端开发中,我们会尝试去定一些规则和约定,来让项目质量更高,更易于维护。而对于这些规则和约定,我们也会希望它内容简单,容易理解。
rscss和rsjs是一套比较新,也比较小巧的前端开发规则和约定,其中rs代表Reasonable System,所以可以理解为,追求“合理”的css和js。本文除了介绍它们,还会有一点补充以及我自己的看法,也推荐你点击链接阅读原作者给出的完整内容。
从css的疑问开始
rscss希望有效地改善写css中的这样几个常见问题(css哲学三问):
- 这个class到底什么意思?
- 这个class还有地方用到吗?
- 我新写的这个class,会有冲突吗?
组件原则
rscss首先推崇的是以组件(Components)为基础的思考方式。在各类前端框架中,几乎都可以看到组件,如Bootstrap和Materialize:
一个组件是这样的感觉:
小到一个按钮,大到整个web应用,可见的视觉元素都可以这样当做一个组件。
组件的命名
rscss推荐组件至少使用两个单词的命名,中间用短横线(-
)连接:
.search-form { /* ... */ } .article-card { /* ... */ }
组件的元素
组件内部的更细小的部分,当做组件的元素(Elements)。
元素的命名
为了和前面的组件区分开来,元素的命名只使用一个单词。
显然,只有一个单词是很容易冲突的,因此rscss建议以关系选择符把元素和组件关联起来:
.search-form > .field { /* ... */ } .search-form > .action { /* ... */ }
推荐子选择符 > 而不是包含选择符 (空格),以更好地避免冲突:
.article-card .title { /* okay */ } .article-card > .author { /* "htmlcode">.profile-box > .firstname { /* ... */ }为每一个组件的元素使用class名,不要使用标签选择符。有名字的元素会更有语义。
多种属性或状态
无论是组件还是元素,都可以有多种属性或状态(Variants,也可以叫变体):
属性或状态的命名
使用短横线(-)开头来命名表示属性或状态的class。
/* component variants */ .like-button.-wide { /* ... */ } .like-button.-disabled { /* ... */ } /* element variants */ .shopping-card > .title.-small { /* ... */ }对命名方式的解释
rscss推荐的短横线作为前缀的class名可能会让你有一点惊讶,可以这样写的吗?答案是的确可以,而且搭配得还相当巧妙。为什么这么说呢?请看w3c对css标识符的解释:
In CSS, identifiers (including element names, classes, and IDs in selectors) can contain only the characters [a-zA-Z0-9] and ISO 10646 characters U+0080 and higher, plus the hyphen (-) and the underscore (_); they cannot start with a digit, two hyphens, or a hyphen followed by a digit.
其中ISO 10646等同于Unicode。可以看到,w3c特意在css标识符一般使用的英文字母、数字以及一部分Unicode字符(U+0080以上)之外,提到了短横线(-)和下划线(_)也是可用的。
以短横线作为前缀的class名相当于有了一个特殊的标记,一眼就可以提醒你这是一个表示属性或状态的class。
组件嵌套
组件是可以嵌套的。
对应html类似这样:
<div class="article-link"> <div class="vote-box"> ... </div> <h3 class="title">...</h3> <p class="meta">...</p> </div>嵌套中的属性或状态
当一个组件位于另一个组件内部的时候,可能会想要这个组件表现得特别一点。这个时候,建议不要使用关系选择符把它们耦合在一起:
.article-header > .vote-box > .up { /* "htmlcode"><div class="article-header"> <div class="vote-box -highlight"> ... </div> ... </div>然后以这个class为基础来定义特别的样式:
.vote-box.-highlight > .up { /* ... */ }这样做的目的是让一个组件的样式不依赖其所处的位置。OOCSS的原则之一,Separate container and content,也是这样的理念。
布局思想
rscss推荐除一些具有固定宽高的特定元素(如头像,logo)外,组件本身不定义任何影响布局位置的属性:
- 定位(
position
、top
、left
、right
、bottom
)- 浮动(
float
、clear
)- 外边距(
margin
)- 尺寸(
width
、height
)这样做的意思是说,如果把组件看做一个整体,它应该是自适应的。
需要定义布局位置属性的情况
如果要定义组件的影响布局位置的属性,建议使用关系选择符把组件和它所处的环境关联起来:
.article-list > .article-card { width: 33.3%; float: left; } .article-card { /* ... */ } .article-card > .image { /* ... */ } .article-card > .title { /* ... */ } .article-card > .category { /* ... */ }在上面这段代码可以注意到,“组件本身的外观”与“组件在某一环境中的位置”被明确地分离了。
辅助类
rscss推荐辅助类(Helpers)单独存放一个文件,且class名以下划线(
_
)开头。辅助类也常会用到!important
,对应的,应尽可能少使用辅助类。._pull-left { float: left !important; } ._pull-right { float: right !important; }下划线(_)作为前缀的class名,如前文已经解释过的那样,也是作为一个特殊的标记提醒你这是一个辅助类,请谨慎使用它。
辅助类在前端框架中也很常见。
rscss与其他css理论的比较
rscss的组件(Component),元素(Element)等概念,在BEM、SMACSS这些css理论中也有类似的存在。它们比较起来是这样的:
RSCSS BEM SMACSS Component Block Module Element Element Sub-Component Layout "external nofollow" target="_blank" href="https://github.com/airbnb/javascript">风格指南,因此,rsjs只对一些其他的要点提出建议,如命名空间,文件组织方式。 行为原则
rsjs推荐把由JavaScript实现的交互功能当做一次只影响一个组件(Component)的行为(Behavior)。下面是一个参考示例:
<div class="main-navbar" data-js-collapsible-nav> <button class="expand" data-js-expand>Expand</button> <a href="/">Home</a> <ul>...</ul> </div> /* Behavior - behaviors/collapsible-nav.js */ $(function () { var $nav = $("[data-js-collapsible-nav]"); if (!$nav.length) return; $nav .on("click", "[data-js-expand]", function () { $nav.addClass("-expanded"); }) .on("mouseout", function () { $nav.removeClass("-expanded"); }); });这其中包含了多项建议。
使用data属性
建议使用html5的data自定义属性
data-js-___
来标记和一个行为有关的DOM元素。相比用ID和class来选取元素,这种data属性的形式一方面更具有明确的意义,提醒你这是一个和交互行为有关的元素,另一方面更易于复用,在任何DOM结构里添加这样的data属性即可获得对应的行为。
为每个行为单独建立文件
建议每一个行为对应的JavaScript代码都分离到单独的文件里,并以文件名明示。文件名可以参照
data-js-___
这个属性名里的对应名称,这样,根据属性名就很容易找到对应的JavaScript代码。一个可能的文件目录结构:
└── javascripts/ └── behaviors/ ├── collapsible-nav.js ├── avatar-hover.js ├── popup-dialog.js └── notification.js不使用行内JavaScript
在html中不要以
<script>...</script>
或onclick=""
等形式添加行内JavaScript代码。通过保持行为的逻辑代码独立于html,可以使代码更易于维护。从rsjs的内容来看,在已有React、Vue等库的今天,“行为独立于内容”的约定仍然对传统的以jQuery为主的Web应用有一定意义。
初始数据的获取方式
传统Web站点的一个常见的场景是,后端语言在页面中预先输出某些数据,然后JavaScript会取用它们。你可能见到过下面这样
<script>
标签的实现方式,但显然,根据上一条建议,这是应避免的。<script> window.UserData = { email: "john@gmail.com", id: 9283 } </script>rsjs建议的方案是,如果这些数据只需要一个组件使用,可以利用之前提到的data属性(保存为值),由行为的JavaScript代码来自行取出。
<!-- "user-info" data-js-user-info='{"email":"john@gmail.com","id":9283}'>如果是多个组件使用的数据,可以使用
<head>
里的meta标签。<head> ... <!-- option 1 --> <meta property="app:user_data" content='{"email":"john@gmail.com","id":9283}'> <!-- option 2 --> <meta property="app:user_data:email" content="john@gmail.com"> <meta property="app:user_data:id" content="9283">命名空间
rsjs建议使用尽可能少的全局变量。共用的类,函数,放到单个Object里,比如叫
App
:if (!window.App) window.App = {}; App.Editor = function() { // ... };在多个行为之间可复用的帮助方法,可以单独建立Object,并将它们分文件保存在
helpers/
:/* helpers/format_error.js */ if (!window.Helpers) window.Helpers = {}; Helpers.formatError = function (err) { return "" + err.project_id + " error: " + err.message; };第三方库的处理
rsjs建议如果引入第三方库,也做成组件行为的形式。比如,Select2的功能,可以只影响带有属性
data-js-select2
的元素。// select2.js -- affects `[data-js-select2]` $(function () { $("[data-js-select2]").select2(); });所有第三方库的代码可以集中到一个类似
vendor.js
的文件,并和站点本身的代码各自独立。这样,当站点更新代码的时候,用户可以直接利用缓存,而并不需要再次获取这些第三方库代码。rsjs对自己的归纳
rsjs认为自身的内容更偏向于对开发者友好,也就是更易于维护,而在性能上(对用户友好)可能没有做到最好。以上提到的各项建议,也是有利有弊,rsjs只是在权衡了利弊的基础上得到的更利于长期维护的结论。
rsjs不是万金油,它不适用于单页应用(SPA)等前端功能很复杂的情况。它关注的是的那种多个网页,每个网页一点JavaScript交互的传统网站。
结语
rscss和rsjs所用的“合理”是一个很取巧的表述,不是完美,不是最好,也不是出色,它只是在说希望代码能“合乎道理”。rscss和rsjs大概就是这样,以简约的风格,不长的篇幅,追求着“小而合理”。
目前rsjs还在更新中(work-in-progress),rscss则已经比较成熟。很推荐试试其中你也认为合理的建议!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]