CSS设计模式介绍

697 阅读9分钟

一、 常见CSS设计模式分析

oocss

Object Oriented CSS,面向对象的CSS,旨在编写高可复用、低耦合和高扩展的CSS代码。

OOCSS是以面向对象的思想去定义样式,将抽象(结构)和实现(样式)分离,抽离公共代码。

区分结构和样式 在定义一个可重用性的组件库时,我们仅创建基础的结构(html)和基础的类名,不应该创建类似于border, width, height, background等样式规则,这样使组件库更灵活和可扩展性。组件库在不同环境下的样式所要求不一样,若未能区分其结构和样式,给其添加样式,会使其变成一个特定的组件库,而难以重用。

以下是一个基础库创建的样式:

.metadata{
  font-size: 1.2em;
  text-align: left;
  margin: 10px 0;
}

若在给其添加更多的样式:

.metadata{
    font-size: 1.2em;
    text-align: left;
    margin: 10px 0;
    /*在基础组件上新加的样式*/
    width: 500px;
    background-color: #efefef;
    color: #fff;
}

这样就使前面创建的基础组件metadata变成了一个特定的组件了,使其在其他场景下较难复用。

区分容器和内容, 把容器和内容独立分区,使内容能作用于任何容器下。

#sidebar h3 {
  font-family: Arial, Helvetica, sans-serif;
  font-size: .8em;
  line-height: 1;
  color: #777;
  text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}

上面我们定义了一个id为sidebar 中 h3的样式,但是我们发现在footer 中 h3的样式也基本一致,仅个别不一样,那么我们可能会这样写样式:

#sidebar h3, #footer h3 {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 2em;
  line-height: 1;
  color: #777;
  text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}

#footer h3 {
  font-size: 1.5em;
  text-shadow: rgba(0, 0, 0, .3) 2px 2px 4px;
}

甚至我们可能会用更糟糕的方式来写这个样式:

#sidebar h3 {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 2em;
  line-height: 1;
  color: #777;
  text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}

#footer h3 {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 1.5em;
  line-height: 1;
  color: #777;
  text-shadow: rgba(0, 0, 0, .3) 2px 2px 4px;
}

我们可以看到上面的代码中出现了不必要的duplicating styles。而OOCSS鼓励我们应该思考在不同元素中哪些样式是通用的,然后将这些通用的样式从模块、组件、对象等中抽离出来,使其能在任何地方能够复用,而不依赖于某个特定的容器。

<div class="header theme"></div>
<div class="footer theme"></div>
.header {
  height: 100px;
  width: 100px;
}

.footer {
  height: 200px;
  width: 100px;
}

.theme {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 2em;
  line-height: 1;
  color: #777;
  text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}

最终实现结构与样式分离,从而提高了样式代码的可复用性

SMACSS

image.png

Scalable and Modular Architecture for CSS,可扩展模块化的CSS,它的核心就是结构化CSS代码,提出了一种CSS分类规则,分为五种类型:

  • Base

  • Layout

  • Module

  • State

  • Theme

SMACSS定义了一种css文件的组织方式,其横向的切分,即按照功能模块划分,使css文件更具有结构化、高可维护性。

  1. Base

Base是默认的样式,是对单个元素选择器(包括其属性选择器,伪类选择器,孩子/兄弟选择器)的基础样式设置,例如html, body, input[type=text], a:hover, etc.

html, body {
  margin: 0;
  padding: 0;
}

input[type=text] {
  border: 1px solid #999;
}

a {
  color: #039;
}

a:hover {
  color: #03C;
}

CSS Reset/Normalize就是一种Base Rule的应用.

Note: 在基础样式中不应该使用!important

  1. Layout

不明思议,是对页面布局元素(页面架构中主要和次要的组件)的样式设置,例如header, navigation, footer, sidebar, login-form, etc.


.header, footer {
  margin: 0;
}

.header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 9999;
}

.navs {
  display: inline-block;
  margin: 0 auto;
}
  1. Modules

对公共组件样式的设置,例如dropdown, tabs, carousels, dialogs, etc.


.dropdown, .dropdown > ul {
  display: inline-block;
  border: 1px solid #283AE2;
}

.dropdown li:hover {
  background-color: #999;
}

.tabs {
  border: 1px solid #e8e8e8;
}

.tabs > .tab--active {
  border-bottom: none;
  color: #29A288;
}
  1. State

对组件、模块、元素等表现行为或状态的样式修饰,例如hide, show, is-error, etc.


.hide {
  display: none;
}

.show {
  display: block;
}

.is-error {
  color: red;
}
  1. Theme

对页面整体布局样式的设置,可以说是一种皮肤,它可以在特定场景下覆盖base, layout等的默认样式。


.body--theme-sky {
  background: blue url(/static/img/body--theme-sky.png) repeat;
}

.footer--theme-sky {
  background-image: blue url('/static/img/header--theme-sky.png') no-repeat center;
}

BEM

BEM 是我的方法的基础。如果你以前从未听说过 BEM,它代表 block , element 和 modifier。当你第一次接触它时,它看起来是那么的难看。

.block { /* styles */ } 
.block__element { /* styles */ } 
.block--modifier { /* styles */ }

当我第一次看见 BEM 的时候,我就很讨厌它,甚至没有给它一个机会。我不记得是什么驱使我尝试 BEM 的,但我现在深深的知道它有多么的强大。让我来完整地解释一下 BEM 是什么(当然,加入了我自己的理解)。

一个块就是一个组件。这有点抽象,所以让我们用示例来学习。

假设您正在建立一个联系表单。在这种情况下,这个表单可以是一个块。在 BEM 中,块被写为像 class 的名字一样,如下所示:

.form { /* styles */ }

BEM 使用 .form 而不是 <form> 元素的原因是因为 类允许无限的可重用性,而即使是最基本的元素也可能改变样式。

按钮很好地阐释了可以包含不同样式的块。如果将 <button> 元素的背景颜色设置为红色,则所有<buttons> 都将被强制继承红色背景。接下来,你必须通过覆盖你的<button> 元素来修复代码(并且可能会在修复中“伤及无辜” )。

button { 
    background-color: red; 
} 

.something button { 
    background-color: blue;
}

如果设置了一个 .button 类的按钮,则可以在任何<button>元素上选择是否使用 .button 类。那么,如果你需要一个不同的背景颜色,你所做的就是改成一个新的 class,比如说 .button--secondary,很舒服吧!

.button { 
    background-color: red; 
}

.button--secondary { 
    background-color: blue;
}
  1. 元素

元素是块的子节点。为了表明某个东西是一个元素,你需要在块名后添加__element。所以,如果你看到一个像那样的名字,比如 form__row ,你将立即知道 .form 块中有一个 row 元素。

<form class="form" action=""> 
    <div class="form__row"> 
        <!-- ... --> 
    </div> 
</form>

.form__row { 
    /* styles */ 
}

BEM 元素有两个优点 :

  • 你可以让 CSS 的优先级保持相对扁平。
  • 你能立即知道哪些东西是一个子元素。

为了解释以上两点,考虑使用两个单独的 class 的替代方法(许多框架这么做的)。你可能会用这样的东西:

<form class="form" action=""> 
    <div class="row"> 
        <!-- ... --> 
    </div>
</form> 

.form .row { 
    /* styles */ 
}

如果你使用 BEM 元素,则可以使用优先级为 10 而不是 20 的的选择器来为 .form__row 提供样式。此外,你可以立即分辨出(不论是在 HTML 还是 CSS 中).form__row.form的子节点。

  1. 修饰符

修饰符是改变某个块的外观的标志。要使用修饰符,可以将 --modifier 添加到块中。

从上面的按钮示例继续,修改的按钮将被命名为 .button--secondary。

在传统的 BEM 中,当你使用修饰符时,你应该 将块和修饰符添加 到 HTML 中,以便在新的 .button--secondary 中不重写 .button 样式。

<button class="button">Primary button</button>
<button class="button button--secondary">Secondary button</button>

.button { 
    padding: 0.5em 0.75em; 
    background-color: red; 
} 
.button--secondary { 
    background-color: green; 
}

注意为什么没有必要在 .button--secondary 中重新声明 padding,因为它已经在 .button 中声明了。这很棒,因为 BEM 确保你编写简洁的 CSS,而不需要付出大量的工作。

ITCSS

组织CSS的现代方法通常会退回到模块化或CSS对象来构造抽象思想。

倒三角形CSS的新思想是一种基于 CSS属性 的特异性和重要性的分层方法 。 与SMACSS和OOCSS相比,这是一种鲜为人知的方法-尽管两者都可以与ITCSS结合使用。

由于ITCSS 主要是专有的 ,因此不存在有关其用法的详细规则手册。 我们只能使用一组特定的原则 。 作者在下面的视频中谈到了它们。

默认情况下,ITCSS使用相同的原则OOCSS 但基于特异性更大的分离 。 因此,如果您已经熟悉OOCSS,请考虑尝试使用这种独特的替代CSS体系结构 。

以下是使用ITCSS的最大好处:

  • 页面对象可以拆分为自己CSS / SCSS文件,以实现可重用性 。
  • 复制/粘贴并将每个对象扩展到其他项目很简单 。
  • 具体的深度取决于您 。
  • 没有设置的文件夹结构 ,也不需要使用预处理工具。
  • 您可以合并来自其他方法(例如CSS模块)的概念,以创建自己的混合工作流 。

image.png

从倒三角形的平坦顶部到底部尖端的定向流表示特异性的增加 。 由于专注于降低特异性 ,因此可以更轻松地在站点中多次重用类。

三角形的每个子部分都可以视为一个单独的文件或文件组,尽管您无需以这种方式编写代码。 由于具有导入功能,因此对Sass / Less用户更有意义。 只需将每个小节视为拆分和组织可重用CSS代码的方法即可 。

让我们快速看一下倒三角形从上到下的每个部分 。

  • 设置 –预处理程序变量和方法(无实际CSS输出)
  • 工具 – Mixins和函数(无实际CSS输出)
  • 常规 – CSS重置,其中可能包括Eric Meyer的重置, Normalize.css或您自己的一批代码
  • 元素 –没有类的单个HTML元素选择器
  • 对象 -通常遵循OOCSS方法的页面结构类
  • 组件 –用于设置任何页面元素和所有页面元素样式的美学类(通常与对象类的结构结合使用)
  • Trumps –最重要的样式,用于覆盖三角形中的任何其他内容

倒三角形的每一层都可以调整以满足您的需要 。 因此,如果您不使用CSS预处理器,则不需要设置或工具层。

在实际项目中应当灵活使用。

ACSS

ACSS使用了紧密的类名库。 这些类名通常被缩写,并与它们影响的内容分开。 在ACSS系统中,您可以知道类名的作用; 但是类名称(至少不是样式表中使用的名称)与内容类型之间没有关系,即每一个样式对应一个类,也称原子类CSS。

.bg-a {
  background-color: #a6d5fa;
}
.bg-b {
  background-color: #aedbaf;
}
.bg-c {
  background-color: #ffe8a5;
}
.bg-d {
  background-color: #faaaa4;
}

二、CSS设计模式在UI库中的使用情况分析

  1. Element UI

    ITCSS + BEM

  2. Ant Design

    ITCSS + BEM

  3. Bootstrap

    ITCSS + OOCSS

  4. Tailwind CSS

    ACSS

总结

  • 在各流行UI库中CSS设计模式无处不在
  • 我们应当积极在项目中实现自己的CSS设计模式组合以便优化我们项目的CSS架构
  • 建议使用ITCSS架构,配合BEM命名规范,组织ACSS基础样式便于后续使用