參考文章:
CSS Modules 用法教程-阮一峰
css module
css模塊化及CSS Modules使用詳解
背景-CSS 模塊化
CSS 模塊化的解決方案有很多,但主要有兩類:
一類是徹底拋棄 CSS,使用 JS 或 JSON 來寫樣式。Radium,jsxstyle,react-style 屬于這一類。
- 優(yōu)點是能給 CSS 提供 JS 同樣強大的模塊化能力;
- 缺點是不能利用成熟的 CSS 預處理器(或后處理器) Sass/Less/PostCSS,:hover 和 :active 偽類處理起來復雜。
另一類是依舊使用 CSS,但使用 JS 來管理樣式依賴,代表是 CSS Modules。
- CSS Modules 能最大化地結合現(xiàn)有 CSS 生態(tài)和 JS 模塊化能力,API 簡潔到幾乎零學習成本。
- 發(fā)布時依舊編譯出單獨的 JS和 CSS。
- 它并不依賴于 React,只要你使用 Webpack,可以在 Vue/Angular/jQuery 中使用。
- 是我認為目前最好的CSS 模塊化解決方案
前言
CSS Modules 提供各種插件,支持不同的構建工具。
本文使用的是 Webpack 的css-loader插件,因為它對 CSS Modules 的支持最好,而且很容易使用。
為什么需要CSS Modules
解決類名沖突問題
CSS的規(guī)則都是全局的,任何一個組件的樣式規(guī)則,都對整個頁面有效。因此,為了使用獨特的樣式,要保證元素的類名不沖突。這對于大型項目而言是很難的。
CSS Modules的思路:產生一個獨一無二的class的名字
,不會與其他選擇器重名
實現(xiàn)原理
-
開啟了css module后,構建工具webpack的css-loader會
將樣式中的類名進行轉換,轉換為一個唯一的hash值
由于hash值是根據模塊路徑和類名生成的
,因此,不同的css模塊,哪怕具有相同的類名,轉換后的hash值也不一樣。 -
根據導出結果可知,我們就可以在js代碼中
獲取到css模塊導出的結果,從而應用類名
// src/index.js
import style from "./assets/style.css"
console.log(style)
const div = document.getElementById("div1");
div.className = style.c1;
打印結果如下:
語法
參考CSS Modules 用法教程-阮一峰
0.配置
webpack.config.js文件如下:
module.exports = {
entry: __dirname + '/index.js',
output: {
publicPath: '/',
filename: './bundle.js'
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015', 'stage-0', 'react']
}
},
{
test: /\.css$/,
loader: "style-loader!css-loader?modules"
},
]
}
};
關鍵的一行是style-loader!css-loader?modules,它在css-loader后面加了一個查詢參數modules,表示打開 CSS Modules 功能。
0.1初始代碼
App.css:
.title {
color: red;
}
React組件App.js:
import React from 'react';
import style from './App.css';
export default () => {
return (
<h1 className={style.title}>
Hello World
</h1>
);
};
1. 局部作用域
使用了 CSS Modules 后,樣式默認局部
相當于給每個 class 名外加加了一個 :local,以此來實現(xiàn)樣式的局部化
.normal {
color: green;
}
/* 以上與下面等價 */
:local(.normal) {
color: green;
}
同上。h1標題會顯示為紅色
2.全局作用域
CSS Modules 允許使用**:global(.className)**的語法,聲明一個全局規(guī)則。
凡是這樣聲明的class,都不會被編譯成哈希字符串。
e.g.
App.css加入一個全局class:
.title {
color: red;
}
:global(.title) {
color: green;
}
/* 定義多個全局樣式 */
:global {
.link {
color: green;
}
.box {
color: yellow;
}
}
App.js使用普通的class的寫法:
import React from 'react';
import styles from './App.css';
export default () => {
return (
<h1 className="title">
Hello World
</h1>
);
};
h1標題顯示為綠色。
CSS Modules 還提供一種顯式的局部作用域語法:local(.className),等同于.className,所以上面的App.css也可以寫成下面這樣:
:local(.title) {
color: red;
}
:global(.title) {
color: green;
}
3.定制哈希類名
css-loader默認的哈希算法是[hash:base64]
,這會將.title
編譯成._3zyde4l1yATCOkgn-DBWEL
這樣的字符串。
webpack.config.js里面可以定制哈希字符串的格式:
module: {
loaders: [
// ...
{
test: /\.css$/,
loader: "style-loader!css-loader?modules&localIdentName=[path][name]---[local]---[hash:base64:5]"
},
]
}
你會發(fā)現(xiàn).title
被編譯成了demo03-components-App---title---GpMto
4.Class的組合
在 CSS Modules 中,一個選擇器可以繼承另一個選擇器的規(guī)則,這稱為"組合"(“composition”)
在App.css中,讓.title
繼承.className
:
.className {
background-color: blue;
}
.title {
composes: className;
color: red;
}
運行,會看到紅色的h1在藍色的背景上。
打印App.js中導入的style,結果如下:
5.輸入其他模塊
選擇器也可以繼承其他CSS文件里面的規(guī)則
e.g. another.css文件
.className {
background-color: blue;
}
App.css繼承another.css里面的規(guī)則
.title {
composes: className from './another.css';
color: red;
}
藍色的背景上有一個紅色的h1(相當于class的組合,只不過來自另一個文件)
6.輸入變量
CSS Modules 支持使用變量,不過需要安裝 PostCSS 和 postcss-modules-values
- 把postcss-loader加入webpack.config.js:
var values = require('postcss-modules-values');
module.exports = {
entry: __dirname + '/index.js',
output: {
publicPath: '/',
filename: './bundle.js'
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015', 'stage-0', 'react']
}
},
{
test: /\.css$/,
loader: "style-loader!css-loader?modules!postcss-loader"
},
]
},
postcss: [
values
]
};
- 在colors.css里面定義變量
@value blue: #0c77f8;
@value red: #ff0000;
@value green: #aaf200;
- App.css可以引用這些變量
@value colors: "./colors.css";
@value blue, red, green from colors;
.title {
color: red;
background-color: blue;
}
會看到藍色的背景上有一個紅色的h1文章來源:http://www.zghlxwxcb.cn/news/detail-744779.html
項目使用
一般的腳手架都默認集成了 CSS Modules
,比如 React 官方的腳手架create-react-app,已經將 CSS Modules 集成進來了,可以直接使用。
我有個問題,螞蟻的前端腳手架Ant Design Pro是基于react的,這是不是意味著它默認也集成了 CSS Modules。(當然,它的確是集成了的,只是,是不是基于react的腳手架也都默認集成了CSS Modules)文章來源地址http://www.zghlxwxcb.cn/news/detail-744779.html
到了這里,關于CSS Modules - CSS模塊化的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!