Ques核心思想——CSS Namespace

Facebook’s challenges are applicable to any very complex websites with many developers. Or any situation where CSS is bundled into multiple files and loaded asynchronously, and often loaded lazily. ——@vjeux 将Facebook换成Tencent一样适用。javascript

同行们是怎么解决的?

  • Shadow DOM Style

Shadow DOM的样式是彻底隔离的,这就意味着即便你在主文档中有一个针对所有 <h3> 标签的样式选择器,这个样式也不会不经你的容许便影响到 shadow DOM 的元素。css

举个例子:html

举个栗子

<body>  
  <style>
    button {
      font-size: 18px; font-family: '华文行楷'; } </style> <button>我是一个普通的按钮</button> <div></div> <script> var host = document.querySelector('div'); var root = host.createShadowRoot(); root.innerHTML = '<style>button { font-size: 24px; color: blue; } </style>' + '<button>我是一个影子按钮</button>' </script> </body> 

Nacespace

这就很好地为Web Component创建了CSS Namespace机制。java

  • Facebook: CSS in JS

http://blog.vjeux.com/2014/javascript/react-css-in-js-nationjs.htmlreact

比较变态的想法,干脆直接不要用classname,直接用style,而后利用js来写每一个元素的style……git

例如,若是要写一个相似button:hover的样式,须要写成这样子:github

var Button = React.createClass({ styles: { container: { fontSize: '13px', backgroundColor: 'rgb(233, 234, 237)', border: '1px solid #cdced0', borderRadius: 2, boxShadow: '0 1px 1px rgba(0, 0, 0, 0.05)', padding: '0 8px', margin: 2, lineHeight: '23px' }, depressed: { backgroundColor: '#4e69a2', borderColor: '#1A356E', color: '#FFF' }, }, propTypes: { isDepressed: React.PropTypes.bool, style: React.PropTypes.object, }, render: function() { return ( <button style={m( this.styles.container, // 若是压下按钮,mixin压下的style this.props.isDepressed && this.styles.depressed, this.props.style )}>{this.props.children}</button> ); } }); 

几乎等同于脱离了css,直接利用javascript来实现样式依赖、继承、混入、变量等问题……固然若是咱们去看看React-nativecss-layout,就能够发现,若是想经过React打通客户端开发,style几乎成了必选方案。web

咱们的方案

咱们指望用相似Web Component的方式去写Component的样式,但在低端浏览器根本就不支持Shadow DOM,因此,咱们基于BEM来搭建了一种CSS Namespace的方案。react-native

咱们的Component由下面3个文件组成:浏览器

  • main.html 结构
  • main.js 逻辑
  • main.css 样式

可参考:https://github.com/miniflycn/Ques/tree/master/src/components/qtree

能够发现咱们的css是这么写的:

.$__title { margin: 0 auto; font-size: 14px; cursor: default; padding-left: 10px; -webkit-user-select: none; } /** 太长忽略 **/ 

这里面有长得很奇怪的.$__前缀,该前缀是咱们的占位符,构建系统会自动将其替换成Component名,例如,该Component为qtree,因此生成结果是:

.qtree__title {
    margin: 0 auto; font-size: 14px; cursor: default; padding-left: 10px; -webkit-user-select: none; } /** 太长忽略 **/ 

一样道理,在main.htmlmain.js中的对应选择器,在构建中也会自动替换成Component名。

这有什么好处呢?

  1. 基于路径的Namespace,路径没有冲突,那么在该项目中Namespace也不会冲突
  2. Component能够任意更名,或复制重构,不会产生任何影响,便于Component的重构和扩展
  3. Component相对隔离,不会对外部产生影响
  4. Component非绝对隔离,外部能够对其产生必定影响
相关文章
相关标签/搜索