我最近对 CSS Modules 感兴趣。 如果你还没有听说过它们,这篇文章就是为你准备的。 我们将研究这个项目及其目标和目的。 如果你感兴趣,请继续关注,因为下一篇文章将介绍如何开始使用这个理念。 如果你想实现或提升你的使用水平,第 3 部分将介绍如何在 React 环境中使用它们。
文章系列
- 什么是 CSS Modules 以及我们为什么需要它们? (您当前所在位置!)
- CSS Modules 入门
- React + CSS Modules = 😍
什么是 CSS Modules?
根据 仓库,CSS Modules 是
默认情况下所有类名和动画名称都在本地限定范围的 CSS 文件。
因此,CSS Modules 不是一个官方规范或浏览器中的实现,而是在构建步骤中(借助 Webpack 或 Browserify)更改类名和选择器以限定范围(即有点像命名空间)的过程。
这看起来像什么,为什么要这样做? 我们稍后会详细介绍。 首先,请记住 HTML 和 CSS 通常是如何工作的。 类在 HTML 中应用
<h1 class="title">An example heading</h1>
并在 CSS 中设置该类的样式
.title {
background-color: red;
}
只要该 CSS 应用于 HTML 文档,则该<h1>
的背景将为红色。 我们不需要处理 CSS 或 HTML。 浏览器理解这两种文件格式。
CSS Modules 采用了不同的方法。 我们需要在 JavaScript 文件(如index.js
)中编写所有标记,而不是编写纯 HTML。 以下是如何工作的示例(我们稍后将查看更真实的示例)
import styles from "./styles.css";
element.innerHTML =
`<h1 class="${styles.title}">
An example heading
</h1>`;
在我们的构建步骤中,编译器将搜索我们导入的styles.css
文件,然后查看我们编写的 JavaScript 并通过styles.title
使.title
类可访问。 然后,我们的构建步骤将这两者处理成新的、单独的 HTML 和 CSS 文件,并使用新的字符字符串替换 HTML 类和 CSS 选择器类。
我们生成的 HTML 可能如下所示
<h1 class="_styles__title_309571057">
An example heading
</h1>
我们生成的 CSS 可能如下所示
._styles__title_309571057 {
background-color: red;
}

类属性和选择器.title
完全消失了,被这个全新的字符串替换了;我们的原始 CSS 根本没有提供给浏览器。
【类】是动态生成的、唯一的,并映射到正确的样式。
这就是样式限定范围的含义。 它们限定在特定的模板中。 如果我们有一个buttons.css
文件,我们只会将其导入到buttons.js
模板中,并且其中的.btn
类将无法访问其他模板(例如forms.js
),除非我们也在那里专门导入它。
为什么我们要修改 CSS 和 HTML 来做到这一点? 我们为什么要以这种方式工作?
我们为什么要使用 CSS Modules?
使用 CSS Modules,可以保证单个组件的所有样式
- 位于一个地方
- 仅应用于该组件,而不是其他任何组件
此外,任何组件都可以拥有真正的依赖项,例如
import buttons from "./buttons.css";
import padding from "./padding.css";
element.innerHTML = `<div class="${buttons.red} ${padding.large}">`;
这种方法旨在解决 CSS 中的全局作用域问题。
您是否曾因为时间或资源不足而只想尽快编写 CSS,而不考虑可能影响的其他内容?
您是否曾经在样式表的底部粘贴一些随机的片段和垃圾,打算以后整理,但从未整理?
您是否曾经遇到过不确定其作用或是否正在使用的样式?
您是否曾经想过是否可以在不破坏任何内容的情况下删除某些样式?想知道样式是否独立存在或依赖于其他内容?或者覆盖了其他地方的样式?
这些问题会导致严重的麻烦、项目截止日期延长以及悲伤、渴望地望着窗外。
使用 CSS Modules 和默认本地作用域的概念,可以避免此问题。 您在编写样式时始终被迫考虑后果。
例如,如果您在 HTML 中使用random-gross-class
而不将其应用为 CSS modules 样式类,则样式将不会应用,因为 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。 这是因为两个原因
- 易于解析 – 像
type.display
这样的代码对于开发人员来说与 BEM 风格的.font-size__serif--large
一样易读。 当 BEM 选择器变长时,可能更容易在心理上进行解析。 - 本地作用域 – 假设我们在一个模块中有一个像
.big
这样的类,它更改了font-size
。 在另一个模块中,我们使用完全相同的类.big
,它以不同的数量增加padding
和font-size
。 这根本没关系! 它们不会发生冲突,因为样式非常谨慎地限定了范围。 即使一个模块导入两个样式表,它也有一个自定义名称,我们的构建过程专门为此类创建该名称。 换句话说,CSS Modules 消除了特异性问题。
很酷,对吧?
这些只是编写 CSS Modules 的一些好处。
如果您有兴趣了解更多信息,Glen Madden 已经广泛地撰写了关于这种方法的其他一些好处。
本系列的下一篇文章将介绍如何使用 Webpack 和 CSS Modules 启动项目。 我们将使用最新的 ES2015 功能来执行此操作,并查看一些示例代码以指导我们完成整个过程。
进一步阅读
文章系列
- 什么是 CSS Modules 以及我们为什么需要它们? (您当前所在位置!)
- CSS Modules 入门
- React + CSS Modules = 😍
如果 CSS 与元素如此紧密地绑定,则应将其放在元素的 style 属性中。
我同意。 这似乎是不必要的复杂化。 使用外部 css 的目的是使 html 更简洁。 我甚至尽量避免过度使用 class 属性。 只需添加
<section class="newsList">
,并按元素名称向下设置树的样式。内联 CSS 有一些限制,例如不支持伪选择器…
我也有同样的想法。 唯一的事情是您只需编写一次样式部分。
我同意理查德的观点。在我看来,这似乎是倒退了一步。
实际上它更友好,我必须同意罗宾在这点上的观点,它甚至可以在IE6上运行,你敢相信吗?尽管我前几天访问的一个网站似乎在整个网站中都使用了它 http://www.skyblueoceanmedia.com/ .. 他们似乎也使用了Section-Class模块?我仍然很困惑,这如何在IE6甚至新浏览器中工作?
我不会把自己所有的HTML都写在JS里面,仅仅是为了使用CSS模块……抱歉,这是一个聪明的想法,但我认为它不实用。
我同意!
这听起来毫无必要地复杂。尤其是在你可以使用带有polyfill的scoped css 的情况下。
我的第一反应是WTF!
我心想:“也许我特别愚钝,完全错过了重点。”
所以我又读了http://glenmaddern.com/articles/css-modules
是的,当前的CSS模块实现对我来说看起来真的很乱,但我能理解为什么它们可能是一件好事。
我可能会在某个时候改变主意,但这似乎毫无必要地复杂。
整个“让我们把所有东西都变成JavaScript”的做法有点过头了。我和其他人一样喜欢React及其朋友,但需要划清界限。这是Sass文件可以轻松完成的事情,而且不需要那么多额外的工作。
有很多其他方法可以控制你的作用域,而不必诉诸于此。我想如果已经使用了像React这样的工具,在那里它们在JS中完成所有事情,那么这种方法会很有用,但是使用像LESS或PostCSS(带插件)这样的工具,这种精确的作用域已经可以在范围内实现,并且具有更好的语义。
关于CSS模块,有两件事我真的很喜欢。
它们可以承担/补充BEM(或任何其他命名约定/方法)的作用,但它们可以作为构建的一部分自动化。对于大型项目/团队来说,这对于保持所有内容正确的作用域非常有帮助。
它们允许在构建中进行一些很酷的创新。例如,使用PostCSS-Modules和SweatMap(我的一点Github项目),我已经能够将所有像
.hello__greeting
这样的超语义BEM类名混淆成.a
,并将它们传递到所有相关的JS和HTML文件中,同时仍然保持正确的作用域。我想评论的另一件事是文章中的这句话
需要明确的是,我们**不需要**在JavaScript中编写我们的标记。标记可以用我们喜欢的任何方式编写,我们只需要能够在构建期间传入我们的CSS模块数据即可。我最近用Handlebars + PostCSS-Modules做了一个静态站点项目,感觉比在JavaScript文件中编写标记自然得多。当一个项目需要React时,JSX也感觉非常好:)
很好的分解,罗宾!我期待着有一天我们能够以原生方式正确地为我们的css设置作用域,而不需要构建过程或“神秘的”命名约定。
你的SweatMap工具看起来很棒——我查看了一些来自谷歌的源代码,并假设他们有一个类似的构建过程。
在前端代码传递给后端开发人员的开发团队中,你如何看待这个过程的工作方式?
谢谢,迪恩!PostCSS-Modules通过生成所有已更改模块的JSON文件来处理后端模板。只要你的前端构建在后端构建之前运行,你就可以将该JSON文件传递到你用于后端模板的任何内容中(在以React为中心的产物中非常流畅)。
前端和后端之间的协调始终是一个挑战,但我发现无论使用什么工具,在任何项目中都是如此。
好吧,是的,我同意这里的大多数评论。不,我绝对不会用javascript开发一个新的框架,它仅仅因为CSS是模块化的就生成HTML代码。
但我心想“如果我被分配了一个找到这个的完美场景的任务会怎么样?”——在我看来,这对于动态生成的页面来说是好的。最有可能的是用户生成的内容,在你有每个用户的个人资料部分并且他们可以修改其个人资料页面的布局和结构的场景中。你可能不希望加载该页面所有的模块。曾经有iGoogle(现在:http://www.igoogleportal.com/)。
我猜这是一个场景?
仅供参考,CSS作用域是Angular 2开箱即用的功能。它对于创建干净的可重用组件非常不错。
“我们不需要编写纯HTML,而需要在JavaScript文件中编写所有标记,例如index.js。”
不。我不会在我的JS中编写所有标记并添加编译步骤,最终得到语义上毫无意义的类名,仅仅是为了解决作用域问题。
而且我真的希望前端开发社区失去对尝试用JS做所有事情的迷恋。它非常有用,但将前端开发的每一部分都塞进JS思维模式中,真的开始让人感到厌烦了。
我完全同意,向JS解决方案的转变速度非常快——也许快到对我们自己不利的地步。
同时,完全否决这个想法也可能对我们不利。我坚信为特定工作选择合适的工具,而JS模板(包括CSS模块)可能是你可能尚未遇到的应用程序的可靠解决方案。
JS模板可能确实有一个利基市场。我只是不喜欢它被推崇为我们首先寻求的解决方案。克里斯刚刚发布了杰里米·基思的一个演讲的链接(https://css-tricks.cn/resilience/),我认为它体现了我所青睐的方法。
确定网站的核心功能。
使用最简单的技术提供该功能。
增强!
当然,在JS能带来真正价值的地方使用它。如果在给定项目的模板中,那么当然可以使用它。但不要把JS模板强加于我作为一种通用的良好实践。
同意!!
用纯JS编写我的所有标记会要了我的命,以及我的前端开发人员的命……:(
CSS模块似乎是一个好主意,但我认为它还没有达到那个水平,如果我们需要转向JS标记……
从技术上讲并非如此。你只需要一种机制将自动生成的CSS类名放入最终的HTML标记中。
如果你正在使用JSX或ES2015模板,那么JavaScript就是这种机制。
但是CSS模块方法与Angular 1一起工作得很好,Angular 1使用HTML模板。
请不要吓跑人们,让他们远离CSS模块。:)
罗恩。
你是否有机会解释如何将CSS模块与Angular一起使用?
我对这么多评论都错过了这篇文章的重点感到惊讶。我可以看到很多人在被告知使用Javascript输出HTML时皱起了眉头,因此这种CSS的使用可能会导致类似——如果不是更糟糕——的反应。
但是web开发中的时代和技术变化**很快**,像React这样的东西在刚出现时被拒绝甚至被嘲笑,现在却成为讨论最多的技术。
看看——在第三部分中,我们将看到CSS模块与React的集成,我认为它们将在那里真正闪耀。当然,对于可能甚至不需要编译的小型项目来说,它是不切实际的,但拜托,伙计们,你们必须给它们一个机会。
我不会代表其他人说话,但正是你评论中隐含的观念——web上的东西应该用React或类似的东西编写——我正在反驳。当然,在某些情况下,React或类似的东西是绝对正确的选择。然而,并非所有情况都是如此,而且似乎很多人默认地选择JS框架,而没有询问他们正在进行的项目是否真的需要它。应用程序?是的。很多网站?可能不是。
我认为web是HTML/CSS/JS,我们首先使用最简单、最快、最基本的技术,只有在真正需要时才转向更复杂的技术。
或者这篇文章错过了 CSS 模块的真正意义。也许这种愚蠢的例子无法展示任何重要的用例,尤其是在作为新用户的入门介绍时。
此外,“最常用”或“讨论最多”并不意味着“最好”。流行度不是验证器,也不能保证适用性。
推广采用需要更好的用例,因为(充其量)决策应该基于需求,而不是影响。
我真是不明白!这似乎又是我们找到的一种方法,可以毫无意义地大幅增加开发过程的复杂性。过去使用外部 CSS 文件的卖点是,您可以全局地为网站的组件设置样式。这仅仅引入了荒谬的特定级别,这将产生 CSS 膨胀,并且为了实现它,您必须在 JS 文件中编写 HTML 和 CSS!
如果你问我,这很愚蠢,但各有所好。
喜欢第一个例子本身就是一些在逻辑结构规则下(也就是 HTML 5 的胡闹把编号标题搞乱之前我们已经拥有的东西)根本没有正当理由去做的事情……在编号标题上使用类?这真是个好主意。
但考虑到预处理器/包含垃圾吐出的臃肿、愚蠢、白痴、笨蛋、垃圾类,以及它有胆量称之为标记,我想这种愚蠢的“我们能把简单的事情变得多么困难”的开发方法应该不足为奇;鉴于任何自愿使用这种东西的人——就像 SCSS、OOCSS 及其同类(是的,牛的古英语复数在这里确实很贴切)——可能对 HTML、CSS、JavaScript、带宽限制、媒介限制、可访问性、可持续性或用户体验一无所知,根本不应该开始创建网站!
我的天哪,我读到的关于这些“新”方法的文章越多,这些方法让 HTML 和 CSS 变得毫无意义地更模糊、更难以维护,就越让人恐惧。说真的,如果你发现使用这种方法编写 HTML 和 CSS 有任何优势,请为世界做个好事,从键盘上退后,去从事一些不太注重细节的事情,比如编织!
但我想,由于有那么多人愚蠢地用像 Bootcrap 和 jQuery 这样的令人窒息的短途巴士愚蠢行为来膨胀他们的代码,所以在尝试使网站尽可能地臃肿和难以维护方面,已经没有顾忌了!
也许您想用一些您作品的例子来支持这些观点?
我敢打赌,您的网站可能看起来像 1996 年左右的雅虎首页,因为您似乎认为网络技术不应该从 20 年前的原始基本文档标记和样式工具中发展。
或者,也许您讨厌 SASS、模块加载、JS 框架等的原因是您根本没有能力正确理解它们?
如果您如此讨厌所有新技术,我认为您来错行业了。
“textExtract”插件支持它吗?看起来像您调试器窗口中的内联样式表。
http://www.xanthir.com/blog/b49w0
这就是我所想象的 CSS 模块。我将等待它在原生 CSS 中实现,或者有一个 polyfill。我不会像您在这里做的那样做。
一方面,我忍不住想成为我通常的那样怀疑,并写一些类似于其他人已经写过的话……
另一方面,这有点意思。从最简单的角度来看,在去除所有 JS 垃圾并编写一些伪代码后,它似乎归结为以下内容
foo.css
bar.css
index.html
而如果这两个样式表简单地连接在一起(或只是包含在一起),
foo
最终将应用来自foo.css
和bar.css
的所有样式,而无法分离。除了……为什么不放弃整个预/后处理步骤,而只是为您的 CSS 类命名空间?
foo_foo
与foo.foo
键入的难度相同,并且设置起来要容易得多(无需预/后处理,无需不必要的 HTML 模板等)。哦,也没有可怕的、丑陋的、到底是什么鬼东西的类名。
所以,长话短说,这篇文章描述的内容听起来像是 CSS 命名空间,但使用文件名而不是在 CSS 标识符中添加前缀。我错过了什么吗?
好吧,我想我错过了 CSS 和 HTML 之间的紧密耦合。使用 CSS 模块,可以更容易地分析实际使用了哪些 CSS 规则,哪些规则是死代码等。
但是,等一下……您如何从动态代码中使用这些类?例如
foo.toggleClass('active')
?我们是否必须进入一些复杂的样式 JS 映射,例如foo.toggleClass(compiledStylesMap['active'])
,其中compiledStylesMap['active']
导致'active_fileName_1234'
?我的头有点疼。
是的!CSS 模块本质上是构建/自动化的命名空间。
如果您在一个小型团队中或独自工作并遵循良好的约定(BEM、ACSS 等),这是一个好主意。问题在于,当您开始向团队添加开发人员并且他们不认同或没有良好的实践时。无论您的团队是否这样做,CSS 模块都会强制执行命名空间。
类名如何显示完全取决于您。上面显示的内容只是默认值或作者为该项目选择的内容。您可以使用 CSS 模块并输出类似
[filename]_[classname]
的内容,并在构建设置后无需考虑任何内容或做任何额外工作的情况下生成与您上面描述完全相同的类名。您甚至可以混淆名称(如我在上面的评论中提到的),并节省一些字节,将.my-semantic-class
转换为.a
用于生产,同时确保它仍然是唯一的。在构建期间。CSS 模块 和 PostCSS-Modules 的 Github 页面更详细地介绍了这些内容。
“当您开始向团队添加开发人员并且他们不认同或没有良好的实践时,问题就开始了。”
这是一个工程管理/领导的失败,我不确定使用这种技术来弥补人们的懒惰和无法或不愿变得有条理是否是一个好主意。
这不仅仅是关于懒惰或能力问题。人们也会犯错误。
冒着听起来教条主义的风险,我认为自动化和工具来为我们进行优化始终是一个好主意。为什么要手动执行某些操作,并因此让整个团队手动执行可以在构建时自动且完美一致地执行的操作?是的,它增加了复杂性,但我们在这里谈论的是保证它的团队项目。
如果您在一个团队中,我假设您会自动对 HTML、JS 和 CSS 执行其他优化,例如缩小和混淆。是什么让构建期间的命名空间类成为“工程管理/领导的失败”?
本杰明,你能给我链接一个动态交互类的例子吗?抱歉,找不到您引用的内容。
当然可以 @Agop,看看这个 -> https://github.com/outpunk/postcss-modules#integration-with-templates
它给出了一些使用 Jade(现在是 Pug)和带有 PostHTML 的纯 HTML 的示例。相同的原则适用于在构建时可以将 JSON 对象作为值的任何模板设置。我个人在 JSX 和 Handlebars 中都使用它来渲染静态 HTML。如果您遇到问题,请告诉我!
在“javascript 中的白色 HTML”处,我迷失了方向,拜托。
写*
对不起,我仍然不明白“CSS 模块”的价值。这里宣传的主要原因是避免级联,如果您想要正确的标记并想要在该标记上使用任何 CSS,这根本不可能。我在这里总结了我的“问题”:https://helloanselm.com/notes/on-css-modules/。
如果您有使用 CSS 模块的实际经验,我很想知道我的文章中的观点是否正确,以及使用该技术/工具的主要优势是什么。提前感谢。
安塞尔姆,很棒的回复。你和我发现了同样的东西。
我一直在尝试对这篇文章持开放态度,但我认为当我阅读链接的格伦·马登的文章时,我找到了我无法与之产生共鸣的原因。
我认为这触及了为什么我们很多评论者对所提议的内容没有产生共鸣的根本原因。CSS 模块的思维方式假设 CSS 作为一种语言是“有缺陷的”,因为它不像其他语言那样工作。因此,需要使用(JavaScript)修复它以使其像其他语言一样。
CSS 的工作方式与其他语言不同,因为它被设计为一种全局适用、影响深远的语言,您可以用很少的努力产生很大的变化。
CSS 是一种强大的语言,需要大量的培训和经验才能熟练使用。即使 CSS 模块确实有其实用目的,这篇文章也试图从“编码很难,维护代码更难,所以这里有一个捷径”的角度来论证这个目的,这不是赢得 CSS 专家芳心的方法。
不过,我确实喜欢发人深省的讨论,所以在这一点上这是一篇好文章。
@Kevin Powell,我们今天面临的问题与20年前不同了。现在 Web 被用于构建 Web 应用、混合应用,甚至桌面应用。这就是 CSS 的问题所在。现在我们需要解决 CSS 的规模化问题。JavaScript 在今年发展壮大以解决其可扩展性问题,现在是 CSS 做同样的事情的时候了。
即使对于大型网站和大型前端团队中的 Web 应用,我从未遇到过 CSS 可扩展性问题(或者人们常说的:“CSS 规模化”)。在大型团队中编写可重用、模块化的代码确实需要更多努力和纪律性,但这是编写 CSS 的人员的工作。
不过,Matteo,你有一点是对的,那就是“桌面应用”。在这种情况下,我们谈论的是不需要通过网络下载 CSS 的桌面应用,文件大小不再那么关键。但另一方面,你也不希望应用程序臃肿缓慢(我并不是说“CSS 模块”很慢,这完全取决于它的使用方式)。如果你有关于 CSS 规模化效果不好的真实案例,请告诉我。除了模块需要元素查询之外(这确实很有用,但总体上并不是使其工作所需的条件),我还没有发现其他问题。
嗨,团队!
这是一个强烈的讨论——证明了这一点值得讨论。
现在是时候练习不要教条式地思考,并记住 Web 是一个广阔的地方,有许多方法可以做事情(有时是相同的事情)。
确实如此。
我记得当人们意识到 Angular 涉及将 JavaScript 放入 HTML 属性中时(更不用说我们中的一些人使用非标准的 HTML 标签)所带来的负面情绪。很多人也说 CSS 预处理器永远不会流行起来。不过,Angular 和 SASS 似乎都取得了相当不错的成绩,我无法想象回到不使用它们的时候。
话虽如此,我个人并不喜欢它,因为我认为它很丑陋,而且需要太多妥协。但我认为它是必要的,并且我认为更好的解决方案将会出现,即使我们不得不等待 WC3/浏览器供应商提出一个合适的 CSS 模块规范。
感谢 Robin 的清晰解释,我赞同这一点。
关于这个概念的一些意见,而不是文章或 Robin 本人。
CSS 模块的概念:110% 完全有效。
CSS 模块的实现:彻底的灾难。
必须得喜欢这个:
class="_type__display_0980340 _type__serif_404840"
“不需要 BEM”——BEM 从来都不是必需的 :)
将 CSS 移到 JavaScript 中只会继续使 Web 设计和开发专业人员碎片化。
解决 CSS 中的“全局作用域”问题真的那么重要吗?实际上,它甚至算是一个问题吗?
“compose”不是一个关键字,而是一个属性吗?
从这里其他评论中,尤其是 Kevin Powell 的评论来看,CSS 模块似乎只是去除了 CSS 的强大全局作用域(它被创建的原因),以解决人们存在的问题——代码组织不当,没有遵循最佳实践。当然,我们的世界并不完美,因此我们的代码也不完美,但我认为这增加了很大程度的复杂性,而回报却很少。
我很惊讶这么多人错过了 CSS 模块的重点。
CSS 选择器就像一个 API,HTML 可以使用它来应用特定的样式。
CSS 模块提出了一种解决方案,用于解决名称冲突、封装和样式组合的更好管理问题。
巧妙的方法,但在所有情况下都不需要。
我想提出一个我在评论中还没有看到的问题。
除了增加整体复杂性之外,我最大的担忧是最终网页的权重。虽然对于内容较少的较小网站来说,这可能不是一个大问题,但对于内容动态且持续请求的内容(例如 Twitter、Facebook)的单页应用程序来说,这肯定是一个问题,因为你每次请求都会从服务器获取这些数据。(越小越好?)
假设字符在 ASCII 范围内,类属性中的每个字符大约等于 1 字节(UTF-8),并且使用此方法生成的字符数量有可能至少增加一倍,甚至更多。根据你网站的结构以及你打算使用类的频率,网页的权重肯定会随之增加。在考虑移动设备时,这一点尤其令人担忧,因为你通常不希望不必要地占用用户的流量。
我将继续关注后续文章,因为我想看看这件事会如何发展。我可能只是因为缺乏理解而存在偏见。正如一图胜过千言万语一样,一个实际的例子也同样如此。
因此,类的尺寸通常不是问题,尤其因为你可能应该对所有内容进行 Gzip 压缩,这更加重要且有益。也就是说,实际的类名完全由你决定。你可以指定格式,或者如果你愿意,甚至可以对其进行混淆(
.my-semantic-class
->.A
)。你可以在 CSS 模块 和 PostCSS-Modules 的 Github 页面上了解更多信息。我有点沉迷于节省一些字节,所以我制作了一个名为 SweatMap 的工具,它与 CSS 模块配合得非常好,并允许我执行上面提到的混淆操作。
是的,可能会有潜力。但由于示例如此愚蠢,因此很难很快成为信徒。
我认为标题中缺少一个“not”。
等等,其他选择器(如
:nth-child(x)
或[foo=bar]
)怎么办?兄弟选择器呢?嵌套呢(例如.no-js .foo {}
)?对我来说,这里不需要 CSS。这些不是“CSS 模块”。不妨直接称它们为“SDL 模块”——“样式定义语言模块”。
我在 React 应用中使用过它。它绝对很有趣,尝试新事物总是一件好事。但我不喜欢的是必须在 JS 文件中编写纯 HTML。此外,据我所知,无法使用 HAML,这对我来说是一个很大的障碍(缩进语法万岁)。据我所知,不支持 SASS 语法,因此你无法使用 SASS 混合。但总的来说,我认为 CSS 的优势在于你可以编写可重用的样式,这些样式可以被应用中任何元素使用。这种方法并没有促进这一点。此外,我不喜欢 CSS 散布在整个项目中,而不是集中在一个地方。这可能对某些人有一些好处,但我并不喜欢它(个人观点)。我也不喜欢那些可怕的长随机类名。这使得调试非常困难。
为了解决类名冲突的问题,我认为使用合适的架构并遵循最佳实践(结合 BEM 等方法)是一个更好的选择。
你好!我只是想知道你使用的是哪个 DevTools 主题。
哦,不,在简单的 HTML/CSS 中又增加了复杂性。在我看来,CSS 模块是为了创建组织良好的 CSS 样式,因为开发人员很粗心。我认为重点应该放在让开发人员编写组织良好的代码上,而不是依赖像这样的东西来帮助他们组织代码。此外,由于有这么多不同的方法,当某人接手一个不熟悉所用开发工具的 Web 项目时,这将是一场噩梦。
在 Chrome 检查器中看到“_styles__title_309571057”能帮助我调试任何问题吗?
哈哈。
这不是错误,而是一个特性。层叠样式表,有人吗?
停止争论!学会爱上层叠。
我想“:root”之类的选择器将无法工作(例如,谷歌的 Polymer 也一样)。
相信我,一旦你开始使用 React,这就会更有意义。对于那些想知道我在说什么的人,可以查看 React Starter Kit。
这是一个有趣但深奥的技巧。对于小型脏乱的 hack 来说还不错,但对于那些可以正确组织和编写 CSS 的人来说,它似乎是一种古色古香的方法。它唯一的作用就是通过使 HTML 结构更加复杂来修复糟糕的 HTML 结构。尤其是在 SASS 等和它的前辈出现后,这种方法几乎是自相矛盾的。
而且,如果没有 JS,整个东西都会崩溃 :-)
Jason Knight ^^^ 说的没错 ;-)
看起来这篇文章系列的最终目标是如何在 React 中工作。也许将标题改为“什么是 CSS 模块以及**为什么我们需要它们用于 React**”会是一个好主意?现在的标题确实倾向于采取教条式的方法……
同意!
如果你曾经在一个由数百家供应商使用和自定义样式的企业应用程序上工作过,你就会理解这有多棒。
这个 ^。CSS 模块的附加值与代码库的大小和参与的人数成正比。
……那么文章需要重命名为“什么是 CSS 模块以及为什么我们需要它们在企业应用程序中?”。在这种情况下,正确的工具和技术非常适用。正如大多数评论所证明的那样,这并不是利用 CSS 全局能力的实用方法(正如 Kim Joy Fox/Kevin Powell 指出的那样)。
完全同意“适合工作的正确工具”的理念。问题在于,在一定规模下,CSS 的全局能力开始成为一个沉重的负担,而不是一个好处。
CSS 模块
优势:命名空间。非常有用,但可以通过后代选择器、预处理器中的嵌套或您喜欢的手动命名约定方案(BEM 等)标准最佳实践轻松解决。最好将精力花在将命名空间添加到 CSS 规范上!
成本:复杂性大大增加,渲染性能差(只有原生 CSS 在 JavaScript 之前应用),来自模块中重复的 CSS 属性的 CSS 膨胀,这些属性以前是全局的。
首先,我并不反对改变。相反,我使用并接受许多新的工具和模式,包括 Js 作为视图引擎(如 React)、不可变数据、转译、预处理、构建工具等。我客观地思考过 CSS 模块,但最终我认为这是一个严重的错误,并希望它不会发展得太远。
我可以保证,将此推向 Web 开发界最大的原因是,那些几乎没有涉猎前端问题的计算机科学专业学生,可以用尽可能少的 CSS 知识进入前端。想想看。这要归功于大型公司人力资源/财务部门的招聘/团队构成决策。你注意到了吗?最近几年,他们逐渐用软件工程师取代了那些真正擅长 HTML/CSS 的人(无论是通过自然减员还是其他方式)。他们通过以下方式实现了这一点:a) 使用抽象掉对更深入的 HTML/CSS 知识需求的工具,如 Bootstrap 或第三方主题;b) 由于响应式革命,当前的 UI/UX 趋势变得简单化,需要更少的专业知识。这些正是撰写此类文章并主要宣传它的人。
我并不是说这些人有什么问题。但他们中的许多人并不深入了解对应用程序逻辑有益的东西并不总是符合设计工作方式的最佳利益。首先,设计受益于一个简洁的框架。方法中越多的技术性和样板代码,大脑就需要处理更多内容。就我个人而言,而且我认为我代表了其他人,虽然我可以理解和使用额外的结构,并且很多时候可以看到它的优点,但它也可能阻碍创造性过程,以至于增加的效率达到或超过了收益递减点。
软件工程师从第一天起就被教导全局命名空间是一种邪恶,这是一种口头禅。这在编程语言中通常是正确的……不仅是因为与您自己和第三方代码发生冲突,而且在 JavaScript 中与核心全局对象发生冲突。但在 CSS 中,问题与编程语言不同。默认继承并不是一件坏事,因为需要如此多的继承。设计是品牌。品牌需要统一,因此级联是你的朋友,而不是你的敌人。
也就是说,我们当然需要防止 CSS 中的名称冲突,那么为什么不直接将其构建到 CSS 中呢?除了能够驯服后代选择器之外,我还赞成受保护不受级联影响的 Web 组件的想法。但不同之处在于,作为一名经常从纯白页面构建大型应用程序复杂用户界面的人;-),我相信 CSS 中的全局优先是正确的方法。向人们灌输 CSS 中全局实际上很糟糕的想法弊大于利,我保证会导致很多品牌受损……(例如,一个 H1 在一个“组件”中是 30px,但在另一个组件中是 32px,等等等等)。