“Every line of code should appear to be written by a single person, no matter the number of contributors.” —@mdo
- 避免在 CSS 使用 HTML 标签选择器
- 例如,
.o-modal {}要优于div.o-modal {} - 相对于 HTML 标签,你应该优先使用类(除非是重置 CSS 这样的特殊情况)
- 例如,
- 不要使用 id 选择器
#header相比.header太过具体,难以覆盖其样式。- CSS 中使用 id 选择器的更多坏处可以参见这篇文章。
- 嵌套曾测不应该超过 3 层
- 层次嵌套过深意味着太过具体,覆盖其样式时则需要更具体的选择器,这很容易引起维护问题。
- 除伪类选择器和状态选择器外,应尽量避免过度嵌套。
- 嵌套
:hover,:focus,::before等选择器没问题,但是嵌套普通选择器应当避免。
- 不要使用
!important- 永远!
- 如果一定要使用它必须留下足够详细的注释。你应当在使用
!important前尽可能地使用其它方法解决问题。 !important会大幅提升 CSS 规则的优先级,极难覆盖,除非再使用一个!important。
- 不要使用
margin-top- 垂直 margin 会折叠在一起。优先设定
padding-top或者前面元素的margin-bottom。
- 垂直 margin 会折叠在一起。优先设定
- 避免使用属性简称(除非真的有必要)
- 在有些情况下你可以考虑这样使用,比如使用
background: #fff而不是background-color: #fff,但是这样做会覆盖该简写属性所包含的所有属性。(在这个例子中background-image会被覆盖为none。) - 一个简写就能覆盖所有的属性:比如 border, margin, padding, font 等等。
- 在有些情况下你可以考虑这样使用,比如使用
- 四个缩进
- 属性定义中
:后应放置空格- 比如
color: red;而不是color:red;
- 比如
- 定义规则时
{前应有空格.o-modal {而不应该.o-modal{
- 每条 CSS 规则单独成行
- 规则定义结束应在
}后换行 - 聚合规则时,每条规则应单独成行
- 规则定义结尾的
}应单独成行 - .scss 文件的结尾添加空行
- 不要使用多余的空格
- 所有选择器都应该是小写,使用连此符连接,也就是 “spinal case” 表示法。例如:
.my-class-name - 优先使用 Sass 双斜线
//注释,即使块级注释也是如此。 - 零值不需要单位,比如:
margin: 0;而不要margin: 0px; - 样式规则后面应该加上分号
- 小数前面应该保留 0
opacity: 0.4;而不要opacity: .4; - 自选择器前后加上空格,
div > span要优于div>span
- import 语句
- 变量
- 基础样式
- 试验样式
例如:
//------------------------------
// Modal
//------------------------------
@import "../constants";
@import "../helpers";
$DBmodal-namespace: "c-modal" !default;
$DBmodal-padding: 32px;
$DBmodal-background: #fff !default;
$DBmodal-background-alt: color(gray, x-light) !default;
.o-modal { ... }
// Many lines later...
// EXPERIMENT: experiment-rule-name
.o-modal--experiment { ... }
// END EXPERIMENT: experiment-rule-name- 应该在文件的顶部紧跟在 import 后的地方定义变量
- 本地变量前应当加上文件名(SASS 没有文档级变量)
- 例如
business_contact.scss→$business_contact_font_size: 14px;
- 例如
- 本地变量应当遵循蛇形命名
$snake_lowercase - 本地常量应当是大写蛇形
$SNAKE_ALL_CAPS
- 使用颜色变量来定义颜色
- 表示颜色的十六进制数值应当全部小写,如:
#fffff - alpha 通道最多保持两位有效数字。不要省去前面的 0
示例:
// Bad
.c-link {
color: #007ee5;
border-color: #FFF;
background-color: rgba(#FFF, .0625);
}
// Good
.c-link {
color: color(blue);
border-color: #ffffff;
background-color: rgba(#ffffff, 0.1);
}试验性规则应当以注释包裹:
// EXPERIMENT: experiment-rule-name
.stuff { ... }
// END EXPERIMENT: experiment-rule-name属性以及嵌套的声明应当按照以下顺序排列,每种规则间以换行隔开:
- 所有
@规则 - 布局及盒模型规则
- margin, padding, box-sizing, overflow, position, display, width/height 等等
- 排版属性
- 例如 font-*, line-height, letter-spacing, text-* 等等
- 样式属性
- color, background-*, animation, border 等等
- UI 属性
- appearance, cursor, user-select, pointer-events 等等
- 伪元素
- ::after, ::before, ::selection 等等
- 伪选择器
- :hover, :focus, :active 等等
- 装饰类
- 嵌套元素
综合示例:
.c-btn {
@extend %link--plain;
display: inline-block;
padding: 6px 12px;
text-align: center;
font-weight: 600;
background-color: color(blue);
border-radius: 3px;
color: white;
&::before {
content: '';
}
&:focus, &:hover {
box-shadow: 0 0 0 1px color(blue, .3);
}
&--big {
padding: 12px 24px;
}
> .c-icon {
margin-right: 6px;
}
}-
出于可读性的考虑,应当避免三层以上的选择器嵌套
-
优先使用嵌套样式而不是嵌套元素。例如:
.block { padding: 24px; &--mini { padding: 12px; } }
可以通过优秀的类命名方法(BEM)来减少嵌套。应当避免直接使用标签选择器。
Block(块):独立、有意义的名字,样式的逻辑单元。应当避免过度简化
- Good:
.alert-boxor.recents-introor.button - Bad:
.featureor.contentor.btn
Element(元素):块的子元素才拥有的样式,块本身也是元素。元素的类名应当是块名加上两个下划线加上元素名。例如:
.alert-box__close.expanding-section__section
Modifier(修饰符):重载或者扩张块或者元素的基础样式 。其类名应当是块或者元素名加上两个下划线加上元素名。例如:
.alert-box--success.expanding-section--expanded
不要基于块元素样式 @extend(扩展)修饰符。
- Good:
<div class="my-block my-block--modifier"> - Bad:
<div class="my-block--modifier">
不要在元素中创建元素。如果你真的认为有必要,先试着将元素转换为 block。
- Bad:
.alert-box__close__button
明智地选择修饰符。下面两条规则的意义完全不同:
.block--modifier .block__element { color: red; }
.block__element--modifier { color: red; }- 为类型使用基于 BEM 的(中文)命名方式。
- 使用修饰符类时,永远应当加上基类/未修改的类。
- 像这样使用嵌套的 SASS 来管理 BEM 选择器:
.block { &--modifier { //编译为 .block--modifier text-align: center; } &__element { // 编译为 .block__element color: red; &--modifier { // 编译为 .block__element--modifier color: blue; } } }
类型命名空间中有一些保留名,用于全局抽象。
.o-表示 CSS 对象。对象通常是基于通用设计模式(比如 Flag 对象),修改这项元素可能会引起严重问题。.c-表示 CSS 组件。组件通常是基于 UI 的设计元素,比如按钮、输入框、模态窗以及横幅。.u-表示帮助工具。工具类通常是用于单一目的,拥有高优先级。比如浮动元素、消除 margin 等等。.is-, .has-表示状态类,遵循 SMACSS 形式。这些类用于表示临时、可选或者短期存在的状态和样式。._一些 hack 用法。当你需要使用!important或者增加 specificity 时应当使用这种类名。只应当临时使用,不应该绑定使用。.t-主题类。在独立样式的页面或者需要覆盖组件/对象的样式时应当使用主题类。
分类思想(One Thing Well™)
你应该尽可能地提取出相同的 padding、字体、布局模式,并将其抽象为可重用的基于名字空间的类,可以保证绑定的元素只提供单一约束。这样做有助于防止规则的覆盖和重复,并且有助于按方面区分。
// 糟糕的例子
// HTML:
// <div class="modal compact">...</div>
.modal {
padding: 32px;
background-color: color(gray, x-light);
&.compact {
padding: 24px;
}
}
// 优秀的例子
// HTML:
// <div class="c-modal u-l-island">...</div>
// <div class="c-modal u-l-isle">...</div>
// components/_modal.scss
.c-modal {
background-color: color(gray, x-light);
}
// helpers/_layout.scss
.u-l-island {
padding: 32px;
}
.u-l-isle {
padding: 24px;
}Media query 应当以 SMACSS 的形式写在 CSS 选择器中。
.selector {
float: left;
@media only screen and (max-width: 767px) {
float: none;
}
}应该为经常用到的断点(breakpoint)设置变量
$SCREEN_SM_MAX: "max-width: 767px";
.selector {
float: left;
@media only screen and ($SCREEN_SM_MAX) {
float: none;
}
}