参考:
copy form 
CSS之路:css->less->moudleCss->styleComponet
OOCSS
面向对象的 CSS ,独立于应用逻辑书写,鼓励 html 与 css 分离和代码的复用
OOCSS遵循两个原则:
- 独立的结构和样式
 - 独立的容器和内容
 
具体实现上可以是拆分为基类和修饰类,将尽可能多的公共属性抽象到基础类,然后将每个变体的样式归类为修饰符类。
<div class="container"><div class="row"><div class="col-4"><button type="button" class="btn btn-success hidden">Success</button></div><div class="col-8"><button type="button" class="btn btn-primary">Primary</button></div></div></div>
优点:
css复用率高,扩展性好;- 具备良好的可读性和可维护性;
 - 代码量比较少,天然 
Atomic CSS; 
缺点:
- 多人协作模式下,class 选择器容易冲突,没有解决命名空间的问题
 - 基础类库开发周期时间偏长
 
SMACSS
通过结构化命名,将类名模组分组,达到可扩展的目的。与OOCSS相比,SMACSS 更像是一套模板指导 CSS 的书写。
<div id="section"><div class="l-flex"><div class="l-col l-col-4"><button type="button" class="btn-success is-hidden">Success</button></div><div class="l-col l-col-8"><!-- 扩展btn样式,创建子模块 --><button type="button" class="btn-primary">Primary</button></div></div></div>
分类:
- Base:重置元素的基本样式,保证元素在任意浏览器中,视觉样式具有一致性。实现如:reset.css、normalize.css;
 - Layout:布局规则将页面分块,将一个或多个模块组合在一起,命名以 
l-开头; - Module:模块是设计中可重用的模块化部分,也是 SMACSS 里最重要的一部分,不强制以 
m-开头; - State:状态规则是描述我们的模块或布局在特定状态下的外观的方式。比如 Tab 是否选中,命名一般以 
is-开头; - Theme:主题规则与状态规则相似,它们描述了模块或布局的外观;
 
优缺点:同 OOCSS
BEM
Block__Element—Modifier
使用 Block、Element、Modifier 描述页面结构
Block即为区块,可以独立存在;Element可以理解为元素,它依附于Block存在,与Block使用__连接;Modifier用于描述Block或Element的外观或状态,与他们使用--连接;
<form class="form form--theme-xmas form--simple"><input class="form__input" type="text" /><input class="form__submit form__submit--disabled" type="submit" /></form>
优点:
- 制定了一套易与理解的
CSS编码规范; - 可读性高,通过 class 的命名,可以得知元素的结构;
 - 很大程度解决了命名冲突的问题;
 
缺点:
- 重新定义 
Block与Element的含义,容易造成混淆; - 需要与页面结构并行维护一套
CSS逻辑; - 命名过长,产出的 
size偏大; 
Shadow DOM
Web components 标准的一部分,将封装的 Showdow DOM 附加到元素并控制其关联的功能。
在 Shadow DOM 中定义的 CSS 样式只会在 ShadowRoot 下生效,很好的实现了代码的隔离。
// jslet tmp1 = document.createElement('template');tmp1.innerHTML = `<style>.btn {display: inline-block;font-weight: 400;line-height: 1.5;text-align: center;text-decoration: none;vertical-align: middle;user-select: none;border: 1px solid transparent;padding: .375rem .75rem;font-size: 1rem;border-radius: .25rem;transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;}.btn-primary {color: #fff;background-color: #0d6efd;border-color: #0d6efd;}</style><button type="button" class="btn btn-primary">I'm in shadow dom!</button><slot></slot>`;customElements.define('x-button', class extends HTMLElement {constructor() {super();let shadowRoot = this.attachShadow({ mode: 'open' });shadowRoot.appendChild(tmp1.content.cloneNode(true));}});// html<x-button></x-button>
优点:
- 面向未来的原生组件写法
 - 与页面的其他代码天然隔离
 - 可增强现有 
HTML标签,创建可重用的新标签(Custom Element) 
缺点:
- 对平台实现有强依赖,浏览器支持度一般
 - 目前只能使用 
link标签引入外部样式 (存在绘制闪烁的问题),其他形式的外部样式 (例如全局的CSS重置) 无法渗透进shadowDOM内部 (已有提案解决) 
CSS-in-JS
React原生自带内联样式属于CSS-In-Js的一种,
同时还有其他几种方案
styled-componentsnts
借助 js 语言的灵活性,使用 js 样式化组件,在组件的运行时,将CSS 附加到 DOM 当中。
import React from 'react';import styled, { css } from 'styled-components';const Button = styled.button`display: inline-block;font-weight: 400;line-height: 1.5;text-align: center;text-decoration: none;vertical-align: middle;user-select: none;border: 1px solid transparent;padding: .375rem .75rem;font-size: 1rem;border-radius: .25rem;transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;${props => props.primary && css`color: #fff;background-color: #0d6efd;border-color: #0d6efd;`}`// OR// A new component based on Button, but with some override stylesconst PrimaryButton = styled(Button)`color: #fff;background-color: #0d6efd;border-color: #0d6efd;`;export default ShowButton() {return (<div><Button>Normal</Button><Button primary>Primary</Button><PrimaryButton>Primary</PrimaryButton></div>)}
优点:
- 很轻松的实现
css与js变量共享,易于维护; - 代码中只存在 
javaScript,具有跨平台优势; - 不需借助编译工具,即可提取 
Critical CSS; 
缺点:
- 风格比较激进
 - 有一定学习理解门槛
 - 没有统一的标准约束
styled-jsx
nextjs捆绑自带的css in js 方案
https://nextjs.org/docs/basic-features/built-in-css-support#css-in-js
https://github.com/vercel/styled-jsxtailwind css
https://tailwindcss.com/ 
CSS modules
https://github.com/camsong/blog/issues/5
http://www.ruanyifeng.com/blog/2016/06/css_modules.html
利用 webpack 之类的工具,编译阶段将类名加上随机的 hash 值,以回避命名冲突的问题
比如在某个nextjs项目上,使用less+moudle,解决组件和页面类名冲突
:global 设置成全局class(不加hash值)
CSS Houdini
开放 css 底层 api,开发者可通过接口自行扩展 css
文章介绍了几种前端发展中出现的 css 方案,其实在解决的下面提及的几个问题:
- 作用域(全局 -> 组件)
 - 模块化与代码复用(提高可维护性)
 - CSS Atomic 化(更小的代码尺寸)
 - 提取 Critical CSS(更快的首屏加载体验)
 - 跨平台(Write once,run every where)
 
方案可能会过时,但其中折射隐含的思想,会以新的形式流传进化,它值得每个前端开发人员深入学习与思考。总而言之,技术没有银弹,实际开发中亦需要不断权衡利弊,明确使用场景,选择合适的方法维护项目。
参考链接:
https://caniuse.com/
http://oocss.org/
http://smacss.com/
https://github.com/Polymer/polymer
https://www.cssinjsplayground.com/
https://styled-components.com/
https://github.com/webpack-contrib/css-loader#modules
https://github.com/WICG/webcomponents/blob/gh-pages/proposals/css-modules-v1-explainer.md
https://developer.mozilla.org/zh-CN/docs/Web/Houdini
https://www.smashingmagazine.com/2016/03/houdini-maybe-the-most-exciting-development-in-css-youve-never-heard-of/


