CSSModules详解
.title { color: silver; }
然后又在后边写了一条相似的(选手2):
.title { color: gold; }
由于名字雷同,选手2就会和选手1打起来(让你丫假冒我!)。效果是选手2得胜,class名为title的元素,终究的color值为gold。
css里就像这样,随时可能一言反面就产生战役,效果输掉的一方就会被胜利的一方所遮盖。“层叠”一词可以说形象地描述了这个历程。
那么,为何会有这样的层叠(zhàn zhēng )呢?
css的作用域题目
在javascript里,可以做到这样的搭配:
var title = "silver"; (function(){ var title = "gold"; console.log(title); // gold }()); console.log(title); // silver
应用javascript的函数作用域,两位一样名为title的选手可以友爱相处。
但回到css里的样式法则,状况就完全不是这么回事了。
css不是程序说话,但要是说要给它加一个作用域的概念的话,那就是:只要全局作用域。
不管分拆为多少个css文件,不管用如何的方式引入,所有的样式法则都位于统一作用域,只有选中符近似,就有产生遮盖的可能。
减少彼此影响的战略
为减少彼此影响,以免预料以外的样式遮盖,我们不断以来想过许多方法。
比方你接手一一般人留下来的旧项目,接下来要新增一个标题元素的时候,你会成心识地不去运用.title这样依稀的class名,由于它太容易重名了。终究,你用的名称可能是:
.module-sp-title { color: deepskyblue; }
即便你决议要用.title这个名字,你也会加上包括选中符作为限制:
.module-1 .title { font-size: 18px; } /* ... */ .module-2 .title { font-size: 14px; }
其中.module-1和.module-2的名字应当是独一的,这样的代码在组件化(模块化)的开发格调里很常见。
此外,一些有名的css理论,如SMACSS,会倡议你为所有布局样式运用l-或layout-的前缀,以示区分。
相似的做法还有许多,但归结起来,都是在尝试供给一种合理的命名约定。而合理的命名约定,确实是组织css代码的有效战略。
此刻,我们有了新的可用战略,CSS Modules就是其中之一。
技术流的模块化
CSS Modules是一种技术流的组织css代码的战略,它将为css供给默许的部分作用域。
CSS Modules是怎样做到的呢?来看一个CSS Modules的简略例子吧。
有这样的一个html元素:
a title for CSS Modules
按照普通css的写法,我们可以这样为它增加样式:
.title { background-color: snow; }
此刻我们改用CSS Modules。第一,css维持不变。然后,修改html的写法。不再这样直接写html,而是改为在javascript文件里动态增加,这样做(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会酿成这样:
module: { loaders: [{ test: /\.css$/, loader: 'style!css?modules' }] }
才发明不断用着的css-loader本来有这功能?其实,CSS Modules的确是一个后来才并入css-loader的新功能。
自定义生成的class名
“
名字都这样了,还怎么调试?”
为css-loader添加localIdentName参数,是可以指定生成的名字。localIdentName的默许值是[hash:base64],个别开发环境倡议用相似这样的配置:
{ test: /\.css$/, loader: 'style!css?modules&localIdentName=[name]__[local]___[hash:base64:5]' }
一样利用到前面的例子里,这时候就会酿成这样的效果:
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的页面,但你想在一小块区域运用CSS Modules。这一块区域在一个容器元素里:
后用jade来写html(关联的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' }
编译运转,就可以得到想要的效果。除Jade之外,还有些其他CSS Modules的html利用方案,举荐参照 github上的这篇issue。
当前CSS Modules还在开展中,并且也在考虑改善CSS Modules下的html写作体验。CSS Modules团队成员有提到一个叫CSS Modules Injector的将来计划项目,目的是让开发者不消javascript也可以运用CSS Modules(这就很接近原生html + css的组合了)。
CSS Modules下的样式复用
“样式都是独一的了,怎么复用?”
我们已经说了挺多普通css单个全局作用域的害处。但对应的,这也有一个很大的益处,就是便于实现样式的复用。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; }
那么,这个p.btn-sp的DOM元素将会是:
var styles = require("./main.css"); console.log("styles = ", styles);
效果相似这样:
{ "btn-sp": "_2SCQ7Kuv31NIIiVU-Q2ubA _2r6eZFEKnJgc7GLy11yRmV", title: "_1m-KkPQynpIso3ofWhMVuK" }
这可以帮忙了解CSS Modules是如何工作的。
预编译器
sass等预编译器也可以用CSS Modules,对应的loader可能是这样:
{ test: /\.scss$/, loader: 'style!css?modules!resolve-url!sass?sourceMap' }
注意不要由于是sass就习惯性地用嵌套写法,CSS Modules并不适合运用包括选中符。
倡议的命名方式
CSS Modules会把.title转换为styles.title,因为后者是用在javascript中,因而驼峰命名会更适合。
要是像我以前那样写.btn-sp,需要注意在javascript中写为styles["btn-sp"]。
此外,你还可认为css-loader添加camelCase参数来实现主动转换:
{ test: /\.css$/, loader: 'style!css?modules&camelCase', }
这样即使你写.btn-sp,你也可以直接在javascript里用styles.btnSp。
结语
不管是不断以来我们认真遵循的命名约定,还是这个新的CSS Modules,目的都是同样的:可保护的css代码。我觉得就CSS Modules根本还是在写css这一点来说,它还是很友爱的。
虽然本文为了严谨,效果写了相当长的篇幅,但但愿你读过之后,还能觉得CSS Modules是简略易懂的。由于这样,我就达成我的目的:扣题,了。
举荐教程:《PHP》
以上就是CSS Modules 详解的细致内容,更多请关注 百分百源码网 其它相干文章!