简介
设计模式是一套被反复使用、多人知晓、经过分类、代码设计经验的总结,使用设计模式是为了可重用代码、保证代码可读性、可靠性,大幅度提高效能
一. CSS规范必要性
我们在开发页面或组件通常需要解决各种样式管理问题,如样式命名、样式拆分等操作,如果没有规范好这些管理,则会增加 css 开发难度,特别是后期维护,各种没有规则的 class 名称、各种全局样式会让你写 css 过程变得更加难受,总结下来有几点:
- 如何进行样式拆分
- 如何合理进行
class命名 - 如何进行全局样式命名和规范
二. CSS开发思路
对 UI 图结构的分析同时也会决定我们 css 编写的思路,通过分析页面相同的部分抽离出组件,或相同的样式抽离出公共的样式
2.1 拆分结构
对页面进行拆分这是比较频繁的操作,可以把一个页面拆分出很多模块,如 header、menu、column等,把这些模块单独出来之后,我们可以在 css 命名思路上使用同样的规则

2.2 拆分样式
样式可以拆分成两种,一种属于布局相关(如width、height、padding)等,另一种属于皮肤相关(如border、color)等,并且还可以分析当前布局或皮肤的相关性拆分成一个可以复用的 class,减少重复代码,比如清除浮动、超出文本省略号、居中、相同的边框样式、背景颜色可以抽出单独的类名使用,而不是强行与布局耦合在一起
三. CSS现有的设计模式
3.1 OOCSS
OOCSS:面向对象css(Object-Oriented CSS)
OOCSS 它是一种 css 的编程思想,没有具体的实施
OOCSS 遵循两大原则:
-
皮肤和结构分离(
SEPARATION OF STRUCTURE FROM SKIN) -
容器和内容分离(
SEPARATION OF CONTAINERS AND CONTENT)
OOCSS 主要用于开发 css 时为拆分 css 的代码结构提供思路,不要把结构和皮肤以及内容进行强耦合,让它们相互独立,达到可复用、可组合效果
3.2 SMACSS
SMACSS:可拓展和模块化 css 架构(Scalable and Modular Architecture for CSS)
SMACSS 它是一种 css 指导,相比 OOCSS,它有具体的实施方式
SMACSS 的核心点分为以下:
- CSS分类规则(Categorizing CSS Rules)
- CSS命名规范(Naming Rules)
3.2.1 CSS分类规则
SMACSS 有五个分类规则:
1. Base Rule(基础)
HTML 基础样式,在开发 css 之前通常都需要初始化样式,如浏览器默认行高、元素自带的 margin 和 padding,这个过程只使用标签选择器,如:
- reset.css:社区最火的重置浏览器默认样式的
css工具 - normalize.css:提供跨浏览器的
HTML元素默认样式,可以替代传统的css重置
2. Layout Rule(布局)
页面布局,布局一般都是有层级嵌套的,而 Layout Rule 属于最高层,用来充当子模块的容器,比如页面的 header、main、footer ,其中每个模块都包含很多子模块,通过容器布局来决定子模块的排版,栅格系统、多列布局都属于 Layout Rule 分类
<header class="layout-header"></header>
<main class="layout-main"></main>
<footer class="layout-footer"></footer>
复制代码
3. Module Rule(模块)
把 layout 里面的子模块拆分成一个个模块,类似于拆分组件一样,比如我在 main 的容器里面有文章模块(artice),而文章模块里面又有评论模块(comment),这些模块都含有复用性和拓展性,所以这些模块应该避免使用元素选择器,并且 class 应该依照模块的功能去命名,这样能有效把它们独立出来
<main class="layout-main">
<article class="article-wrap">
<h1 class="article-title"></h1>
<div class="comment-wrap"></div>
</article>
</main>
复制代码
4. State Rule(状态)
像普通元素的显示和隐藏、tab 的选中和不选中、input 的 focus 和 blur,这些都是属于 state,而这些 state 应该进行样式抽离把它们抽离成单独的 class 进行管理,因为这些 class 不仅可以应用在布局样式、模块样式中,还会应用到脚本中,我们应该为这些 state 定制一个命名规则,把它们与其他样式进行分类
一般 state 样式用于覆盖原来样式,所以出现 !important 是有必要的
<button class="button is-disabled"></button>
复制代码
.is-disabled {
color: #E6E6E6 !important;
cursor: not-allowed;
pointer-events: none;
}
复制代码
5. Theme Rule(主题)
一个网站的模块几乎都会出现相同点,因为网站设计都是会以一种主题风格去设计的,比如按钮(button)和搜索框(searchInput)会出现同样的颜色、边框,这两个元素经常会出现 focus、blur 两种状态去展示不同的风格,但是这些风格总是在整个网站出现,我们需要通过一种全局的方式去定制一套通用的风格 class,然后通过组合的方式去使用它们
<p class="content primary-color font-size-base"></p>
复制代码
/* color */
.primary-color {
color: #FF8022;
}
.secondary-color {
color: #52C41A;
}
/* font */
.font-size-base {
font-size: 14px;
}
.font-size-lg {
font-size: 16px;
}
.font-size-sm: {
font-size: 12px;
}
复制代码
3.2.2 CSS命名规则
根据 SMACSS 五大分类,命名也可以分为五大分类:
- Base:使用标签选择器和标签命名
- Layout: 以
l-/layout-为前缀,后面根据布局的块来命名,如layout-header、layout-footer - Module:以模块功能为命名,如文章组件可以以
article-为前缀,文章标题(article-title)、文章内容(article-content) - State:以
is-作为前缀,如is-disabled、is-active - Theme:以状态或区域加上主题功能名称方式去命名,如主要颜色(
primary-color)、成功颜色(success-color)、主要字体(font-size-base)
3.2.3 SMAC 总结
SMACSS 提供了一整套 css 规范的实施方案,通过分析页面模块和样式的功能点去拆分成5大块,然后每个块都位开发 css 提供很好的思路,除了样式开发之外还提供了命名的规范,增加 css 命名的语义化,让协作人员更容易理解,降低沟通与维护成本
3.3 BEM
BEM 是一种基于组件的 web 开发方法,将用户界面划分为独立的块,它允许重用现有代码,无需进行复制和粘贴
BEM 在页面模块上,class 命名的规范比 SMACSS 更加完善,通过拆分组件的思路去拆分页面模块,然后根据模块的功能以命名空间和扁平化形式去编写 class 命名,,可以减少命名冲突、命名词穷、css 层次嵌套问题
BEM 分为块(Block)、元素(Element)、修饰符(Modifier)三大块:
3.3.1 Block(块)
Block 含义指的是一个独立的模块,相当于组件的概念,如 header、menu、tab 是一个组件,而组件的名称具有唯一性,可以用作 class 命名的头部:
.header_xxx {};
.menu_xxx {};
.tab_xxx {};
复制代码
3.3.2 Element(元素)
Element 是 Block 的组成部分,不能单独使用,也就是上级必须是 Block,用于描述 Block 的组成,而不是状态
一个 Element 始终是 Block 的一部分,Element 与 Block 名称之间使用双下划线(__)分隔
.header__input {};
.header__content {};
.header__button {};
复制代码
3.3.3 Modifier(修饰符)
Modifier 用来定义 Block 或 Element 的外观、状态、行为的实体,如大小(size-lg)、主题(theme-color)、状态(disabled、focus)
Modifier 名称与 Block 或 Element 名称之间用单个下划线(_)分隔
.header__input_focused {}; /* focused 是布尔值修饰符 */
.header__content_theme_primary {}; /* theme 是修饰符, primary 是修饰符的值 */
.header__button_size_m {}; /* size 是修饰符,m 是修饰符的值 */
复制代码
3.3.4 BEM 总结
BEM 以划分组件的思想去划分 css 样式,并且把命名分成三大块,不仅使用命名空间的方式解决了 css 作用域、多层嵌套问题,还提供了统一的 class 命名规范,适合用于组件开发,在开发组件库时还可以根据它提供的命名规则再拓展一层,如 Antd、Element,它的 css 命名在 Block 还多了一层 namespace(ant-layout-header),防止与页面的样式名冲突
3.4 Meta css
Meta css 通过一种规定好的命名规则去定义全局 css,通过规定好的全局 css 规则去组合然后实现页面效果,减少编写重复的 css 代码
Meta css 通常用于提供一系列通用的 class,例如 clearfix、超出文本省略等,这些 class 可以定义在全局内,因为它们很大几率在各个不同的页面或组件中使用,你绝不想在每个地方 copy 一遍
Meta css 的思想就在于把通用的 css 代码抽离出单独的 class,然后以覆盖的形式并且通过不同的组合达到不同的效果,例如 bootstrap 就是一个非常火爆的 css 库,提供一套规范和完整的元定义(meta),能够完美与其他 css 框架或组件库一起使用
Meta css 的命名规则可以参考一下 bootstrap 命名规范
四. 总结
css 设计模式可以增加 css 开发的效率,规范的 class 命名和 css 功能的模块拆分让开发人员更容易理解整个项目的 css 的开发流程,设计模式主要提供编程思路,但并不是比较完美的解决方案,如 SMACSS 随着页面的模块相似度越来越高,很容易出现命名冲突的问题,而 BEM 使用命名空间的方式解决命名冲突问题,但是随着页面的复杂度 BEM 的命名会越来越长
目前 css 开发的编程思想有了,接下来会深入探讨 css 开发的方案





















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)
![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)
