CSS module和React 中的應(yīng)用

為什么需要CSS模塊化 ?

由于CSS的規(guī)則是全局性的,添加任何一個(gè)樣式,在全局都有效,優(yōu)點(diǎn)是方便復(fù)用,缺點(diǎn)是會(huì)根據(jù)權(quán)重的計(jì)算造成樣式?jīng)_突,非常難以管理。

CSS 模塊化的方案

有了釘子,自然就會(huì)有錘子。隨著前端的發(fā)展出現(xiàn)了各種CSS模塊解決方案,主要分兩種:
一類是采用JS或者JSON 的方式寫CSS,比如 jsxstyle,react-style,雖然可以采用JS成熟方案來管理css, 但是它無法使用postcss ,sass等css預(yù)處理器,并且衍生了大批的api, 使用的代價(jià)較大。
另一類還是采用css 來寫樣式, 不過是通過工具生成CSS作用域的方式實(shí)現(xiàn)模塊化,比如CSS module。常用的BEM命名技巧或者團(tuán)隊(duì)中約定的方案來實(shí)現(xiàn)命名空間從而實(shí)現(xiàn)模塊化,不過約定總會(huì)出現(xiàn)問題,于是就出現(xiàn)了通過工具,比如webpack的css-loader根據(jù)算法,實(shí)現(xiàn)css 模塊化。

啟用CSS

webpack 內(nèi)置的 css-loader 自帶了CSS modoule, 配置如下:

rules: [
      ...
      {
        test: /\.css$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              modules: true,
              localIdentName: '[name]__[local]--[hash:base64:5]' // 生成樣式的命名規(guī)則
            }
           //或者采用loader: 'css?modules&localIdentName=[name]__[local]-[hash:base64:5]'的寫法
          }
        ]
       }
    ]

create-react-app 2.0以上的版本中內(nèi)置啟動(dòng)了CSS module, 如果需要特殊配置,則需要eject操作, 在webpack.config.js 中:

 // Adds support for CSS Modules (https://github.com/css-modules/css-modules)
// using the extension .module.css
      {
          test: cssModuleRegex,
          use: getStyleLoaders({
          importLoaders: 1,
          sourceMap: isEnvProduction && shouldUseSourceMap,
          modules: true,
          getLocalIdent: getCSSModuleLocalIdent,
          }),
      },
      

CSS module 用法

基本用法
/* components/Button.css */
.normal { /* normal 相關(guān)的所有樣式 */ }
.disabled { /* disabled 相關(guān)的所有樣式 */ }

// components/Button.js
import styles from './Button.css';
buttonElem.outerHTML = `<button class=${styles.normal}>Submit</button>`

//生成的HTML
<button class="button--normal-abc53">Submit</button>

CSS module 默認(rèn)采用局部樣式,即給每個(gè)css 名添加上了“:local”, 對(duì)應(yīng)的全局性的寫法:

/* 定義全局樣式 */
:global(.btn) {
  color: red;
}

/* 定義多個(gè)全局樣式 */
:global {
  .link {
    color: green;
  }
  .box {
    color: yellow;
  }
}

compose 組合樣式:
對(duì)于樣式復(fù)用,CSS module提供了唯一的方式 "compose":

/* components/Button.css */
.base { /* 所有通用的樣式 */ }

.normal {
  composes: base;
  /* normal 其它樣式 */
}

.disabled {
  composes: base;
  /* disabled 其它樣式 */
}

import styles from './Button.css';
buttonElem.outerHTML = `<button class=${styles.normal}>Submit</button>`

// 生成后的html
<button class="button--base-fec26 button--normal-abc53">Submit</button>

多CSS class 的寫法:

.normal {
  composes: base;
  /* normal 其它樣式 */
}

.disabled {
  composes: base;
  /* disabled 其它樣式 */
}

import styles from './Button.css';
buttonElem.outerHTML = `<button className={ `${styles.normal}  ${style.disbale} `}>Submit</button>`

Sass 變量與JS共享

/* config.scss */
$primary-color: #f40;

// 內(nèi)置語法,可以到處該變量
:export {
  primaryColor: $primary-color;
}

/* app.js */
import style from 'config.scss';

// 會(huì)輸出 #F40
console.log(style.primaryColor);
使用技巧

Css module 作者建議:
1.不使用選擇器,只使用 class 名來定義樣式
2.不層疊多個(gè) class,只使用一個(gè) class 把所有樣式定義好
3.不嵌套
4.使用 composes 組合來實(shí)現(xiàn)復(fù)用

Css module 在React中的實(shí)踐

采用classnames來增強(qiáng)CSS module 在react 中的使用,類似Angular 中的樣式指令:

var classNames = require('classnames');

class Button extends React.Component {
  // ...
  render () {
    var btnClass = classNames({
      btn: true,
      'btn-pressed': this.state.isPressed,
      'btn-over': !this.state.isPressed && this.state.isHovered
    });
    return <button className={btnClass}>{this.props.label}</button>;
  }
}
應(yīng)用全局樣式
...
// 引入全局樣式 
import 'xxx/common.css';
// 引入局部樣式
import styles from './xxx.module.css';
...
<div className={styles.wrapper}>
  <!-- 同時(shí)引入全局、局部樣式,且如果className帶中劃線,用['className']代替 -->
  <button className={`btn ${styles['my-btn']}`}>save</button>
</div>
...

參考鏈接:https://zhuanlan.zhihu.com/p/20495964

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML標(biāo)準(zhǔn)。 注意:講述HT...
    kismetajun閱讀 28,803評(píng)論 1 45
  • 學(xué)習(xí)流程 參考文檔:入門Webpack,看這篇就夠了Webpack for React 一. 簡單使用webpac...
    Jason_Zeng閱讀 3,257評(píng)論 2 16
  • 目錄第1章 webpack簡介 11.1 webpack是什么? 11.2 官網(wǎng)地址 21.3 為什么使用 web...
    lemonzoey閱讀 1,826評(píng)論 0 1
  • 朋友說, 父親今日去世, 一切安好,勿掛心。 但我不想只在傷痛時(shí)才去撫慰。 所以你未收到我的訊息, 未收到我的不安...
    伊思xxx閱讀 472評(píng)論 0 7
  • 不是愛情不肯放過你,不是回憶不肯放過你,不是宿命不肯放過你,而是你自己不肯放過你自己。 我們終于變成了我 你
    夢(mèng)琪琪昂閱讀 293評(píng)論 0 1

友情鏈接更多精彩內(nèi)容