本文作者:IMWeb 杨文坚 原文出处:IMWeb社区 未经同意,禁止转载 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的样式是完全隔离的,这就意味着即使你在主文档中有一个针对全部 <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 = '<style>button { font-size: 24px; color: blue; } </style>' +
'<button>我是一个影子按钮</button>'
</script>
</body>
这就很好地为Web Component
建立了CSS Namespace机制。
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个文件组成:
可参考: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名。
这有什么好处呢?