构建CSS现在有很多成熟的方法, 例如使用新的命名空间, 扩充数据属性或在JavaScript里面定义CSS. 这些方法你可以从BootStrap, ElementUI这类UI框架中找到影子. 下面, 介绍3种比较常用的方法.
1.OOCSS方法(Object-Oriented CSS 面向对象的CSS)
[cc lang=”html”]
标题
[/cc]
上面这段代码就展示了如何使用OOCSS方法创建一个可切换的HTML代码, OOCSS有两个主要的原则:
分离结构和外观
分离容器和内容
分离结构和外观
这里的toggle用来控制结构, simple用来控制外观,这就是分离结构和外观的表现. 这样可以实现外观的复用, 例如当前的simple皮肤使用直角, 而complex皮肤可能使用圆角, 还加了阴影.
分离容器和内容
这里使用toggle-title就是分离容器和内容的表现, 无论toggle-title的容器是用的<h1>还是<h2>或者是<div>, 一旦加上了toggle-title这个类名, 那么该容器均已该类名所定义的样式呈现内容.
2.SMACSS方法(Scalable and Modular Architecture for CSS 模块化架构的可扩展的CSS)
[cc lang=”html”]
标题2
[/cc]
上面的这段代码基本展示了如何使用SMACSS方法,在我个人的理解中, OOCSS更多的其实是提供了一种CSS构建思想, 该思想要求将结构和外观分离, 将容器和内容分离. 但是并没有提供一套完整的CSS构建规范, 而SMACSS是提供了一套样式系统, 该样式系统有5个具体类别:
基础: 如果不添加CSS类名, 标记会以什么外观呈现
布局: 把页面分成一些区域
模块: 设计中的模块化, 可复用的单元
状态: 描述在特定的状态或情况下, 模块或布局的的显示方法
主题: 一个可选的视觉外观层, 可以让你更换不同主题
基础
[cc lang=”css”]//base.css
body, form {
margin: 0;
padding: 0;
}
a {
color: #039;
}
a:hover {
color: #03F;
[/cc]
这里的布局指的是页面中一些通用的布局组件, 例如头部, 侧边栏, 主体和底部这些. 这些布局组件会在多个页面通用, 所以最好把其放入到一个css文件中. 方便复用. 在SMACSS中, 推荐将布局容器的顶级标签设置为id, 这样确保了每个页面中拥有唯一持有该样式的布局容器, 也方便其css和js选择器的使用. 当然, 你也可以使用一个唯一的类名替代id.
[cc lang=”css”]
//layout.css
#header, #article, #footer {
width: 960px;
margin: auto;
}
#article {
border: solid #CCC;
border-width: 1px 0 0;
}
[/cc]
模块是指页面中可以单独分离并提取出来复用的部分, 例如导航条, 侧边栏, 对话框或一些widget等. 所以, 模块禁止使用id, 而应该采用类名的方式.
[cc lang=”css”]
//module.css
//module1
.module1 > h2 {
padding: 5px;
}
.module1 span {
padding: 5px;
}
//module2
.module2 > h2 {
padding: 10px;
}
.module2 span {
padding: 10px;
}
}[/cc]
状态
[cc lang=”html”]
[/cc]
State 负责定义元素不同的状态下,所呈现的样式. 上面的一段代码中,已is-开头的就是表示状态的类名, is-collapsed, is-error等类名不会单独使用, 而是和前面的布局和模块一起使用. 下面的代码, 就是在tab栏模块和状态一起使用:
[cc lang=”css”]
//state.css
.tab {
background-color: purple;
color: white;
}
.is-tab-active {
background-color: white;
color: black;
}
[/cc]
主题
这里的主题理解为皮肤更加合适, 已上面的代码为例, 在module-name.css中定义了边框除颜色之外的样式, 在theme.css文件中定义了该边框的颜色, 这样的好处就是, 如果定义其他颜色的类名去覆盖这些有颜色的样式, 那么就可以通过类名去切换皮肤的颜色. 达到更换主题的效果.
[cc lang=”css”]
// module-name.css
.mod {
border: 1px solid;
}
//theme.css
.mod {
border-color: blue;
}
[/cc]
3.BEM方法(Block Element Modifier 块元素修饰符)
[cc lang=”html”]
标题3
…
[/cc]
BEM是由Yandex提出的给一个CSS命名方法, 该方法要求使用一个CSS类名, 尽可能使用以下三者组成:
block-name__elem-name_mod-name_mod-val
1. Block modifier name
menu_hidden
menu_theme_islands
2.Element modifier name
menu__item_visible
menu__item_type_radio
块名: 所属组件的名称
元素: 元素在块里面的名称
修饰符: 任何与块或元素相关联的的修饰符
块名
这里的块名很多初学者会以为是inline-block中的块, 其实这里的块名指的是一个独立的模块或组件. 例如一个<header>可以用做一个模块, <header>中的<nav>可以用作一个模块. 模块之间是可以相互嵌套的. 上面的示例代码中 ,toggle就是一个独立的模块
元素
元素是指无法用在其他块名中的部分, 在BEM方法中, 元素跟在块名后面使用__连接, 之所以约定使用双下划线是因为方便在块名中使用单下划线命名. 上面示例代码中的toggle__control, toggle__title就是块名+元素的命名方式.
修饰符
修饰符与SMACSS中的状态类似, 在BEM方法中, 修饰符需要跟在元素后面使用–连接. 有的人会觉得这种写法会使得代码冗余, SMACSS使用is-active同样可以表示同样的作用, 为什么上面的代码要使用toggle__details–active呢? 其实, 如果单独看open和is-active这两个名字, 我们并不知道它们的含义是什么, 但是当看到一个toggle__details–active的类名, 我们就知道它是表示: 这个元素的名称是details, 位置在toggle组件里, 状态为active.
具体用法
[cc lang=”html”]
WRONG:
RIGHT #1: Make a new block
RIGHT #2: Make your bem-tree with a single nested elements
BEM-tree:
.menu {}
.menu__item {}
.menu__link {}
.menu__text {}
reference https://en.bem.info/methodology/key-concepts/#element
[/cc]