RSCSS,简单有效的CSS命名规范

Reasonable System for CSS Stylesheet Structure. A set of simple ideas to guide your process of building maintainable CSS

RSCSS不是什么框架,而是一套可以帮助你写出可维护 css 代码的  想法,或说规范。

一、组件-Components

以组件化的方式思考。把 UI 上每一块内容  抽象成一个“component”,如  下图所示:

如何命名组件

使用至少两个单词来命名组件,并且单词之间使用连字符-连接,举例如下:

  • 一个点赞按钮(.like-button
  • 一个搜索表单(.search-form
  • 一个新闻文章卡片 (.article-card

二、元素-Elements

元素包含在组件之内,如  下图所示:

如何命名元素

以一个单词命名元素。

.search-form {
  > .field {
    /* ... */
  }
  > .action {
    /* ... */
  }
}

元素选择器

 尽可能使用子元素选择器(直接后代选择器)>。这比后代选择器更精确,可以避免  意外的样式干扰,执行性能上也会更好。

.article-card {
  .title {
    /* okay */
  }
  > .author {
    /* ✓ better */
  }
}

拼接多个单词

 对于某些必须使用两个单词表达的元素,直接拼接单词而不使用连字符或下划线。

.profile-box {
  > .firstname {
    /* ... */
  }
  > .lastname {
    /* ... */
  }
  > .avatar {
    /* ... */
  }
}

 避免标签选择器

 尽可能使用 class 选择器。标签选择器虽然也能完成工作,但性能上会差一些,并且没有 class 选择器那么具有描述性。

.article-card {
  > h3 {
    /* ✗ avoid */
  }
  > .name {
    /* ✓ better */
  }
}

三、变体-Variants

组件和元素都有可能存在变体,如下图所示:

如何命名变体

在变体的 class 名之前加上连字符-前缀。

.like-button {
  &.-wide {
    /* ... */
  }
  &.-short {
    /* ... */
  }
  &.-disabled {
    /* ... */
  }
}

元素变体

元素也可能有变体。

.shopping-card {
  > .title {
    /* ... */
  }
  > .title.-small {
    /* ... */
  }
}

选择连字符-作变体前缀的原因

  •  能够清晰地和元素命名区别开。
  • class 命名只能以字母,-或者_开头。
  • 连字符-比下划线_更方便键盘输入。
  • 类似于 UNIX 命令(gcc -O2 -Wall -emit-last)。

四、嵌套组件-Nested components

<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;
  }
}

五、布局设计-Layouts

避免  一些布局属性

组件应该能够尽可能多地在各种上下文中复用。因为最好避免在组件上使用以下一些属性。

  • Positioning (position, top, left, right, bottom)
  • Floats (float, clear)
  • Margins (margin)
  • Dimensions (width, height) *

固定的大小

对于用户头像或者 logo 之类的组件可以使用固定的大小。

在父容器内使用布局

如果你需要使用以上的一些属性来完成工作,可以在组件所在的上下文环境中使用布局属性。在下面的  示例代码中,widthfloat属性都是应用在list组件内的,而不是直接修改组件自身。

.article-list {
  & {
    @include clearfix;
  }

  > .article-card {
    width: 33.3%;
    float: left;
  }
}

.article-card {
  & {
    /* ... */
  }
  > .image {
    /* ... */
  }
  > .title {
    /* ... */
  }
  > .category {
    /* ... */
  }
}

六、帮助类-Helpers

对于一些常用样式,比如左浮动有浮动,可以写一些通用的帮助类。但这些类名应该组织在一个单独的文件中。这些类名以下划线_开头,通常需要在属性后加!important标记。请谨慎使用这些帮助类。

._unmargin {
  margin: 0 !important;
}
._center {
  text-align: center !important;
}
._pull-left {
  float: left !important;
}
._pull-right {
  float: right !important;
}

如何命名帮助类

使用下划线_前缀来命名。这可以使帮助类和组件变体的类名有明显的区别。并且,下划线看上去有点丑,这是有意为之的,目的是告诫开发者不要过多地使用帮助类。

如何组织帮助类

把所有的帮助类放在一个叫helpers的文件中。虽然你可以把它们分散在多个文件中,但请记住尽可能地减少帮助类的体量。

七、CSS 的组织结构-CSS structure

一个组件对应一个文件

对于每一个组件,相关的  样式放在各自独立的文件中。

/* 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 的比较

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>

九、总结

  • 以组件的方式去思考,并且用两个单词命名组件(.screenshot-image)
  • 组件  拥有元素,使用一个单词命名元素(.blog-post > .title)
  • 使用带连字符前缀的类来命名变体(.shop-banner.-with-icon)
  • 组件可以嵌套
  • 为了让事情更简单,你可以扩展自己的规则
Topic:#css