资讯专栏INFORMATION COLUMN

CSS方法论(一)

haoguo / 1445人阅读

摘要:由于年提出,这基于她在雅虎的工作。但是这很难做到解决的问题样式全局性造成的样式冲突问题多人协作的命名问题解决层叠问题,使的优先级保持相对扁平的模块化,使更具有复用的能力于年由提出,当时他在雅虎工作。

编写CSS会遇到什么问题?

其实CSS很好写,只要知道css语法,你就可以写出来,通过各种学习,你也可以做出一个很美丽的页面。对能熟练编写网页的人来说,可以很简单的将设计图变成网页。
但是在中型/大型项目中,你往往遇见的问题,并不是如何写出一个网页,而是:

在前端框架内引入UI框架,是否能保证你的样式与框架不产生冲突,怎么解决

是否能处理多人协作所产生的问题

怎么提高你的样式的可维护性

你的样式是否可以复用,怎么复用

能不能提升幸福感

甚至于个人,怎么让你自己的代码更优雅,让自己更有成长,而不是仅仅在写代码。

CSS方法论

早在前几年,社区就根据种种编写CSS所遇到的问题,提出了一些方法论:

OOCSS

BEM

SMACSS

Atomic CSS

OOCSS(面向对象的CSS)
社区内最早提出的一种方法,也可以说是模块化CSS的起源。由NicoleSullivan 于 2009 年提出,这基于她在雅虎的工作。

面向对象对于后端开发人员可能较为熟悉,那么在CSS中的面向对象是什么?

面向对象:把数据及对数据的操作方法放在一起,作为一个相互依存的整体——对象。对同类对象抽象出其共性,形成类。类中的大多数数据,只能用本类的方法进行处理。类通过一个简单的外部接口与外界发生关系,对象与对象之间通过消息进行通信。程序流程由用户在使用中决定。

CSS中的对象是一个可复用的样式规则。

Basically, a CSS “object” is a repeating visual pattern, that can be abstracted into an independent snippet of HTML, CSS, and possibly JavaScript. That object can then be reused throughout a site. 
-- OOCSS wiki

举个简单的例子,我们在一个网站中,很多页面都需要使用到按钮,那么根据oocss的定义我们应该怎么做?
在style中加入一个 btn 的类,之后网站内全部的按钮都使用这个样式。这个 btn 就是一个对象。


在例子中我们定义了一个 btn 的css类。那么这个css类就是一个对象。熟悉面向对象的朋友肯定知道,哦,我们把button这个对象封装了。所以以后在网站中在使用按钮,直接用 btn 这个类就可以了。

接下来我们来了解下,OOCSS包含了两个原则:

容器与结构分离(Separate container and content)

内容与样式分离(Separate structure and skin)

以及OOCSS的其他特点:

使用类名来扩展基础对象

坚持语义化的命名方式

容器与结构分离

通常在我们写CSS的时候,我们通常会根据Html元素的位置来规定样式,例如:

.nav ul li {...}

而在OOCSS认为,我们的样式不应该根据元素的位置来判断对象的样式。
而是应该给元素定义自己的样式,如:

.list {...}
.list-item {...}

也就是说,在网页中的任何位置使用 list ,我都不需要考虑 list 的上下文是什么,不论什么情况下 list 的样式都不应该改变。

内容与样式分离

现在我们就遇到了新问题,在之前我们定义了一个 btn 对象,现在我想要再网页中加入一个红色的按钮怎么办?
在学oocss之前我们可能说,在style改一下就好了,或者加一个红颜色的对象就可以了;

.btn {
    padding: 4px 8px;
    background-color: #bbb;
    color: #fff;
}

.red-btn {
    padding: 4px 8px;
    background-color: red;
    color: #fff;
}

这样修改的确是有一个红色的按钮,但是出现了什么问题?

我发现我写两遍的 padding: 4px 8px; 和 color: #fff;

拿我现在想要绿色、蓝色、橙色的按钮怎么办,甚至我想要大一点的按钮?

OOCSS提出了他的核心原则之一:内容与样式分离,他将对象设置为基本的样式,而如果这个对象存在多种多样的样式,我们通过添加皮肤(skin)的方式给他添加样式。

.btn{
   padding: 4px 8px;
   background-color: #bbb;
   color: #fff;
}

.red{
   background-color: red;
}

这样我们要的红色按钮就出炉了,你们想要的绿色、蓝色等等等等爱要什么要什么...

使用类名来扩展基础对象

那么在这个例子中,我们可以看到我们使用了一个红色的按钮,但是我们会发现一个问题,如果当我们写了一个label的时候我们想让他的字体是红色的,我们如果不注意,样式很有可能会冲突。


在OOCSS中,提倡将对象的皮肤使用其基础类名来进行拓展。

.btn {...}
.btn-red {...}
.label {...}
.label-red {...}

这样我们一眼就可以看出,我们的扩展样式是对应哪个对象的。也减少了样式的冲突。

坚持语义化的命名方式

OOCSS还提倡使用语义化的命名方式,这样有什么好处呢?我们可以根据名称给皮肤定义使用场景,在特定场景使用特定的皮肤,这样就不需要担心在网站中胡乱使用颜色了。

.btn {...}
.btn-edit{  background-color: blue;}
.btn-delete{  background-color: red;}
总结

如果对前端比较了解的同学可以发现,其实这个方法我们经常能使用得到,大名鼎鼎的Bootstrap就是使用了这种方法。
这种方法就是让你的CSS代码更灵活、更具有可复用性、可维护行及可扩展性。

BEM(Block-Element-Modifier) 什么是BEM?
BEM代表块(Block),元素(Element),修饰符(Modifier),由Yandex团队提出的一种前端命名方法论。
BEM是一种让你可以快速开发网站并对此进行多年维护的技术。 -- 早期描述
BEM是一种命名方法,能够帮助你在前端开发中实现可复用的组件和代码共享。

BEM是一个严格约定的命名规范,通过这种规范,来解决我们在编写CSS是所遇到的问题。

BEM将网页中的元素分为块、元素、修饰符

/* 书写规范 */
.block {...} /* 块 块名*/
.block__element {...} /* 元素 块名 + __ + 元素名 */
.block--modifier {...} /* 修饰符 块名 + -- + 元素名 */

.block 块:代表了更高级别的抽象或组件

.block__element 元素:代表 .block 的后代,用于形成一个完整的.block的整体

.block--modifier 修饰符:代表 .block 的不同状态或不同版本

块(Block)

我们可以将块理解为web应用中的组件或者模块。
特点:

嵌套式的构造
Block 可以被嵌套到任何其他 block 里面去。例如,一个头部 header 可以包含一个 logo 、一个搜索表单 form 和一个登录 login 。

随意放置
Block 可以在一个页面内任意移动,也可以在页面之间或项目之间移动。Block 作为独立的实体来实现,这使得在页面上改变 block 的位置 并确保其功能和外观一切正常 成为可能。

可复用
一个界面可以包含同一个 block 的几个实例。

元素(Element)

大部分组件都不是由多层HTML嵌套组成的,那么元素就是就是这个组件内部的各级元素。
这里需要注意的是,不论在HTML中一个块的结构是什么,在BEM规则中中,块下的元素全部属于块。

list-item 和 list-icon 都属于块 list 。

修饰符(Modifier)

修饰符与在OOCSS中的皮肤比较类似,属于组件在不同状态或组件的不同版本。

其他特点

一个块必须有一个“名字”(一个CSS类)才能被CSS规则所使用

为什么不使用ID选择器或元素选择器?

类允许无限的重复使用,而ID在页面中只允许使用一次

元素具有元素本身的意义,不应该和组件互相产生影响

永远不要链式命名
在之前提到过,元素应该只属于块,所以元素的命名只可能是 block--element 而不是 block--element1--element2

尽量避免子代选择器

将样式与HTML结构解耦,减少修改HTML而造成的样式无法显示,同样减少了因HTML修改造成的样式重写

解决了CSS特殊性的问题,所有的样式都是由一个类选择器定义。

但是这很难做到

BEM解决的问题

CSS样式全局性造成的样式冲突问题

多人协作的命名问题

解决层叠问题,使CSS的优先级保持相对扁平

CSS的模块化,使CSS更具有复用的能力

SMACSS
SMACSS于2011年由JonathanSnook提出,当时他在雅虎工作。

SMACSS是指CSS 的可扩展性和模块化架构。我们可以将SMACSS看做是对OOCSS和BEM的一个延伸。
刚刚讲过了BEM,那么我们将我们页面的样式都化为了组件,但是在大型网站开发中,这些组件依旧很庞大,那么在SMACSS中,它提出了将CSS分类这一概念。

SMACSS的分类

在SMACSS中,它认为CSS应该根据如下五种分组类别进行分类:

Base(基础规范):任何场合下,页面元素的默认外观,这里样式只会对标签元素本身做设定,不会出现任何class或id,但是可以有属性选择器或是伪类。

Layout(布局规范):布局是一个网站的基本,无论是左右还是居中,甚至其他什么布局,要实现页面的基本浏览功能,布局必不可少。使用l-/layout-为前缀。

Module(模块规范):基本思想与BEM类似。使用m-/module-为前缀。

State(状态规范):元素在特定状态下的外观。但是与OOCSS分离Skin的方式不同,SMACSS是抽取更高级别的样式类,得到更强的复用性。使用is-/has-为前缀。

Theme(主题规范):页面主题外观。使用t-/theme-为前缀

其他特点

命名方式借鉴BEM命名规范

同样提倡最小配饰深度,既尽量不使用子选择器,保持CSS扁平化

Atomic CSS(原子化CSS)
由雅虎公司内部提出,并应用于雅虎官网。

刚刚我们讲了几种方法论,都提到了重用性,那么原子化CSS就是将重用性运用到了极端。

Atomic Design(原子化思想)

在2013年网页设计师Brad Frost从化学中受到启发:原子(Atoms)结合在一起,形成分子(Molecures),进一步结合形成的生物体(Organisms)。

Brad将这个概念应用在界面设计,我们的界面就是由一些基本的元素组成的。Josh Duck的“HTML元素周期表”(下图)完美阐述了我们所有的网站、APP、企业内部网、hoobadyboops等等是如何由相同的HTML元素组成的。

Atoms(原子):为网页构成的基本元素。

Molecules(分子):由原子构成的简单UI组件。

Organisms(组织):由原子及分子组成的相对复杂的UI构成物。

Templates(模板):将以上元素进行排版,显示设计的底层内容结构

Pages(页面):将实际内容(图片、文章等)套件在特定模板,页面是模板的具体实例。

原子化CSS

理解了原子化的设计,那么为什么说原子化CSS就是将重用性进行到了极端。
让我们来举个例子,GitHub上面有一款开源的ACSS工具,叫做 Atomizer
我们使用它来看一下

    

Grid

Inline Block

  • .W(1/2)
  • .W(1/2)
  • .W(1/3)
  • .W(1/3)
  • .W(1/3)
    • Flex

      • .W(1/2)
      • .W(1/2)
      • .W(1/3)
      • .W(1/3)
      • .W(1/3)

看到这段代码,大家肯定会怀疑人生,这是什么鬼?
那么我们来下这段HTML生成的css代码

.Bgc(#add8e6) {
  background-color: #add8e6;
}
.Bgc(#ccc) {
  background-color: #ccc;
}
.Bgc($primary) {
  background-color: #f3f3f3;
}
.D(f) {
  display: flex;
}
.D(ib) {
  display: inline-block;
}
.Fw(b) {
  font-weight: bold;
}
.Fz(30px) {
  font-size: 30px;
}
.W(1/2) {
  width: 50%;
}
.W(1/3) {
  width: 33.3333%;
}
.W(1/5) {
  width: 20%;
}

那么原子化的CSS到底是什么?
将CSS的代码最小化。每一个CSS的类里面只存在一条属性,而在使用时,用到这一条属性时,我们只需要在HTML的class中加入对应的CSS类就可以,最小化了CSS,但是造成了HTML的臃肿。。

总结

我们学习了几种CSS的方法论,社区内还有很多种其他的方法论,如SUITCSS,ITCSS等等这里就不一一进行讨论了。

最后我们来总结下书写CSS的方法:

CSS模块化,使CSS与上下文无关

使用 CLASS,确保复用性

使用命名约定及前缀,提高可读性

不嵌套 CSS,使CSS扁平化

提高CSS的可维护性及扩展性

下一篇我将介绍现在比较流行的编写CSS的方法如:

CSS预处理器

CSS后处理器

CSS in Js

CSS Module

引用

OOCSS——概念篇
BEM的定义
为什么我们要用BEM
Atomic Design原子设计理念:构建科学规范的设计系统
什么是模块化 CSS?

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/114051.html

相关文章

  • [译]聊CSS法论

    摘要:这个方法论在内容和容器之间有着明显的区分。这是通过把命名为表示其角色的类名。通过使用这种扁平的命名方式避免了多后代的选择器。 原文链接:A Look at Some CSS methodologies CSS在大型,复杂,快速迭代的系统中难以管理的程度是出了名的。 其中一个原因是CSS缺少内置的作用域管理机制。在CSS中,所有的一切都是全局的,这意味着任何你所做的改变都有可能层叠或者改...

    CoffeX 评论0 收藏0
  • [译]聊CSS法论

    摘要:这个方法论在内容和容器之间有着明显的区分。这是通过把命名为表示其角色的类名。通过使用这种扁平的命名方式避免了多后代的选择器。 原文链接:A Look at Some CSS methodologies CSS在大型,复杂,快速迭代的系统中难以管理的程度是出了名的。 其中一个原因是CSS缺少内置的作用域管理机制。在CSS中,所有的一切都是全局的,这意味着任何你所做的改变都有可能层叠或者改...

    cfanr 评论0 收藏0
  • 前端-CSS3&H5

    摘要:高度模型浅识为的简写,简称为块级格式化上下文,为浏览器渲染某一区域的机制,中只有和中还增加了和。并非所有的布局都会在开发中使用,但是其中也会涉及一些知识点。然而在不同的纯制作各种图形纯制作各种图形多图预警 一劳永逸的搞定 flex 布局 寻根溯源话布局 一切都始于这样一个问题:怎样通过 CSS 简单而优雅的实现水平、垂直同时居中。记得刚开始学习 CSS 的时候,看到 float 属性不...

    xiaolinbang 评论0 收藏0
  • jQuery入门笔记之()选择器引擎

    摘要:选择器,若未作特别说明,获取的都是元素集合。过滤器名语法说明选取所有不可见元素选取所有可见元素注意过滤器一般是包含的内容为样式为表单类型为和的元素。四子元素过滤器子元素过滤器的过滤规则是通过父元素和子元素的关系来获取相应的元素。 转自个人博客本来是单独整理了一个CSS选择器的,但是在jQuery中基本都有对应的,所以就不发了。 jQuery选择器,若未作特别说明,获取的都是元素集合。...

    charles_paul 评论0 收藏0

发表评论

0条评论

haoguo

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<