想起刚工作不久的时候,自己想要明确一套规范,而不只是看到什么就是什么,但实际经验欠缺,就只是简单的了解了一下。现在又有这样的念头了,也有对应的素材,尝试着总结一下,看下能弄出什么样来。
谈到 CSS 就离不开 HTML,现在有不少关于阐释 HTML 和 CSS 之间关系的理论。了解这些,对于组织 CSS 很有帮助。下面通过网上的一些资料,介绍一些认可度比较高的方法论。
全称是 Object-Oriented CSS,面向对象的 CSS。在 2008 年的时候就被提出,在 OOCSS wiki 介绍中,该方法有两个主要的原则:
意思是将视觉特性定义为可复用的单元(例如背景和边框样式)。换句话说,就是把布局和设计的样式都独立出来。见下面的例子:
<div class="warn">warningdiv>
样式 warn 表示警告的字体颜色,在系统内,只要是用到警告的地方,统一使用这个样式。
意思是指把内容从容器中分离开来。不论你放到那里,看起来都是一样的。见下面的例子:
<div class="dialog blue">
<div class=“dialog-title”><span class="text">Titlespan>div>
<div class="dialog-content show"><span class="text">contentspan>div>
div>
这个例子中不同的模块显示不同的字体和颜色,一般可能会这样做:
.dialog-title .text {color: #333;}
.dialog-content .text {color: #666;}
但在 OOCSS 方法中是通过添加一个新的 class
来描述需要的样式:
<div class="dialog blue">
<div class=“dialog-title”><span class="text title-text">Titlespan>div>
<div class="dialog-content show"><span class="text content-text">contentspan>div>
div>
.title-text {color: #333;}
.content-text {color: #666;}
当想提供一套组件让开发人员组合起来创建用户界面时,这种方法非常有用。Bootstrap 就是一个例子,它是一个自带各种皮肤的小组件系统。
全称是 Scalable and Modular Architecture for CSS,模块化架构的可扩展 CSS。SMACSS 把样式系统划分为五个具体类别:
!important
。见下面的例子:
<div class="dialog dialog-blue">
<div class=“dialog-title”><span class="text">Titlespan>div>
<div class="dialog-content is-show"><span class="text">contentspan>div>
div>
观察模块样式 dialog
、dialog-blue
、dialog-title
、dialog-content
和状态 is-show
,可以发现对于如何创建功能的小模块,OOCSS 和 SMACSS 有许多相似之处。它们都把样式作用域限定到根节点的 CSS 类名上,然后通过皮肤(OOCSS)或者子模块(SMACSS)进行修改。除了SMACSS 把代码划分类别之外,两者之间最显著的差异是使用皮肤而不是子模块,以及带 is
前缀的状态类名。
全称是 Block Element Modifier,块元素修饰符。BEM 是一种基于组件的 Web 开发方法。其背后的想法是将用户界面划分为独立的块。其中包含的内容不仅仅是 CSS,其中 CSS 的内容结合 About HTML semantics and front-end architecture,得出一套命名规则:
.block
。.block__element
。.block--modifier
。看下面例子:
<div class="dialog dialog-skin-blue">
<div class=“dialog__title”><span class="dialog__text">Titlespan>div>
<div class="dialog__content dialog__content--show"><span class="dialog__text">contentspan>div>
div>
这种方式不建议使用元素选择器,名称过长时,用 - 连接。BEM 使用非常简洁的约定来创建 CSS 类名,而这些字符串可能会相当长。
这种方法在 OOCSS 或 SMACSS 里使用的好处是,每一个 CSS 类名都详细地描述了它实现了什么。代码中没有 show
或者 is-show
这样只在特定背景下才能理解的 CSS 类名。如果单独看 show
或者 is-show
这两个名字,我们并不知道它们的含义是什么。
虽然 BEM 法看起来很累赘、很冗余 ,但是当看到一个 dialog__content--show
的 CSS 类名,就知道它是表示:这个元素的名称是 content,位置在 dialog 组件里,状态为显示。
没有什么方法论是完美的,你可能会发现,不同的项目适合不同的方法。也许还有新的方法,我们还没有发现,不要因为一套规范很流行或者别的团队在使用就选择它。理解方案背后这么做的原因,不要害怕尝试,混合已有的方案,甚至自己或者团队一起创造出独一无二的方案。
!important
。由于 CSS 选择符是从右到左进行匹配,所以:
.content ul li
。.content > ul >li
。使用 2 个空格。
需要空格情况:
{
前。:
后面。!important
前。不需要空格情况:
:
前面。!important
中 !
后。,
前。(
后和 )
前。/* good */
.nav,
.footer {
font-size: 18px;
color: #666 !important;
background-color: rgba(0,0,0,.5);
}
/*not good*/
.nav ,
.footer{
font-size :18px;
color: #666! important;
background-color: rgba( 0, 0, 0, .5 );
}
需要空行的情况:
}
后留空行./* good */
.nav {
font-size: 18px;
}
.footer {
color: #666;
}
/* not good */
.nav {
font-size: 18px;
}
.footer {
color: #666;
}
需要换行的情况:
{
后和 }
前。,
后。/* good */
.nav,
.footer {
font-size: 18px;
color: #666;
}
.body {
font-size: 16px;
}
/* not good */
.nav,.footer {
font-size: 18px;color: #666;
}
.body {font-size: 16px;}
每个属性名末尾要加分号。
/* good */
.nav {
font-size: 18px;
}
/* not good */
.nav {
font-size: 18px
}
统一使用双引号。
/* good */
.nav:before {
content: "";
font-size: 18px;
}
/* not good */
.nav:before {
content: '';
font-size: 18px;
}
使用小写字幕,能简写就使用简写。
/* good */
.nav {
color: #ab1243;
background-color: #236;
}
/* not good */
.nav {
color: #AB1243;
background-color: #223366;
}
需要简写的属性有:
/* good */
.nav {
margin: 10px 0 0 6px;
padding: 2px 0 0 3px;
}
/* not good */
.nav {
margin-top: 10px;
margin-left: 6px;
padding-top: 2px;
padding-left: 3px;
}
建议顺序为:
[
"display",
"visibility",
"float",
"clear",
"overflow",
"clip",
"zoom",
"table-layout",
"border-spacing",
"border-collapse",
"list-style",
"flex",
"flex-direction",
"justify-content",
"align-items",
"position",
"top",
"right",
"bottom",
"right",
"z-index",
]
[
"margin",
"box-sizing",
"border",
"border-radius",
"padding",
"width",
"min-width",
"max-widht",
"height",
"min-height",
"max-height",
]
[
"font-size",
"line-height",
"text-align",
"vertical-align",
"white-space",
"text-decoration",
"text-emphasis",
"text-indent",
"text-overflow",
"word-wrap",
"word-break",
"color",
"text-shadow",
]
[
"background",
"background-color",
"background-image",
"background-repeat",
"background-attachment",
"background-position",
"background-clip",
"background-origin",
"background-size",
"outline",
"opacity",
"filter",
"box-shadow",
"transition"
"transform",
"animation",
"cursor",
"pointer-events",
]
尽量将媒体查询的规则靠近与他们相关的规则,不要将他们一起放到一个独立的样式文件中,或者丢在文档的最底部,这样做只会让大家以后更容易忘记他们。
/* good */
.nav {
font-size: 14px;
}
@media (min-width: 480px) {
.nav {
font-size: 16px;
}
}
对比 stylelint-config-recommended 配置中的规则,发现:
在 stylelint-config-standard 配置中的规则,发现:
基于 stylelint-config-recommended
配置,根据 stylelint 已有的配置规则,以及上面总结的规范进行自选配置。
"use strict"
module.exports = {
"extends": "stylelint-config-recommended",
"rules": {
// 缩进
"indentation": 2,
// 空格
"block-opening-brace-space-before": "always",
"declaration-colon-space-after": "always",
"declaration-bang-space-before": "always",
"comment-whitespace-inside": "always",
"declaration-colon-space-before": "never",
"declaration-bang-space-after": "never",
"value-list-comma-newline-before": "never",
// 空行
"max-empty-lines": 1,
// 换行
"block-closing-brace-newline-after": "always",
"block-opening-brace-newline-after": "always",
"declaration-block-semicolon-newline-after": "always",
"selector-list-comma-newline-after": "always",
// 引号
"string-quotes": "double",
// 颜色
"color-hex-length": "short",
"color-hex-case": "lower",
},
}
在收集资料过程中碰到的示例和工具,有些需要。