css 算是前端發展的一個痛點吧. 以前是裸寫css, 接著到後來的 inline css, 然後是, scss/sass. 從單一 file 到可以模塊化書寫css. 不過, 隨著前端發展, 現在的要求是組件化, 那麼, 以前那種直接 < link> 腳本也逐漸變為痛點. so, 2015/6 左右, 出來了 css-module 這個概念. 可以說, 這是一個專門為 component 編程而生的. 因為,他是和 js 緊密結合在一起的。
css-module 更具官方的說法就是: css-module 其實就是原來的 css 文件。只是他的 className 和 animation 最後都會被編譯為 object 形式的映射對象。
舉個簡單的例子就是:
.title {
background-color: red;
}
import styles from "./styles.css";
element.innerHTML =
`<h1 class="${styles.title}">
demo
</h1>`;
# css 格式
._styles__title_309571057 {
background-color: red;
}
# HTML 格式
<h1 class="_styles__title_309571057">
demo
</h1>
上面簡單的介紹了, css-module 到底是啥?Ps: 上面漏了一點, 怎麼將css 編譯嘞? 這裡,方法很多,有webpack, gulp等等. 看同學們自己的選擇了
命名方式首先,在 css-module 裡面. 以前在 css 中的命名方式,都變得 nonsense. 在 css-module 推薦一切命名方式使用 camelCase 的形式. 因為, 在寫組件的時候我們並不是來寫全局的樣式, 我們僅僅只是來完成我們當前組件的渲染. 所以, 這就要求, 這些組件所需和隱藏的 css 屬性, 我們必須一個不拉的全部寫上去, 比如: display, font, text-align 等等。
# 原始的css
.btn-normal{...}
# 使用 css-module
# 實際該文件的保存名就是 btn-style.css
.normal{...}
.clickStyle{...}
既然, 上文已經說了 css-module 裡面每個 style 都必須全部寫出所需的樣式, 那麼, 這樣重複的工作實在太多的... 誰 TM 還和你來什麼 module 不 module 的. 所以, 為了解決這樣的痛點, css-module 提供了 composes 這個概念。相當於就是我們以前 css 中的嵌套。
# 直接嵌套
.button{...}
.button .normal{...}
# 使用 composes 進行嵌套
.button{...}
.normal{
composes:button;
...
}
這個 composes 概念,就有點和 sass 中的 @extends 類似. 但,他倆編譯的結果點都不像. composes 是直接在 DOM 渲染時, 添加不同的 class。
而 @extends 只是將 class 變為嵌套而已。
.Button--common { ... }
.Button--normal {
@extends .Button--common;
...
}
.Button--common, .Button--normal {...}
.Button--normal {...}
但,這樣並不符合 css-module 實際編譯後改變 className 的 feature, 並且, @extends 的結果, 會造成很大的 className 冗餘。
具體說一下 css-module composes 的過程。
.common { ...}
.normal { composes: common; ... }
# 注意,這裡並沒有存在嵌套的情況,每個className 都是分離的.
.components_submit_button__common__abc5436 { ... }
.components_submit_button__normal__def6547 { ... }
styles: {
common: "components_submit_button__common__abc5436",
normal: "components_submit_button__common__abc5436 components_submit_button__normal__def6547",
}
# 添加 style.normal 樣式
<button class="components_submit_button__common__abc5436
components_submit_button__normal__def6547">
Submit
</button>
當然, composes 也可以引入其他 css 文件中的某個 class。
.primary {
color: #720;
}
.normal {
composes: primary from "../shared/colors.css";
}
另外, 寫好一個 css-module 有很多原則可以遵循的. 最出名的應該就是 單一職責原則。
單一職責因為 composes 的限制, 我們一般只能引入單一的 className 去包裹我們想要的 style 樣式. 但這樣,感覺有點浪費. 這點,感覺 sass 做的還是挺棒的。
@mixin subtle-shadow {
box-shadow: 0 0 4px -2px;
}
.some_element {
@include subtle-shadow;
}
所以, 為了在 css-module 達到同樣的目的. 我們一般只能使用單一的文件去包裹,所需的樣式內容. 像下面的 demo:
.element {
composes: large from "./typography.css";
}
css-module 主要是和 react 一起使用. 因為, react 存在, 才使前端組件化得到蓬勃的發展. so, 我們這裡,就需要藉助 webpack 對 import 的 css 文件進行編譯。
這裡就不多說了, 直接把配置放出來吧。
var ExtractTextPlugin = require('extract-text-webpack-plugin');
# 下面就是具體的 module.exports 裡面的內容
module: {
loaders: [
{ test: /\\.css$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss-loader') }
]
},
postcss: [
require('autoprefixer-core'),
require('postcss-color-rebeccapurple')
],
resolve: {
modulesDirectories: ['node_modules', 'components']
},
plugins: [
new ExtractTextPlugin('style.css', { allChunks: true })
]
如果,想更快的了解的話, 那就直接去線上 demo 看吧:
http://plnkr.co/edit/FbcJpb?p=preview
【您可能感興趣的文章】
一、高清屏概念解析與檢測設備像素比的方法
二、學習設計模式前需要知道的事情
三、表單驗證請進!!!
四、探知JS測試(1)
五、探知JS測試(2)
六、前端學習路徑加強版——來自《前端養成記》
七、前端技能圖譜
八、重構代碼的tricks
九、優化你的DOM
十、[VueJS] V1 與 V2 組件實體之差異
前端圈--打造專業的前端技術會議
為web前端開發者提供技術分享和交流的平臺
打造一個良好的前端圈生態,推動web標準化的發展
官網:http://fequan.com
微博:fequancom | QQ群:41378087
長按二維碼關注我們
投稿:content@fequan.com
贊助合作:apply@fequan.com