Airbnb CSS / Sass 指南
inani
9年前
<h2>目录</h2> <h2>术语</h2> <h3>规则声明</h3> <p>我们把一个(或一组)选择器和一组属性称之为 “规则声明”。举个例子:</p> <pre> <code class="language-css">.listing { font-size: 18px; line-height: 1.2; } </code></pre> <h3>选择器</h3> <p>在规则声明中,“选择器” 负责选取 DOM 树中的元素,这些元素将被定义的属性所修饰。选择器可以匹配 HTML 元素,也可以匹配一个元素的类名、ID, 或者元素拥有的属性。以下是选择器的例子:</p> <pre> <code class="language-css">.my-element-class { /* ... */ } [aria-hidden] { /* ... */ } </code></pre> <h3>属性</h3> <p>最后,属性决定了规则声明里被选择的元素将得到何种样式。属性以键值对形式存在,一个规则声明可以包含一或多个属性定义。以下是属性定义的例子:</p> <pre> <code class="language-css">/* some selector */ { background: #f1f1f1; color: #333; } </code></pre> <h2>CSS</h2> <h3>格式</h3> <ul> <li>使用 2 个空格作为缩进。</li> <li>类名建议使用破折号代替驼峰法。如果你使用 BEM,也可以使用下划线(参见下面的)。</li> <li>不要使用 ID 选择器。</li> <li>在一个规则声明中应用了多个选择器时,每个选择器独占一行。</li> <li>在规则声明的左大括号 { 前加上一个空格。</li> <li>在属性的冒号 : 后面加上一个空格,前面不加空格。</li> <li>规则声明的右大括号 } 独占一行。</li> <li>规则声明之间用空行分隔开。</li> </ul> <p>Bad</p> <pre> <code class="language-css">.avatar{ border-radius:50%; border:2px solid white; } .no, .nope, .not_good { // ... } #lol-no { // ... } </code></pre> <p>Good</p> <pre> <code class="language-css">.avatar { border-radius: 50%; border: 2px solid white; } .one, .selector, .per-line { // ... } </code></pre> <h3>注释</h3> <ul> <li>建议使用行注释 (在 Sass 中是 // ) 代替块注释。</li> <li>建议注释独占一行。避免行末注释。</li> <li>给没有自注释的代码写上详细说明,比如: <ul> <li>为什么用到了 z-index</li> <li>兼容性处理或者针对特定浏览器的 hack</li> </ul> </li> </ul> <h3>OOCSS 和 BEM</h3> <p>出于以下原因,我们鼓励使用 OOCSS 和 BEM 的某种组合:</p> <ul> <li>可以帮助我们理清 CSS 和 HTML 之间清晰且严谨的关系。</li> <li>可以帮助我们创建出可重用、易装配的组件。</li> <li>可以减少嵌套,降低特定性。</li> <li>可以帮助我们创建出可扩展的样式表。</li> </ul> <p>OOCSS,也就是 “Object Oriented CSS(面向对象的CSS)”,是一种写 CSS 的方法,其思想就是鼓励你把样式表看作“对象”的集合:创建可重用性、可重复性的代码段让你可以在整个网站中多次使用。</p> <p>参考资料:</p> <ul> <li>Nicole Sullivan 的 <a href="/misc/goto?guid=4959630086777348387" rel="nofollow,noindex">OOCSS wiki</a></li> <li>Smashing Magazine 的 <a href="/misc/goto?guid=4959630087232313130" rel="nofollow,noindex">Introduction to OOCSS</a></li> </ul> <p>BEM,也就是 “Block-Element-Modifier”,是一种用于 HTML 和 CSS 类名的_命名约定_。BEM 最初是由 Yandex 提出的,要知道他们拥有巨大的代码库和可伸缩性,BEM 就是为此而生的,并且可以作为一套遵循 OOCSS 的参考指导规范。</p> <ul> <li>CSS Trick 的 <a href="/misc/goto?guid=4959670088933323601" rel="nofollow,noindex">BEM 101</a></li> <li>Harry Roberts 的 <a href="/misc/goto?guid=4959670089026816335" rel="nofollow,noindex">introduction to BEM</a></li> </ul> <p>示例</p> <pre> <code class="language-css"><article class="listing-card listing-card--featured"> <h1 class="listing-card__title">Adorable 2BR in the sunny Mission</h1> <div class="listing-card__content"> <p>Vestibulum id ligula porta felis euismod semper.</p> </div> </article> </code></pre> <pre> <code class="language-css">.listing-card { } .listing-card--featured { } .listing-card__title { } .listing-card__content { } </code></pre> <ul> <li>.listing-card 是一个块(block),表示高层次的组件。</li> <li>.listing-card__title 是一个元素(element),它属于 .listing-card 的一部分,因此块是由元素组成的。</li> <li>.listing-card--featured 是一个修饰符(modifier),表示这个块与 .listing-card 有着不同的状态或者变化。</li> </ul> <h3>ID 选择器</h3> <p>在 CSS 中,虽然可以通过 ID 选择元素,但大家通常都会把这种方式列为反面教材。ID 选择器给你的规则声明带来了不必要的高 <a href="/misc/goto?guid=4959670089117721730" rel="nofollow,noindex">优先级</a> ,而且 ID 选择器是不可重用的。</p> <p>想要了解关于这个主题的更多内容,参见 <a href="/misc/goto?guid=4959670089194602894" rel="nofollow,noindex">CSS Wizardry 的文章</a> ,文章中有关于如何处理优先级的内容。</p> <h3>JavaScript 钩子</h3> <p>避免在 CSS 和 JavaScript 中绑定相同的类。否则开发者在重构时通常会出现以下情况:轻则浪费时间在对照查找每个要改变的类,重则因为害怕破坏功能而不敢作出更改。</p> <p>我们推荐在创建用于特定 JavaScript 的类名时,添加 .js- 前缀:</p> <pre> <code class="language-css"><button class="btn btn-primary js-request-to-book">Request to Book</button> </code></pre> <h3>边框</h3> <p>在定义无边框样式时,使用 0 代替 none 。</p> <p>Bad</p> <pre> <code class="language-css">.foo { border: none; } </code></pre> <p>Good</p> <pre> <code class="language-css">.foo { border: 0; } </code></pre> <h2>Sass</h2> <h3>语法</h3> <ul> <li>使用 .scss 的语法,不使用 .sass 原本的语法。</li> <li>CSS 和 @include 声明按照以下逻辑排序(参见下文)</li> </ul> <h3>属性声明的排序</h3> <ol> <li> <p>属性声明</p> <p>首先列出除去 @include 和嵌套选择器之外的所有属性声明。</p> <p>scss .btn-green { background: green; font-weight: bold; // ... }</p> </li> <li> <p>@include 声明</p> <p>紧随后面的是 @include ,这样可以使得整个选择器的可读性更高。</p> <p>scss .btn-green { background: green; font-weight: bold; @include transition(background 0.5s ease); // ... }</p> </li> <li> <p>嵌套选择器</p> <p>_如果有必要_用到嵌套选择器,把它们放到最后,在规则声明和嵌套选择器之间要加上空白,相邻嵌套选择器之间也要加上空白。嵌套选择器中的内容也要遵循上述指引。</p> <p>```scss .btn { background: green; font-weight: bold; @include transition(background 0.5s ease);</p> <p>.icon { margin-right: 10px; } } ```</p> </li> </ol> <h3>变量</h3> <p>变量名应使用破折号(例如 $my-variable )代替 camelCased 和 snake_cased 风格。对于仅用在当前文件的变量,可以在变量名之前添加下划线前缀(例如 $_my-variable )。</p> <h3>Mixins</h3> <p>为了让代码遵循 DRY 原则(Don’t Repeat Yourself)、增强清晰性或抽象化复杂性,应该使用 mixin,这与那些命名良好的函数的作用是异曲同工的。虽然 mixin 可以不接收参数,但要注意,假如你不压缩负载(比如通过 gzip),这样会导致最终的样式包含不必要的代码重复。</p> <h3>扩展指令</h3> <p>应避免使用 @extend 指令,因为它并不直观,而且具有潜在风险,特别是用在嵌套选择器的时候。即便是在顶层占位符选择器使用扩展,如果选择器的顺序最终会改变,也可能会导致问题。(比如,如果它们存在于其他文件,而加载顺序发生了变化)。其实,使用 @extend 所获得的大部分优化效果,gzip 压缩已经帮助你做到了,因此你只需要通过 mixin 让样式表更符合 DRY 原则就足够了。</p> <h3>嵌套选择器</h3> <p>请不要让嵌套选择器的深度超过 3 层!</p> <pre> <code class="language-css">.page-container { .content { .profile { // STOP! } } } </code></pre> <p>当遇到以上情况的时候,你也许是这样写 CSS 的:</p> <ul> <li>与 HTML 强耦合的(也是脆弱的) <em>或者</em></li> <li>过于具体(强大) <em>或者</em></li> <li>没有重用</li> </ul> <p>再说一遍: <strong>永远不要嵌套 ID 选择器!</strong></p> <p>如果你始终坚持要使用 ID 选择器(劝你三思),那也不应该嵌套它们。如果你正打算这么做,你需要先重新检查你的标签,或者指明原因。如果你想要写出风格良好的 HTML 和 CSS,你是 <strong>不</strong> 应该这样做的。</p> <p> </p> <p>来自: <a href="/misc/goto?guid=4959670089278917558" rel="nofollow">http://qianduan.guru/2016/04/08/airbnb-css-style-guide/</a></p> <p>用更合理的方式写 CSS 和 Sass</p> <p>译文 <a href="/misc/goto?guid=4959670089364852999" rel="nofollow,noindex">GitHub 链接</a> ,欢迎各位指正。</p> <p>翻译自 <a href="/misc/goto?guid=4959664944226676394" rel="nofollow,noindex">Airbnb CSS / Sass Styleguide</a></p>