這篇文章來一起了解 css
模組化的用法和原理 ,dome 地址:css modules ?
區域性作用域
一般我們引入頁面的CSS
的作用域都是全域性的,都是對這個頁面起作用,產生區域性的作用域,就是使用一個獨一無二的class
的名稱,不會和其它選擇器重名的,CSS Modules
就是這個原理。下面我們看一段程式碼
import $ from `jquery`;
import styles from `./main.css`;
import test from `./test.html`;
$(`body`).append($(`<div><h1>我會變綠</h1></div>`));
$(`div h1`).addClass(styles.testGreen);
$(`body`).append(test).find(`h2`).addClass(styles.testBlue);
複製程式碼
上面的程式碼我把main.css
輸入到style
物件,然後下面用了styles.testGreen
物件的屬性形式呼叫,就會應用main.css
裡的樣式
.testGreen {
color: green;
}
複製程式碼
構建工具(webpack
)編譯成一個雜湊字串
<div>
<h1 class="_305zeUSoiGREv3GqPa9H8F">我會變綠</h1>
</div>
複製程式碼
main.css
也會同時編譯
._305zeUSoiGREv3GqPa9H8F {
color: #aaf200;
}
複製程式碼
這樣一來,這個類名就是獨一無二的了,只對應用的元件有效。
**CSS Modules
**支援不同的構建工具,這裡我使用的是webpack
,下文都是以webpack
為例。
下面我們來看下 webpack.config.js
module.exports = {
context: __dirname + `/src`,
devtool: `eval-source-map`, //配置生成Source Maps,選擇合適的選項
entry: {
app: [`./app.js`, `./test.js`],
},
output: {
path: __dirname + `/dist`,
filename: `bundle.js`,
publicPath: `/assets`,
},
module: {
loaders: [
{test: /.json$/,loader: `json-loader`},
{test: /.js$/,exclude: /node_modules/,loader: `babel-loader`},
{test: /.css$/,loader: ExtractTextPlugin.extract({
fallbackLoader: "style-loader",
loader: {
loader: "css-loader",
query: {
modules: true
}
}
})
},
{test: /.html$/,loader: `html-loader`},
]
},
plugins: [
new ExtractTextPlugin(`style.css`)
]
};
複製程式碼
上面的程式碼可以看到,query:{modules:true}
代表開啟 CSS Modules
模組,這裡還配置了把所以得css
合併一個檔案,具體的可以瞭解webpack
的extract-text-webpack-plugin
外掛。
全域性作用域
CSS Modules
允許用:global(.className)
的語法宣告一個全域性的作用域。加了:global
的不會被編譯成雜湊值。
:global(.title) {
color: black;
}
.title {
color: red;
}
複製程式碼
test.js
使用普通的寫法,就會引用全域性的.title
的樣式
import $ from `jquery`;
import styles from `./main.css`;
import test from `./test.html`;
$(`body`).append($(`<div><h1>我是title</h1></div>`));
$(`div h1`).addClass(`title`);
複製程式碼
結果h1
的title顯示黑色。
Class的組合
在 CSS Modules
裡,一個選擇器可以繼承另一個選擇器。
在mian.css
裡,我讓.testBlue
繼承.testBg
類
.testBg {
background-color: red;
}
.testBlue {
color: blue;
composes: testBg;
}
複製程式碼
不用修改test.js
,應用了.testBlue
就會有一個紅色的背景。
編譯結果:
.eh33VC37uFHXkCZ8LfKYd {
background-color: #ff0000;
}
.xrmZso54fTBX29J9G65Ai {
color: #0c77f8;
}
複製程式碼
相應的html
程式碼:
<h3 class="xrmZso54fTBX29J9G65Ai eh33VC37uFHXkCZ8LfKYd _2gsuNWm9029FHPYJP62C-t">
我會變藍
</h3>
複製程式碼
輸入變數
CSS Modules
支援使用變數,不過要安裝 PostCSS 和 postcss-modules-values。
$ npm install --save postcss-loader postcss-modules-values
複製程式碼
把postcss-loader
加入webpack.config.js
.
{
test: /.css$/,
loader: `style-loader!css-loader?modules!postcss-loader`
},
複製程式碼
然後我在colors.css
裡定義了一些變數。
@value blue: #0c77f8;
@value red: #ff0000;
@value green: #aaf200;
複製程式碼
在main.css
裡可以這樣引用變數
@value colors: "./color.css";
@value blue, red, green from colors;
.title {
color: red;
}
.testBg {
background-color: red;
}
.testGreen {
color: green;
}
.testBlue {
color: blue;
composes: testBg;
composes: div;
}
複製程式碼
這樣就可以把colors.css
的變數拿過來用了,是不是很神奇。