前段時(shí)間在閱讀 ant-design-pro 的源碼時(shí),發(fā)現(xiàn)了一種沒見過的 CSS 書寫方法,它能有效地解決 class 命名重復(fù)的問題。后面通過 Google 得知這是 CSS Modules,它能為 CSS 提供默認(rèn)的局部作用域。
基本使用
CSS Modules 使用起來十分簡單,它支持多種構(gòu)建工具,這里以我在一個(gè) React 項(xiàng)目中的實(shí)際使用為例進(jìn)行說明。
在構(gòu)建項(xiàng)目時(shí)使用的是 create-react-app 腳手架,通過 react-app-rewired 進(jìn)行配置的修改。通過 css-loader 支持 CSS Modules,對(duì)應(yīng)的 webpack 配置如下:
{
loader: require.resolve('css-loader'),
options: {
modules: true,
importLoaders: 1,
localIdentName: '[local]___[hash:base64:5]'
}
}
css-loader 內(nèi)置了 CSS Modules,設(shè)置 modules 參數(shù)為 true 即可啟用。
配置好了 CSS Modules 之后,在代碼中通過下面的方式書寫樣式:
// 導(dǎo)入樣式樣式文件
import styles from './BasicLayout.scss';
return (
// 導(dǎo)入的 styles 類似對(duì)象一樣使用,將 className 作為 key
<div className={styles.logo}>
<h1>后臺(tái)管理系統(tǒng)</h1>
</div>
);
最后,渲染出來的效果如下圖所示(戳原文查看圖片)。
全局作用域
CSS Modules 為 CSS 提供了局部作用域,但是有時(shí)候確實(shí)需要定義一些全局的樣式,這時(shí)候該怎么辦呢?
CSS Modules 允許使用 :global(.className) 的語法,聲明一個(gè)全局規(guī)則。凡是這樣聲明的 class,都不會(huì)被編譯成哈希字符串。如果需要聲明多個(gè)全局規(guī)則,可以使用下面這種方式:
:global {
.clearfix {
zoom: 1;
}
.clearfix:after, .clearfix:before {
content: " ";
display: table
}
.clearfix:after {
clear: both;
visibility: hidden;
font-size: 0;
height: 0
}
}
自定義樣式名
css-loader 默認(rèn)生成的樣式名是 [hash:base64],這會(huì)將 .title 編譯成 ._3zyde4l1yATCOkgn-DBWEL 這樣的字符串。我們可以通過添加 localIdentName 參數(shù)來自定義樣式名的生成規(guī)則,如上面 webpack 配置中的 localIdentName: '[local]___[hash:base64:5]',這樣 .title 就會(huì)被編譯成 .title___fhba 這樣的字符串。
樣式復(fù)用
CSS Modules 讓樣式變得唯一了,那么我們要如何復(fù)用已有的樣式呢?
CSS Modules 提供一個(gè) composes 方法用于樣式復(fù)用。例如,在 base.css 中有這樣的一條樣式:
.className {
background-color: red;
}
然后,我們可以在另外一個(gè)樣式文件中這樣引用它:
.title {
composes: className from './base.css';
font-size: 18px;
}
注意事項(xiàng)
- CSS Modules只轉(zhuǎn)換 class 和 id 選擇器。
- 在 js 中 styles 就像一個(gè)對(duì)象一樣使用,因此如果樣式名為
.site-wrapper,那么在使用時(shí)應(yīng)該寫成styles['site-wrapper']。我們可以設(shè)置 css-loader 的 camelCase 參數(shù)為true來啟動(dòng)自動(dòng)轉(zhuǎn)換,這樣在 js 中就可以通過styles.siteWrapper使用。