一套关于构建可维护性的 CSS 的规范。
考虑把 UI 图上的每一块都作为一个单独的组件。
组件命名至少用两个单词,用中划线 - 链接,例如:
like-button
search-form
article-card
元素是组成组件的一部分。
.search-form {
> .field {/*...*/}
> .action {/*...*/}
}
.article-card {
.title {/*这是没有问题的*/}
> .author {/*这是更好的写法*/}
}
.profile-box {
> .firstname {/*...*/}
> .lastname {/*...*/}
> .avatar {/*...*/}
}
.article-card {
> h3 { /* 不要使用标签 */ }
> .name { /* 这样很好 */ }
}
组件可以有多种形式变化,组件的元素也可以有许多变化。
.like-button {
&.-wide { /* ... */ }
&.-short { /* ... */ }
&.-disabled { /* ... */ }
}
.shopping-card {
> .title { /* ... */ }
> .title.-small { /* ... */ }
}
有些时候组件嵌套是必要的,怎么更好的嵌套,这里有一些指南。
<div class="article-link">
<div class="vote-box">
...
</div>
<h3 class="title">...</h3>
<p class="meta">...</p>
</div>
.article-header {
> .vote-box > .up {
/* ✗ avoid this */
}
}
相反,更好的做法是将一个变种类添加到嵌套组件中,并在组件中修改其样式。
.vote-box {
&.-highlight > .up {
/* ... */
}
}
<div class="search-form">
<input class="input" type="text" />
<button class="search-button -red -large"></button>
</div>
这时可以简化组件并使用 CSS 预处理器的继承机制:
<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;
}
}
.article-list {
& {
@include clearfix;
}
> .article-card {
width: 33.3%;
float: left;
}
}
.article-card {
& {
/* ... */
}
> .image {
/* ... */
}
> .title {
/* ... */
}
> .category {
/* ... */
}
}
._unmargin {
margin: 0 !important;
}
._center {
text-align: center !important;
}
._pull-left {
float: left !important;
}
._pull-right {
float: right !important;
}
/* css/components/search-form.scss */
.search-form {
> .button {
/* ... */
}
> .field {
/* ... */
}
> .label {
/* ... */
}
// variants
&.-small {
/* ... */
}
&.-wide {
/* ... */
}
}
@import "components/* */";
/* ✗ Avoid: 3 levels of nesting */
.image-frame {
> .description {
/* ... */
> .icon {
/* ... */
}
}
}
/* ✓ Better: 2 levels */
.image-frame {
> .description {
/* ... */
}
> .description > .icon {
/* ... */
}
}
<article class="article-link">
<div class="vote-box">
<button class="up"></button>
<button class="down"></button>
<span class="count">4</span>
</div>
<h3 class="title">Article title</h3>
<p class="count">3 votes</p>
</article>
.article-link {
> .title {
/* ... */
}
> .count {
/* ... (!!!) */
}
}
.vote-box {
> .up {
/* ... */
}
> .down {
/* ... */
}
> .count {
/* ... */
}
}
在上面这个例子中,如果 .article-link > .count 没有这个子选择器,那这个样式也会应用到 .vote-box .count 上,这也是我们为什么要使用子选择器的原因。
恐惧心理,一些开发者可能害怕应用这些规范,例如:
.alert-box {
}
.alert-card {
}
.alert-block {
}
或者行内组件的命名:
.link-button {
}
.link-span {
}