专栏名称: 众成翻译
翻译,求知的另一种表达
目录
相关文章推荐
内蒙古掌上12348  ·  关于《内蒙古自治区节约用水条例 ... ·  23 小时前  
审计芸  ·  短视频2024 | ... ·  昨天  
内蒙古教育发布  ·  新学期 “新” 引力!叮!校园生活重启键已启动~ ·  昨天  
内蒙古教育发布  ·  新学期 “新” 引力!叮!校园生活重启键已启动~ ·  昨天  
51好读  ›  专栏  ›  众成翻译

什么是CSS模块以及你为什么需要它们?| CSS-Tricks

众成翻译  · 掘金  ·  · 2018-06-13 07:34

正文

#什么是CSS模块以及你为什么需要它们?

我最近对CSS模块很好奇。如果你还没有听说过它们,这篇文章就是为你而写。我们将了解CSS模块以及它的目的是什么。如果你也感兴趣,请持续跟踪,下一篇文章将关于怎样使用CSS模块。如果你想进一步提高你的CSS模块使用技能,第三部分将关于在React环境中使用它们。

系列文章

Part 1:什么是CSS模块以及你为什么需要它们? (你现在就在这里!) Part 2:怎样开始用上CSS模块 Part 3: React + CSS Modules = ?

什么是CSS模块?

根据这篇 文章 ,CSS模块是:

CSS files in which all class names and animation names are scoped locally by default. CSS文件中的所有类名(class names) 和动画名(animation names) 的作用域都默认为当前作用域。

所以CSS模块不是浏览器中的 官方标准(official spec) 或者 实践(implementation) 而是一个(在 Webpack 或者 Browserify 的帮助下)改变类名和选择器的作用域到当前文件(类似于命名空间)的构建过程。

这看起来像什么以及为什么这样呢?我们将马上看到它。首先,记住通常情况下HTML和CSS是怎么工作的。一个类名应用到HTML中:

<h1 class="title">An example heading</h1>

在CSS中定义这个类:

.title { background-color: red; }

一旦这个CSS被应用到这个HTML文档中,应用这个类的 h1 的背景色将变为红色。我们不需要处理CSS或者HTML。浏览器明白这些文件的格式。

CSS模块采用了不同的方法。与写纯HTML不同,我们需要在一个JavaScript文件中,比如 index.js 写我们的标记。下面这个例子告诉我们它将怎样工作(稍后我们将采用一个更实际的例子):

import styles from  "./styles.css"; 
element.innerHTML = 
    `<h1 class="${styles.title}"> 
        An example heading 
    </h1>`;

在我们的构建过程中,编译程序将查看我们引入的 styles.css 文件,随后查看我们的JavaScript文件,将 .title 类通过 styles.title 应用。我们的构建过程接着将处理这些到一个新的、分离的HTML和CSS文件,用一个新的字符串替换HTML类属性(HTML Class )和CSS选择器类(CSS selector class)。

生成的HTML文件可能是这样:

<h1 class="_styles__title_309571057">
    An example heading 
</h1>

生成的CSS文件可能是这样:

._styles__title_309571057 { 
    background-color: red; 
}

img1

之前的类属性和选择器 .title 已经完全不存在了,取而代之的是一个全新的字符串。我们之前的CSS已经根本不提供给浏览器了。

正如 Hugo Giraudel said 在他关于这个主题的教程中提到的:

[the classes] are dynamically generated, unique, and mapped to the correct styles. [这些类]是动态生成的,是独一无二的,并映射到正确的样式。

这就是样式作用域的含义。他们的作用域是特定的模板。如果我们有一个 buttons.css 文件,它将只被我们引入到 buttons.js 模板中,那么其他模板(比如 forms.js )将不能使用 .btn 这个类,除非我们也明确的将 buttons.js 引入到 forms.js 中。

为什么我们想要将CSS与HTML混合来完成这些?我们究竟为什么要这样使用它?

为什么我们应该使用CSS模块?

使用CSS模块,它将保证所有样式都作用于单个组件: 1.在一个地方 2.只应用于该组件而没有别的

此外,任何组件都可以有一个真正的依赖关系,如

import buttons from "./buttons.css";
import padding from "./padding.css";

element.innerHTML = `<div class="${buttons.red}  ${padding.large}">`;

这种做法的目的是为了解决css中全局作用域 (global scope) 的问题

(This approach is designed to fix the problem of the global scope in CSS.)

你曾经有过试图在一个缺乏时间和资源的情况下尽快写出简单的CSS而不用考虑它对其他造成的影响的情况吗?

你曾经有在样式表的底部残留一些随意的不好的片段并且尝试去组织他们但是从来没有组织吗?

你曾经碰到过一些你并不能完全确认它的作用或者是否已经被使用的样式吗?

你曾经是否考虑过你可以移除一些样式而不破坏其他?疑惑这个样式是取决于自己还是依赖于其他?或者在其他地方重写样式?

这些问题可能会让你很头疼,延长项目的截止日期,并且忧伤的、渴望的望着窗外。

使用CSS模块以及 默认当前作用域 的理念,这些问题都将被避免。当你写样式时你必须思考样式的最终结果。

比如,如果你在HTML中使用 random-gross-class 而没有将其应用为一个CSS模块风格的类,这个样式不会被应用,因为CSS选择器将会被转换为 ._style_random-gross-class_0038089 .

composes 关键字

建设我们有一个命名为 type.css 的文本样式模块。在这个文件中我们可能有以下内容:

.serif-font {  
    font-family: Georgia, serif;
}  
.display {  
    composes: serif-font;  
    font-size:  30px;  
    line-height:  35px;  
}

我们将在我们的模板中这样声明它们:

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 关键字,所有样式都被绑定在元素中,从而避免了 一些类似的解决方案的问题 ,比如Sass的 @extend

我们甚至可以在一个独立的CSS文件中引入一个特定的类:

.element {  
    composes: dark-red from "./colors.css";  
    font-size:  30px; 
    line-height:  1.2; 
}

不需要BEM

当我们使用CSS模块时,我们并不需要使用 BEM 。有两个原因:







请到「今天看啥」查看全文