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非絕對隔離,外部能夠對其產生必定影響
相關文章
相關標籤/搜索