原文地址:https://css-tricks.com/css-mo...
最近我对CSS Modules比较好奇。若是你曾经据说过他们,那么这篇博客正适合你。咱们将去探索它的目的和主旨。若是你一样很好奇,敬请关注,在下一篇博文中咱们将介绍如何使用CSS Modules。若是你想亲自尝试而且掌握如何使用,第三部分将会很适合你,这一部分剖析了如何在React环境中使用。css
根据官方的repository介绍,CSS Modules是:webpack
全部的class的名称和动画的名称默认属于本地做用域的CSS文件。
因此CSS Modules不是一个官方的规范,也不是浏览器的一种机制,它是一种构建步骤中的一个进程。(构建一般须要webpack或者browserify的帮助)。经过构建工具的帮助,能够将class的名字或者选择器的名字做用域化。(相似命名空间化。)
这究竟是什么呢?咱们为何要这么作呢?咱们很快就进行介绍。首先,不要忘记HTML和CSS的工做原理。在HTML中一个类添加:web
<h1 class="title">An example heading</h1>
在CSS中这个class的定义以下:浏览器
.title { background-color: red; }
只要CSS被添加到HTML文档上,那个<h1>
的背景色就是红色。咱们不须要人为处理CSS和HTML文件。浏览器自己本身就理解这些文件的格式。dom
CSS Modules 和上面的方法不同。咱们不写纯HTML,咱们须要在一个相似index.js这样的Javascript 文件中取写咱们全部的标签。这里有一个例子来讲明这是怎么回事(咱们以后将会去看更多真实的实例):工具
import styles from "./styles.css"; element.innerHTML = `<h1 class="${styles.title}"> An example heading </h1>`;
在咱们构建的步骤中,编译器将会搜索咱们导入的styles.css文件,而后到咱们刚刚写的js文件中,经过styles.title
使得.title class可用。咱们的构建步骤将会同时处理这些东西成为新的,分离的HTML和CSS文件,而且用一个新的字符串去替换HTML和CSS选择器的class。学习
经过构建工具生成的HTML也许像下面这样:动画
<h1 class="_styles__title_309571057"> An example heading </h1>
经过构建工具生成的CSS也许像下面这样:spa
._styles__title_309571057{ background-color: red; }
class属性和.title选择器已经彻底不见了,取而代之的是这个全新的字符串;咱们的源CSS文件也没有为浏览器提供服务。
就像Hugo Griaudel在他的这一模块的教程中所说:设计
[the classes]是动态生成的,惟一的,并且和当前的样式有映射关系的。
这就是样式也有做用域的缘由。它们的做用域是特定的模板。若是咱们有一个buttons.css文件咱们将在buttons.js模板中导入它,而且在css文件内的.btn class相对于其余模板(例如forms.js)也是不可用的,除非咱们在这个文件中一样导入了进来。
为何咱们想要把CSS和HTML搞成这样?咱们这样作的真真正正的缘由是什么?
有了CSS Modules,就能够确保全部的样式可以服务于单个组件:
除此以外,任何组件都能拥有真正的依赖,就像下面这样:
import buttons from "./buttons.css"; import padding from "./padding.css"; element.innerHTML = `<div class="${buttons.red}${padding.large}">`;
这样设计的目的在于解决CSS中的全局做用域问题。
你曾有过为了提高效率,节省时间去简略的写css吗?并且是在彻底不考虑你会不会影响其余代码的状况下?
你曾有过在样式表的底部随机打了一些的比特和垃圾,而后尝试回过头来从新去组织可是历来没这么作吗?
你曾有过看到样式却不彻底知道它的意义的时候吗?即便它们被用在了当前的标签上?
你曾有过思考如何去不破坏任何东西的状况下,去弃用一些现有的样式吗?考虑过这些样式是仅仅做用于本身仍是依赖其它样式呢?或者是在哪里从新覆盖了样式了?
这些问题会让人很头痛,项目时间紧张,而你的心思又在窗外的花花世界。
可是当你有了CSS Modules以后,关键是这种默认本地做用域的概念,这个问题将会被避免。你必须去思考写样式的方便性。
例如,若是你在不该用CSS module-style class去作转换的状况下,在HTML中使用random-gross-class,这个样式将不会被应用,由于这个选择器将会被转换为._style_random-gross-class_0038089.
咱们如今拥有一个叫作type.css的模块去渲染text样式。在那个文件中,咱们也许会有以下代码:
.serif-font { font-family: Georgia,serif; } .display { composes: serif-font; font-size: 30px; line-height: 35px; }
咱们将在咱们的模板中声明class:
import type from "./type.css"; element.innerHTML = ` <h1 class="${type.display}"> This is a heading </h1>; `
编译后的模板上的标签会是下面这样:
<h1 class="_type__display_0980340 _type_serif_404840"> Heading title </h1>
使用composes关键词汇将2个class都绑定到元素上,从而避免了相似解决方案的一些问题,相似Sass中的@extend。
咱们甚至能够在一个分离的CSS文件中去compose。
.element{ compose: dark-red from "./colors.css"; font-size: 30px; line-height: 1.2; }
在构建CSS module的过程当中,不须要BEM。有2个缘由:
很酷,难道不是吗?
这些仅仅是CSS Modules的部分优势。
若是你想学习更多,Glen Madden写了更多的这样作的好处。
这个系列的下一篇文章将会去探索如何在项目中使用Webpack和CSS Modules。咱们将使用最新的ES2015的特性去实现,也会给出一些代码例子去引导你们去理解。