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同样适用。
同行们是怎么解决的?
- Shadow DOM Style
Shadow DOM的样式是完全隔离的,这就意味着即使你在主文档中有一个针对全部 <h3>
标签的样式选择器,这个样式也不会不经你的允许便影响到 shadow DOM 的元素。
举个例子:
<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>
这就很好地为Web Component
建立了CSS Namespace机制。
- Facebook: CSS in JS
http://blog.vjeux.com/2014/javascript/react-css-in-js-nationjs.html
比较变态的想法,干脆直接不要用classname,直接用style,然后利用js来写每个元素的style……
例如,如果要写一个类似button:hover
的样式,需要写成这样子:
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-native和css-layout,就可以发现,如果想通过React打通客户端开发,style几乎成了必选方案。
我们的方案
我们期望用类似
Web Component
的方式去写Component的样式,但在低端浏览器根本就不支持Shadow DOM
,所以,我们基于BEM来搭建了一种CSS Namespace的方案。
我们的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.html
和main.js
中的对应选择器,在构建中也会自动替换成Component名。
这有什么好处呢?
- 基于路径的Namespace,路径没有冲突,那么在该项目中Namespace也不会冲突
- Component可以任意改名,或复制重构,不会产生任何影响,便于Component的重构和扩展
- Component相对隔离,不会对外部产生影响
- Component非绝对隔离,外部可以对其产生一定影响
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。