CSS Modules 详解


当前第2页 返回上一页

如果你搜一下CSS Modules的demo,可以发现大部分都是基于React的。显然,虚拟DOM风格的React,搭配CSS Modules会很容易(ES6):


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

import styles from './ScopedSelectors.css';

 

import React, { Component } from 'react';

 

export default class ScopedSelectors extends Component {

 

 render() {

 return (

  <p className={ styles.root }>

  <p className={ styles.text }>Scoped Selectors</p>

  </p>

 );

 }

 

};

如果不使用React,还是那句话,只要有办法把变量风格的class名注入到html中,就可以用CSS Modules。原始的字符串拼接的写法显然很糟糕,但我们可以借助各种模板引擎和编译工具做一些改进。下面请看一个用Jade的参考示例。

想象一下你有一个用普通css的页面,但你想在一小块区域使用CSS Modules。这一块区域在一个容器元素里:


1

<p id="module_sp_container"></p>

后用jade来写html(关联的css文件为module_sp.css):


1

2

- styles = require("./module_sp.css");

h2(class=styles.title) a title for CSS Modules

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


1

2

3

var el = document.getElementById("module_sp_container");

var template = require("./main.jade");

el.innerHTML = template();

最后,记得在css-loader启用CSS Modules的同时,增加jade-loader:


1

2

3

4

{

 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里有一条:


1

2

3

.btn{

 display: inline-block;

}

然后,你在另一个CSS Module的module_sp.css里可以这样引入它:


1

2

3

4

.btn-sp{

 composes: btn from "./btn.css";

 font-size: 16px;

}

那么,这个p.btn-sp的DOM元素将会是:

可以看到,composes的用法比较类似sass的@extend,但不同于@extend的是,composes并不增加css里的选择符总量,而是采用组合多个class名的形式。在这个例子里,原本仅有1个class的p.btn-sp,变成了2个class。

因此,CSS Modules建议只使用1个class就定义好对应元素所需的全部样式。它们会再由CSS Modules转换为适当的class组合。

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区分开来。比如,composes的时候,不要从那些普通的css里去取。

在css-loader里通过指定test、include、exclude来区分它们。保持CSS Modules的纯净,只有想要应用CSS Modules的css文件,才启用CSS Modules。

只转换class和id

经过我自己的测试,CSS Modules只转换class和id,此外的标签选择符、伪类等都不会被转换。

建议只使用class。

一个CSS Module的输出

简单用console.log()就可以查看CSS Module的输出:


1

2

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

console.log("styles = ", styles);

结果类似这样:


1

2

3

4

{

 "btn-sp": "_2SCQ7Kuv31NIIiVU-Q2ubA _2r6eZFEKnJgc7GLy11yRmV",

 title: "_1m-KkPQynpIso3ofWhMVuK"

}

这可以帮助理解CSS Modules是怎样工作的。

预编译器

sass等预编译器也可以用CSS Modules,对应的loader可能是这样:


1

2

3

4

{

 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参数来实现自动转换:


1

2

3

4

{

 test: /\.css$/,

 loader: 'style!css?modules&camelCase',

}

这样即便你写.btn-sp,你也可以直接在javascript里用styles.btnSp。

结语

无论是一直以来我们认真遵循的命名约定,还是这个新的CSS Modules,目的都是一样的:可维护的css代码。我觉得就CSS Modules基本还是在写css这一点来说,它还是很友好的。

虽然本文为了严谨,结果写了相当长的篇幅,但希望你读过之后,还能觉得CSS Modules是简单易懂的。因为这样,我就达成我的目的:扣题,了。

推荐教程:《PHP》


以上就是CSS Modules 详解的详细内容,更多文章请关注木庄网络博客

返回前面的内容

相关阅读 >>

css怎么改字体粗细

css超链接的底色如何设置

css modules是什么

最受欢迎的10大css框架

怎样让前端界面自动清理js、css文件的缓存

css怎么设置最小宽度

css line-height值为150%或1.5值的区别

css注释方式是什么

css如何设置banner图自适应

如何利用css改变浏览器滚动条样式

更多相关阅读请进入《css》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...