日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

簡(jiǎn)單明了帶你了解CSS Modules

瀏覽:304日期:2022-06-02 17:47:54

層疊樣式表

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

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

.title { color: silver;}

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

.title { color: gold;}

因?yàn)槊窒嗤x手2就會(huì)和選手1打起來(讓你丫冒充我!)。結(jié)果是選手2獲勝,class名為title的元素,最終的color值為gold。

css里就像這樣,隨時(shí)可能一言不和就發(fā)生戰(zhàn)爭(zhēng),結(jié)果輸?shù)舻囊环骄蜁?huì)被勝利的一方所覆蓋。“層疊”一詞可以說形象地描述了這個(gè)過程。

那么,為什么會(huì)有這樣的層疊(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不是程序語言,但如果說要給它加一個(gè)作用域的概念的話,那就是:只有全局作用域。

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

減少相互影響的策略

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

比如你接手一個(gè)別人留下來的舊項(xiàng)目,接下來要新增一個(gè)標(biāo)題元素的時(shí)候,你會(huì)有意識(shí)地不去使用.title這樣模糊的class名,因?yàn)樗菀字孛恕W罱K,你用的名稱可能是:

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

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

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

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

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

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

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

技術(shù)流的模塊化

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

CSS Modules是如何做到的呢?來看一個(gè)CSS Modules的簡(jiǎn)單例子吧。

有這樣的一個(gè)html元素:

<h2 id="example_title">a title for CSS Modules</h2>


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

.title { background-color: snow;}

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

var styles = require("./main.css");var el = document.getElementById("example_title");el.outerHTML = "<h2>a title for CSS Modules</h2>";

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

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

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

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

CSS Modules的應(yīng)用細(xì)節(jié)

如何啟用CSS Modules

“webpack編譯css我也用過,怎么我用的時(shí)候不長(zhǎng)這樣?”

一般來說,require一個(gè)css文件的寫法是:

require("./main.css");

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

在項(xiàng)目里應(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原來有這功能?其實(shí),CSS Modules確實(shí)是一個(gè)后來才并入css-loader的新功能。

自定義生成的class名

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

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

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

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

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

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

CSS Modules下的html

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

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

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

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

import styles from "./ScopedSelectors.css";import React, { Component } from "react";export default class ScopedSelectors extends Component { render() { return (  <div className={ styles.root }>  <p className={ styles.text }>Scoped Selectors</p>  </div> ); }};

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

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

<div id="module_sp_container"></div>

后用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的同時(shí),增加jade-loader:

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


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

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

CSS Modules下的樣式復(fù)用

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

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

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

.btn{ display: inline-block;}

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

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

那么,這個(gè)div.btn-sp的DOM元素將會(huì)是:

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

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

CSS Modules團(tuán)隊(duì)成員認(rèn)為composes是CSS Modules里最強(qiáng)大的功能:

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.

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

其他可能有用的補(bǔ)充

和已有的普通css共存

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

a CSS Module should only import information relative to it

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

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

只轉(zhuǎn)換class和id

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

建議只使用class。

一個(gè)CSS Module的輸出

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

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

結(jié)果類似這樣:

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


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

預(yù)編譯器

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

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

注意不要因?yàn)槭莝ass就習(xí)慣性地用嵌套寫法,CSS Modules并不適合使用包含選擇符。

建議的命名方式

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

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

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

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

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

結(jié)語

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

雖然本文為了嚴(yán)謹(jǐn),結(jié)果寫了相當(dāng)長(zhǎng)的篇幅,但希望你讀過之后,還能覺得CSS Modules是簡(jiǎn)單易懂的。因?yàn)檫@樣,我就達(dá)成我的目的:扣題,了。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持。

標(biāo)簽: CSS HTML
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产成人精选| 亚洲国产欧美日本视频| 亚洲人成亚洲精品| 国产精品日本一区二区三区在线| 欧美激情另类| 中文字幕一区二区三区日韩精品 | 一区在线观看| 久久久久久久欧美精品| 91av亚洲| 精品国产aⅴ| 青草国产精品| 国产精品美女久久久浪潮软件| 丁香婷婷久久| 日韩欧美另类一区二区| 国产精品嫩模av在线| 中文字幕亚洲在线观看| 最新亚洲一区| 久久伦理在线| 久久的色偷偷| 97se亚洲| 日韩国产欧美视频| 亚洲性视频在线| 午夜亚洲精品| 亚洲少妇一区| 麻豆精品网站| 中文无码久久精品| 中文字幕亚洲在线观看| 日韩精品一卡二卡三卡四卡无卡| 欧美美女一区| 午夜久久免费观看| 欧美精品一二| 久久大逼视频| 亚洲乱码久久| 一区二区三区网站| 久久亚洲一区| 亚洲三级网址| 日韩国产91| 日本不卡一二三区黄网| 亚州av日韩av| 日本成人在线不卡视频| 日韩一区二区三区高清在线观看| 亚洲视频二区| 欧美一级网站| 国产福利一区二区精品秒拍 | 国产一级一区二区| 亚洲精品护士| 91成人在线网站| 国产精品永久| 国产 日韩 欧美 综合 一区| 亚洲精品88| 99久久99视频只有精品| 欧美a级片一区| 免费久久99精品国产自在现线| 日韩中文字幕一区二区三区| 一区免费在线| 亚洲免费观看高清完整版在线观| 国产精品v日韩精品v欧美精品网站| 一本综合精品| 伊人精品视频| 日韩欧美美女在线观看| 9久re热视频在线精品| 国产精品二区不卡| 91p九色成人| 一区视频在线| 亚洲成人三区| 激情久久久久久久| 国产精品天堂蜜av在线播放| 午夜久久久久| 图片区亚洲欧美小说区| 亚洲高清av| 欧美日韩国产免费观看 | 欧美三区四区| 99国产精品久久久久久久成人热| 欧美日韩国产传媒| 国产模特精品视频久久久久| 伊人久久亚洲影院| 欧美资源在线| 亚洲日本在线观看视频| 久久亚洲不卡| 亚洲午夜免费| 视频在线观看一区| 日韩黄色大片| 亚洲视频二区| 国产日韩专区| 亚洲欧美一区在线| 日韩中文在线播放| 国产在线观看www| 日韩一区亚洲二区| 国产v综合v| 久久午夜精品一区二区| 婷婷亚洲五月色综合| 日韩精品水蜜桃| 国产美女高潮在线| 日韩影院二区| 欧美成人午夜| 美女精品网站| 日韩成人午夜精品| 国产精品v亚洲精品v日韩精品| 国产精品丝袜在线播放| 精品午夜av| 五月激情久久| 在线成人动漫av| 中日韩男男gay无套| 日本一区二区三区视频在线看| 国产精品久久久一区二区| 成人高清一区| 亚洲成人日韩| 亚欧成人精品| 久久不见久久见国语| 日本一区二区高清不卡| 91精品国产91久久久久久黑人| 黄色日韩在线| 国产精品午夜一区二区三区| av资源中文在线天堂| 黄页网站一区| 国产欧美日韩亚洲一区二区三区| 色综合五月天| 久久国产精品亚洲77777| 91成人在线网站| 日本不良网站在线观看| 亚洲欧美日韩一区在线观看| 日韩和欧美的一区| 国产一二在线播放| 蜜臀久久99精品久久久久久9| 88久久精品| 色一区二区三区| 三级一区在线视频先锋| 麻豆一区二区三| 欧美日韩国产高清电影| 欧美中文高清| 久久国产小视频| 欧美在线精品一区| 日韩精品欧美激情一区二区| 日本不卡一区二区| 91精品一区二区三区综合| 亚洲狼人精品一区二区三区| 日韩成人免费| 日韩有吗在线观看| 久久精品亚洲人成影院| 色婷婷成人网| 国产精品亚洲一区二区三区在线观看| 国产一级久久| 国产精品99视频| 美国三级日本三级久久99| 欧美91在线|欧美| 亚洲免费网址| 六月婷婷一区| 色婷婷久久久| 国产精品久久久久久久久久久久久久久 | 亚洲1区在线观看| 高清久久精品| 91亚洲无吗| 狠狠久久婷婷| 色综合五月天| 91精品国产自产精品男人的天堂| 99久久精品网| 国产高清精品二区| 亚洲综合色婷婷在线观看| 涩涩av在线| 国产欧美一区二区精品久久久| 日韩精品不卡一区二区| 日韩高清不卡一区二区| 91精品高清| 欧美日韩国产v| 国产精品巨作av| 日韩在线黄色| 免费精品视频| 蜜桃视频欧美| 蜜臀久久精品| 国产精品777777在线播放 | 99精品在线| 精品一区91| 国产精品一级| 日本中文字幕不卡| 亚洲欧美日本国产专区一区| 日韩中文欧美| 亚洲天堂资源| 久久天堂影院| 国产精品videossex| 日韩高清电影免费| 亚洲精品一级| 亚洲涩涩av| 美女国产一区| 欧美日韩三区| 欧美精选一区二区三区| 日本精品影院| 涩涩av在线| 中文字幕在线看片| 高清一区二区三区av| 精品欠久久久中文字幕加勒比| 国产三级一区| 国产亚洲久久| 国产欧美一区二区精品久久久| 日本久久二区| 日韩av成人高清| 日韩av一区二| 日韩激情中文字幕| 亚洲欧洲国产精品一区| 丝袜a∨在线一区二区三区不卡| 99久久精品网站|