国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

簡單易懂的CSS Modules

chunquedong / 1957人閱讀

摘要:結(jié)果是選手獲勝,名為的元素,最終的值為。而合理的命名約定,的確是組織代碼的有效策略。它們會再由轉(zhuǎn)換為適當?shù)慕M合。雖然本文為了嚴謹,結(jié)果寫了相當長的篇幅,但希望你讀過之后,還能覺得是簡單易懂的。

不要誤會,CSS Modules可不是在說“css模塊化”這個好像在某些地方見過的詞,它其實是特指一種近期才出現(xiàn)的技術(shù)手段。

什么技術(shù)手段呢?請待后文說明。

層疊樣式表

我們知道,css的全名叫做層疊樣式表,這個“層疊”到底是什么意思呢?

有一種解釋是,如果你先寫了一條樣式規(guī)則(選手1):

.title {
    color: silver;
}

然后又在后邊寫了一條類似的(選手2):

.title {
    color: gold;
}

因為名字相同,選手2就會和選手1打起來(讓你丫冒充我!)。結(jié)果是選手2獲勝,class名為title的元素,最終的color值為gold

css里就像這樣,隨時可能一言不和就發(fā)生戰(zhàn)爭,結(jié)果輸?shù)舻囊环骄蜁粍倮囊环剿采w。“層疊”一詞可以說形象地描述了這個過程。

那么,為什么會有這樣的層疊(zhàn zhēng )呢?

css的作用域問題

在javascript里,可以做到這樣的搭配:

var title = "silver";

(function(){
    var title = "gold";
    console.log(title); // gold
}());

console.log(title); // silver

利用javascript的函數(shù)作用域,兩位同樣名為title的選手可以友好相處。

但回到css里的樣式規(guī)則,情況就完全不是這么回事了。

css不是程序語言,但如果說要給它加一個作用域的概念的話,那就是:只有全局作用域。

無論分拆為多少個css文件,無論用怎樣的方式引入,所有的樣式規(guī)則都位于同一作用域,只要選擇符近似,就有發(fā)生覆蓋的可能

減少相互影響的策略

為減少相互影響,避免預料之外的樣式覆蓋,我們一直以來想過很多辦法。

比如你接手一個別人留下來的舊項目,接下來要新增一個標題元素的時候,你會有意識地不去使用.title這樣模糊的class名,因為它太容易重名了。最終,你用的名稱可能是:

.module-sp-title {
    color: deepskyblue;
}

即使你決定要用.title這個名字,你也會加上包含選擇符作為限定:

.module-1 .title { 
    font-size: 18px;
}
/* ... */
.module-2 .title {
    font-size: 14px;
}

其中.module-1.module-2的名字應(yīng)該是唯一的,這樣的代碼在組件化(模塊化)的開發(fā)風格里很常見。

此外,一些有名的css理論,如SMACSS,會建議你為所有布局樣式使用l-layout-的前綴,以示區(qū)分。

類似的做法還有很多,但歸結(jié)起來,都是在嘗試提供一種合理的命名約定。而合理的命名約定,的確是組織css代碼的有效策略。

現(xiàn)在,我們有了新的可用策略,CSS Modules就是其中之一。

技術(shù)流的模塊化

CSS Modules是一種技術(shù)流的組織css代碼的策略,它將為css提供默認的局部作用域。

CSS Modules是如何做到的呢?來看一個CSS Modules的簡單例子吧。

有這樣的一個html元素:

a title for CSS Modules

按照普通css的寫法,我們可以這樣為它添加樣式:

.title {
    background-color: snow;
}

現(xiàn)在我們改用CSS Modules。首先,css保持不變。然后,修改html的寫法。不再這樣直接寫html,而是改為在javascript文件里動態(tài)添加,這樣做(css文件名為main.css):

var styles = require("./main.css");

var el = document.getElementById("example_title");
el.outerHTML = "

a title for CSS Modules

";

咦,require了一個css文件?對的,所以要用到webpack。編譯后,html和css會變成這樣:

看到這樣不太美觀的class名你大概就明白了,CSS Modules無法改變css全局作用域的本性,它是依靠動態(tài)生成class名這一手段,來實現(xiàn)局部作用域的。顯然,這樣的class名就可以是唯一的,不管原本的css代碼寫得有多隨便,都可以這樣轉(zhuǎn)換得到不沖突的css代碼。

模擬的局部作用域也沒有關(guān)系,它是可靠的。

這個CSS Modules的例子說完了,但你一定跟我最初看到的時候一樣有很多問題。

CSS Modules的應(yīng)用細節(jié) 如何啟用CSS Modules

“webpack編譯css我也用過,怎么我用的時候不長這樣?”

一般來說,require一個css文件的寫法是:

require("./main.css");

但在前面的例子中,用了var styles = require("./main.css");的寫法。這就好像是在說,我要這個css文件里的樣式是局部的,然后我根據(jù)需要自行取用。

在項目里應(yīng)用CSS Modules有很多方法,目前比較常用的是使用webpack的css-loader。在webpack配置文件里寫css-loader?modules就可以開啟CSS Modules,例如前面的例子所用的:

module: {
    loaders: [{
        test: /.css$/,
        loader: "style!css?modules"
    }]
}

才發(fā)現(xiàn)一直用著的css-loader原來有這功能?其實,CSS Modules確實是一個后來才并入css-loader的新功能。

自定義生成的class名

“名字都這樣了,還怎么調(diào)試?”

為css-loader增加localIdentName參數(shù),是可以指定生成的名字。localIdentName的默認值是[hash:base64],一般開發(fā)環(huán)境建議用類似這樣的配置:

{
    test: /.css$/,
    loader: "style!css?modules&localIdentName=[name]__[local]___[hash:base64:5]"
}

同樣應(yīng)用到前面的例子里,這時候就會變成這樣的結(jié)果:

這樣是不是要有意義多了?

如果是線上環(huán)境,可以考慮用更短的名字進一步減小css文件大小。

CSS Modules下的html

(看了前面例子里的el.outerHTML = ...后)

“什么,outerHTML?class名還要拼接?你家html才這么寫呢!”

很遺憾,CSS Modules官方的例子,也是這個意思:要使用CSS Modules,必須想辦法把變量風格的class名注入到html中。也就是說,html模板系統(tǒng)是必需的,也正是如此,相比普通css的情況,CSS Modules的html寫起來要更為費勁。

如果你搜一下CSS Modules的demo,可以發(fā)現(xiàn)大部分都是基于React的。顯然,虛擬DOM風格的React,搭配CSS Modules會很容易(ES6):

import styles from "./ScopedSelectors.css";

import React, { Component } from "react";

export default class ScopedSelectors extends Component {

  render() {
    return (
      

Scoped Selectors

); } };

如果不使用React,還是那句話,只要有辦法把變量風格的class名注入到html中,就可以用CSS Modules。原始的字符串拼接的寫法顯然很糟糕,但我們可以借助各種模板引擎和編譯工具做一些改進。下面請看一個用Jade的參考示例。

想象一下你有一個用普通css的頁面,但你想在一小塊區(qū)域使用CSS Modules。這一塊區(qū)域在一個容器元素里:

然后用jade來寫html(關(guān)聯(lián)的css文件為module_sp.css):

- styles = require("./module_sp.css");
h2(class=styles.title) a title for CSS Modules

接下來,仍然是在javascript里添加這段jade生成的html:

var el = document.getElementById("module_sp_container");
var template = require("./main.jade");
el.innerHTML = template();

最后,記得在css-loader啟用CSS Modules的同時,增加jade-loader:

{
    test: /.jade$/,
    loader: "jade"
}

編譯運行,就可以得到想要的結(jié)果。除Jade以外,還有些其他CSS Modules的html應(yīng)用方案,推薦參考github上的這篇issue。

目前CSS Modules還在發(fā)展中,而且也在考慮改進CSS Modules下的html寫作體驗。CSS Modules團隊成員有提到一個叫CSS Modules Injector的未來規(guī)劃項目,目的是讓開發(fā)者不用javascript也可以使用CSS Modules(這就很接近原生html + css的組合了)。

CSS Modules下的樣式復用

“樣式都是唯一的了,怎么復用?”

我們已經(jīng)說了挺多普通css單個全局作用域的壞處。但對應(yīng)的,這也有一個很大的好處,就是便于實現(xiàn)樣式的復用。css理論OOCSS也是在追求這一點。

CSS Modules提供一個composes方法用于樣式復用。例如,你有一個btn.css里有一條:

.btn{
    display: inline-block;
}

然后,你在另一個CSS Module的module_sp.css里可以這樣引入它:

.btn-sp{
    composes: btn from "./btn.css";
    font-size: 16px;
}

那么,這個div.btn-sp的DOM元素將會是:

可以看到,composes的用法比較類似sass的@extend,但不同于@extend的是,composes并不增加css里的選擇符總量,而是采用組合多個class名的形式。在這個例子里,原本僅有1個class的div.btn-sp,變成了2個class。

因此,CSS Modules建議只使用1個class就定義好對應(yīng)元素所需的全部樣式。它們會再由CSS Modules轉(zhuǎn)換為適當?shù)腸lass組合。

CSS Modules團隊成員認為composes是CSS Modules里最強大的功能:

For me, the most powerful idea in CSS Modules is composition, where you can deconstruct your visual inventory into atomic classes, and assemble them at a module level, without duplicating markup or hindering performance.

更詳細的composes的用法及其理解,推薦閱讀CSS Modules: Welcome to the Future。

其他可能有用的補充 和已有的普通css共存

很多項目會引入Bootstrap、Materialize等框架,它們是普通的、全局的css。此外,你也可能自己會寫一些普通css。如何共存呢?CSS Modules團隊成員對此提到過:

a CSS Module should only import information relative to it

意思是,建議把CSS Modules看做一種新的css,和原來的普通css區(qū)分開來。比如,composes的時候,不要從那些普通的css里去取。

在css-loader里通過指定testincludeexclude來區(qū)分它們。保持CSS Modules的純凈,只有想要應(yīng)用CSS Modules的css文件,才啟用CSS Modules。

只轉(zhuǎn)換class和id

經(jīng)過我自己的測試,CSS Modules只轉(zhuǎn)換class和id,此外的標簽選擇符、偽類等都不會被轉(zhuǎn)換。

建議只使用class。

一個CSS Module的輸出

簡單用console.log()就可以查看CSS Module的輸出:

var styles = require("./main.css");
console.log("styles = ", styles);

結(jié)果類似這樣:

{
    "btn-sp":  "_2SCQ7Kuv31NIIiVU-Q2ubA _2r6eZFEKnJgc7GLy11yRmV",
    title: "_1m-KkPQynpIso3ofWhMVuK"
}

這可以幫助理解CSS Modules是怎樣工作的。

預編譯器

sass等預編譯器也可以用CSS Modules,對應(yīng)的loader可能是這樣:

{
    test: /.scss$/,
    loader: "style!css?modules!resolve-url!sass?sourceMap"
}

注意不要因為是sass就習慣性地用嵌套寫法,CSS Modules并不適合使用包含選擇符。

建議的命名方式

CSS Modules會把.title轉(zhuǎn)換為styles.title,由于后者是用在javascript中,因此駝峰命名會更適合。

如果像我之前那樣寫.btn-sp,需要注意在javascript中寫為styles["btn-sp"]

此外,你還可以為css-loader增加camelCase參數(shù)來實現(xiàn)自動轉(zhuǎn)換:

{
    test: /.css$/,
    loader: "style!css?modules&camelCase",
}

這樣即便你寫.btn-sp,你也可以直接在javascript里用styles.btnSp

結(jié)語

無論是一直以來我們認真遵循的命名約定,還是這個新的CSS Modules,目的都是一樣的:可維護的css代碼。我覺得就CSS Modules基本還是在寫css這一點來說,它還是很友好的。

雖然本文為了嚴謹,結(jié)果寫了相當長的篇幅,但希望你讀過之后,還能覺得CSS Modules是簡單易懂的。因為這樣,我就達成我的目的:扣題,了。

(重新編輯自我的博客,原文地址:http://acgtofe.com/posts/2016/04/css-modules-made-simple)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/115206.html

相關(guān)文章

  • 前端基礎(chǔ)進階(十五):詳解 ES6 Modules

    摘要:下載地址安裝一個好用的命令行工具在環(huán)境下,系統(tǒng)默認的非常難用,所以我個人比較推薦大家使用或者。下載地址安裝在命令行工具中使用查看版本的方式確保與都安裝好之后,我們就可以安裝了。前端基礎(chǔ)進階系列目錄 showImg(https://segmentfault.com/img/remote/1460000009654403?w=1240&h=272); 對于新人朋友來說,想要自己去搞定一個E...

    Lowky 評論0 收藏0
  • 使用Vue構(gòu)建中(大)型應(yīng)用

    摘要:做前端路由管理,一個中大型項目必須要做路由管理做數(shù)據(jù)管理,類似于的存在,沒有,中大型應(yīng)用中的狀態(tài)會把開發(fā)者搞死,絕對。 想做SPA就快上車! init 首先要起一個項目,推薦用vue-cli安裝 $ npm install -g vue-cli $ vue init webpack demo $ cd demo $ npm install demo是這個示例項目的名字 現(xiàn)在看到目錄結(jié)構(gòu)...

    Rindia 評論0 收藏0
  • 使用 webpack 4 和 Babel 7 構(gòu)建 React 應(yīng)用及如何引入 Material D

    摘要:建立項目首先,創(chuàng)建工程目錄現(xiàn)在我們已經(jīng)創(chuàng)建了我們要開發(fā)應(yīng)用程序的文件夾,接著需要添加一個文件。這里為了版本的一致性,我把里的版本號前面刪除了。為此,需要創(chuàng)建一個名為的文件,用來配置。 showImg(https://segmentfault.com/img/bVboiHi?w=1000&h=625); 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! 在過去的一年和...

    asoren 評論0 收藏0
  • 開發(fā)工具心得:如何 10 倍提高你 Webpack 構(gòu)建效率

    摘要:在項目架構(gòu)中這兩個東西基本成為了標配,但的模塊必須在使用前經(jīng)過的構(gòu)建后文稱為才能在瀏覽器端使用,而每次修改也都需要重新構(gòu)建后文稱為才能生效,如何提高的構(gòu)建效率成為了提高開發(fā)效率的關(guān)鍵之一。 0. 前言 showImg(https://segmentfault.com/img/remote/1460000005770045); 圖1:ES6 + Webpack + React + Bab...

    用戶83 評論0 收藏0
  • 前端模塊化詳解(完整版)

    摘要:二模塊化規(guī)范概述應(yīng)用由模塊組成,采用模塊規(guī)范。模塊化語法命令用于規(guī)定模塊的對外接口,命令用于輸入其他模塊提供的功能。 前言 在JavaScript發(fā)展初期就是為了實現(xiàn)簡單的頁面交互邏輯,寥寥數(shù)語即可;如今CPU、瀏覽器性能得到了極大的提升,很多頁面邏輯遷移到了客戶端(表單驗證等),隨著web2.0時代的到來,Ajax技術(shù)得到廣泛應(yīng)用,jQuery等前端庫層出不窮,前端代碼日益膨脹,此時...

    Sanchi 評論0 收藏0

發(fā)表評論

0條評論

chunquedong

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<