Reasonable System for CSS Stylesheet Structure. A set of simple ideas to guide your process of building maintainable CSS.
这是官网给的定义,RSCSS
不是什么框架,而是一套可以帮助你写出可维护css代码的想法,或说规范。
以组件化的方式思考。把UI上每一块内容抽象成一个“component”,如下图所示:
使用至少两个单词来命名组件,并且单词之间使用连字符-
连接,举例如下:
.like-button
).search-form
).article-card
)元素包含在组件之内,如下图所示:
以一个单词命名元素。
.search-form {
> .field { /* ... */ }
> .action { /* ... */ }
}
尽可能使用子元素选择器(直接后代选择器)>
。这比后代选择器更精确,可以避免意外的样式干扰,执行性能上也会更好。
.article-card {
.title { /* okay */ }
> .author { /* ✓ better */ }
}
对于某些必须使用两个单词表达的元素,直接拼接单词而不使用连字符或下划线。
.profile-box {
> .firstname { /* ... */ }
> .lastname { /* ... */ }
> .avatar { /* ... */ }
}
尽可能使用class选择器。标签选择器虽然也能完成工作,但性能上会差一些,并且没有class选择器那么具有描述性。
.article-card {
> h3 { /* ✗ avoid */ }
> .name { /* ✓ better */ }
}
组件和元素都有可能存在变体,如下图所示:
在变体的class名之前加上连字符-
前缀。
.like-button {
&.-wide { /* ... */ }
&.-short { /* ... */ }
&.-disabled { /* ... */ }
}
元素也可能有变体。
.shopping-card {
> .title { /* ... */ }
> .title.-small { /* ... */ }
}
-
作变体前缀的原因-
或者_
开头。-
比下划线_
更方便键盘输入。gcc -O2 -Wall -emit-last
)。<div class='article-link'>
<div class='vote-box'>
...
</div>
<h3 class='title'>...</h3>
<p class='meta'>...</p>
</div>
有时候不可避免要嵌套组件。以下是一些好的做法建议。
嵌套在一个组件内的组件外观可能会和独立使用时有所区别。避免在容器组件内直接修改该组件的样式.
.article-header {
> .vote-box > .up { /* ✗ 避免这样做 */ }
}
更好的替代方案是,给组件增加一个变体class,并且应用该class。如下所示:
<div class='article-header'>
<div class='vote-box -highlight'>
...
</div>
...
</div>
.vote-box {
&.-highlight > .up { /* ... */ }
}
有时,嵌套组件会导致html代码臃肿丑陋。
<div class='search-form'>
<input class='input' type='text'>
<button class='search-button -red -large'></button>
</div>
你可以使用css预处理器的@extend
语法来优化代码。
<div class='search-form'>
<input class='input' type='text'>
<button class='submit'></button>
</div>
.search-form {
> .submit {
@extend .search-button;
@extend .search-button.-red;
@extend .search-button.-large;
}
}
组件应该能够尽可能多地在各种上下文中复用。因为最好避免在组件上使用以下一些属性。
对于用户头像或者logo之类的组件可以使用固定的大小。
如果你需要使用以上的一些属性来完成工作,可以在组件所在的上下文环境中使用布局属性。在下面的示例代码中,width
和 float
属性都是应用在list
组件内的,而不是直接修改组件自身。
.article-list {
& {
@include clearfix;
}
> .article-card {
width: 33.3%;
float: left;
}
}
.article-card {
& { /* ... */ }
> .image { /* ... */ }
> .title { /* ... */ }
> .category { /* ... */ }
}
对于一些常用样式,比如左浮动有浮动,可以写一些通用的帮助类。但这些类名应该组织在一个单独的文件中。这些类名以下划线_
开头,通常需要在属性后加!important
标记。请谨慎使用这些帮助类。
._unmargin { margin: 0 !important; }
._center { text-align: center !important; }
._pull-left { float: left !important; }
._pull-right { float: right !important; }
使用下划线_
前缀来命名。这可以使帮助类和组件变体的类名有明显的区别。并且,下划线看上去有点丑,这是有意为之的,目的是告诫开发者不要过多地使用帮助类。
把所有的帮助类放在一个叫helpers
的文件中。虽然你可以把它们分散在多个文件中,但请记住尽可能地减少帮助类的体量。
对于每一个组件,相关的样式放在各自独立的文件中。
/* css/components/search-form.scss */
.search-form {
> .button { /* ... */ }
> .field { /* ... */ }
> .label { /* ... */ }
// variants
&.-small { /* ... */ }
&.-wide { /* ... */ }
}
在sass,stylus等预编译语言中,可以使用通配符引入所有组件样式。
@import 'components/*';
使用最多一层嵌套。因为过多的嵌套容易引起混乱以致难以维护。
/* ✗ Avoid: 3 levels of nesting */
.image-frame {
> .description {
/* ... */
> .icon {
/* ... */
}
}
}
/* ✓ Better: 2 levels */
.image-frame {
> .description { /* ... */ }
> .description > .icon { /* ... */ }
}
BEM很不错,但有些人可能会讨厌它不合常规的语法。RSCSS基本符合BEM的思想,但语法上有区别。
<!-- BEM -->
<form class='site-search site-search--full'>
<input class='site-search__field' type='text'>
<button class='site-search__button'></button>
</form>
<!-- rscss -->
<form class='site-search -full'>
<input class='field' type='text'>
<button class='button'></button>
</form>