CSS模块化遇到了哪些问题?
* 全局污染
* 命名混乱
* 依赖引入复杂
* 无法共享变量
* 代码冗余
CSS Modules模块化方案
CSS Modules能最大化地结合现有CSS生态和JavsScript模块化能力,其API非常简洁,学习成本几乎为零。
CSS Modules实现以下几点
* 所有样式都是局部化,解决了命名冲突和全局污染的问题
* class名的生成规则配置灵活,可以以此来压缩 class 名
* 只需引用组件的 JavsScript,就能搞定组件所有的 JavsScript 和 CSS
具体先看以下实例:
importReactfrom'react';
importstylefrom'./App.module.css';
exportdefault () => {
return (
<h1className={style.title}>
Hello World
</h1>
);
};
App.css
.title {
color: red;
}
构建结果会将类名style.title编译成一个哈希字符串。
<h1class="_3zyde4l1yATCOkgn-DBWEL">
Hello World
</h1>
._3zyde4l1yATCOkgn-DBWEL {
color: red;
}
CSS Modules使用特点
+ 不使用选择器,只使用 class 名来定义样式
+ 不层叠多个 class,只使用一个 class 把所有样式定义好
+ 不嵌套class
+ 所有样式通过 composes 组合来实现复用
CSS Modules 语法
作用域
CSS的规则都是全局的,任何一个组件的样式规则,都对整个页面有效。
产生局部作用域的唯一方法,就是使用一个独一无二的class的名字,不会与其他选择器重名。这就是 CSS Modules 的做法。
CSS Modules 默认样式为局部作用域,还提供一种显式的局部作用域语法:local(.className),等同于.className。
如果需要定义一个全局作用域样式时,允许使用:global(.className)的语法,声明一个全局规则。凡是这样声明的class,都不会被编译成哈希字符串。
:local(.title) {
color: red;
}
:global(.title) {
color: green;
}
Class 的组合
compose组合class样式复用,在 CSS Modules 中,一个选择器可以继承另一个选择器的规则, 自身引入的声明的优先级会比较高。
注意:只有局部作用域规则才可以使用composes进行组合
/* 同一个css文件中复用类*/
.bg {
background-color:blue;
}
.title {
composes:bg;
color:white;
}
/* 不同css文件中复用类*/
.title {
composes: blue from './color.css';
border-bottom: 1pxsolid #ccc;
padding-bottom: 20px;
}
/* 全局样式利用*/
.title {
composes: text-blue from global;
border-bottom: 1pxsolid #ccc;
padding-bottom: 20px;
}
这个与预处理器的 @extends
语法很相似,我们用Sass来做实例比较:
.Button-common { /\* font-sizes, padding, border-radius \*/ }
.Button-normal {
@extends .Button--common;
color: blue;
}
.Button-error {
@extends .Button--common;
color: red;
}
编译成css后:
.Button-common, .Button-normal, .Button-error {
/* font-sizes, padding, border-radius */
}
.Button-normal {
color:blue;
}
.Button-error {
color:red;
}
然后,我们在HTML标签中使用一个样式名 <button class=“button--error”>
, 即可获得所需的通用和特定样式。
再来看看CSS Modules的处理方式
.common { /* font-sizes, padding, border-radius */ }
.normal {
composes: common;
color:blue;
}
.error {
composes: common;
color:red;
}
在浏览器上,最终会编译成这样(样式名称规则通过构建工具加载器配置):
.submit_button__common__abc5436 { /* font-sizes, padding, border-radius */ }
.submit_button_normal__def6547 {
color:blue;
}
.submit_button__error__1638bcd {
color:red;
}
在js中使用 import styles from "./submit-button.css"
返回的对象可以看到最终是记录了多个样式名。
styles: {
common: "submit_button_common__abc5436",
normal: "submit_button_common_abc5436 submit_button_normal__def6547",
error: "submit_button_common_abc5436 submit_button_error__1638bcd"
}
这是composes的强大功能,您可以组合多个独立的样式组,而无需更改标记或重写CSS选择器。
嵌套
CSS Modules 允许嵌套定义,但并不推荐这样做。
.title-bar {
height: 48px
}
.title-bar>ul {
text-align: center
}
.titel-bar:global(.cell) {
padding-left:10px
}
和预处理器配合使用
通过构建工具的配置,可以和各种CSS预处理器一起使用,如stylus
@import"~@/assets/css/vendor"
.logo
width: 200px
text-align: center
&:hover
background: $bg /* vendor中定义的变量 */
.round {
display: inline-block
width: 30px
height: @width
line-height: @width
border-radius: 50%
composes: bg-main from global;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。