目录
第一步:像局部一样无需考虑全局冲突
CSS 模块之前我们是怎么做的
CSS 模块出来之后我们是怎么做的
命名约定
React 示例
第二步:组件就是一切
Sass
CSS 模块
第三步:文件间共享
第四步:功能单一模块
翻滚吧!CSS 模块!
最后的最后,祝大家开心写样式,幸福每一天!
首页 web前端 html教程 CSS 模块_html/css_WEB-ITnose

CSS 模块_html/css_WEB-ITnose

Jun 21, 2016 am 09:07 AM

如果你想知道 CSS 最近发展的转折点,你应该选择去观看 Christopher Chedeau 于 2010 年提出来的一个概念),那么 Christopher 则是让许许多多的可能变得更加接近(译者注:上面三个工具中的两个灵感都是来自他的分享)。

上图列出的这些都是在许多大型 CSS 代码库中存在的问题。Christopher 指出,只要将你的样式通过用 JS 去管理,这些问题都能很好的解决。不得不说这的确是有道理的,但是这种方法有它的复杂性并会带来其他的相关问题。其实只要看看浏览器是如何处理 :hover 伪类状态的,我们就会发现有些东西在 CSS 中其实***很早***就解决了。

CSS 模块小组 觉得我们可以更加合理的解决问题:我们可以继续保持 CSS 现在的样子,并在 styles-in-JS 社区的基础上建立更合理的改进。虽然我们已经找到了解决办法同时又捍卫了 CSS 原始的美,但我们仍然欠那些把我们推向这个结果的那些人一声感谢。谢谢你们,朋友们!

下面让我来向大家解说一下什么是 CSS 模块并且为什么它才是未来吧。

第一步:像局部一样无需考虑全局冲突

在 CSS 模块中,每一个文件被编译成独立的文件。这样我们就只需要使用通用简单的类选择器名字就好了。我们不需要担心它会污染全局的变量。下面我就我们编写一个拥有四个状态的按钮来说明这个功能。

https://jsfiddle.net/pqnot81c/embedded/result/

CSS 模块之前我们是怎么做的

我们也许会使用 Suit 命名规范去进行样式命名,这样我们的 HTML 和 CSS 代码看起来就像如下所示:

/* components/submit-button.css */.Button { /* all styles for Normal */ }.Button--disabled { /* overrides for Disabled */ }.Button--error { /* overrides for Error */ }.Button--in-progress { /* overrides for In Progress */
登录后复制
<button class="Button Button--in-progress">Processing...</button>
登录后复制

这样写看起来还挺棒的。使用 BEM 命令方式使我们有了 4 个样式变量这样我们不必使用嵌套选择器。使用Button这种首字母大写的方法可以很好的避免与之前的代码或者是其他的依赖代码进行冲突。另外我们使用了--语法这样能很清楚的显示出我们的依赖 Class。

总的来说,这样做可以让我们的代码更易于维护,但是它需要我们在命名规范的学习上付出很多努力。不过这已经是目前 CSS 能给出的最好的解决办法了。

CSS 模块出来之后我们是怎么做的

CSS 模块意味着你从此再也不必为你的名字太大众而担心,只要使用你觉得有最有意义的名字就好了:

/* components/submit-button.css */.normal { /* all styles for Normal */ }.disabled { /* all styles for Disabled */ }.error { /* all styles for Error */ }.inProgress { /* all styles for In Progress */
登录后复制
登录后复制

请注意我们这里并没有在任何地方使用 button 这个词。不过反过来想,为什么我们一定要使用它呢?这个文件已经被命名成了 submit-button.css 了呀!既然在其它的语言中你不需要为你的局部变量增加前缀,没道理 CSS 需要加上这个蹩脚的功能。

通过使用 require 或者 import 从 JS 中导入文件使得 CSS 模块被编译成为可能。

/* components/submit-button.js */import styles from './submit-button.css';buttonElem.outerHTML = `<button class=${styles.normal}>Submit</button>`
登录后复制

你不必担心大众名字会倒置命名冲突,编译后实际上类名是会自动生成并保证是唯一的。CSS 模块为你做好一切,最终编译成一个 CSS 与 JS 交互的 ICSS 后缀文件(阅读这里了解更多)。因此,你的程序最终看起来可能会是这个样子的:

<button class="components_submit_button__normal__abc5436">  Processing...</button>
登录后复制

如果你的类名变的和上面的例子差不多的话,那么恭喜你你成功了!

命名约定

现在回过头来仔细看看我们的示例代码:

/* components/submit-button.css */.normal { /* all styles for Normal */ }.disabled { /* all styles for Disabled */ }.error { /* all styles for Error */ }.inProgress { /* all styles for In Progress */
登录后复制
登录后复制

请注意所有的类都是相互独立的,这里并不存在一个“**基类**”然后其它的类集成并“**覆盖**”它的属性这种情况。在 CSS 模块中**每一个类都必须包含这个元素需要的所有样式**(稍后会有详细说明)。这使得你在 JS 中使用样式的时候有很大的不同:

/* Don't do this */`class=${[styles.normal, styles['in-progress']].join(" ")}`/* Using a single name makes a big difference */`class=${styles['in-progress']}`/* camelCase makes it even better */`class=${styles.inProgress}`
登录后复制

当然,如果是的工资是按照字符串长度来计算的话,你爱怎么做就怎么做吧!

React 示例

CSS 模块并不是 React 特有的功能,但是不得不说在 React 中使用 CSS 模块会更爽。基于这个理由,我觉得我有必要展示下面这个如飘柔般丝滑的示例:

/* components/submit-button.jsx */import { Component } from 'react';import styles from './submit-button.css';export default class SubmitButton extends Component {  render() {    let className, text = "Submit"    if (this.props.store.submissionInProgress) {      className = styles.inProgress      text = "Processing..."    } else if (this.props.store.errorOccurred) {      className = styles.error    } else if (!this.props.form.valid) {      className = styles.disabled    } else {      className = styles.normal    }    return <button className={className}>{text}</button>  }}
登录后复制

你完全不需要担心你的类命名会和全局的样式表命名冲突,这样能让你的注意力更集中在**组件**上,而不是样式。我敢保证,使用过一次之后,你会再也不想回到原来的模式中去。

然而这仅仅是一切的开始。CSS 模块化是你的基本,但也是时候来思考一下如何把你的样式们都集中到一块了。

第二步:组件就是一切

上文中我提到了每一个类必须包含按钮不同状态下的**所有**的样式,与 BEM 命名方式上相比,代码上可能区别如下:

/* BEM Style */innerHTML = `<button class="Button Button--in-progress">`/* CSS Modules */innerHTML = `<button class="${styles.inProgress}">`
登录后复制

那么问题来了,你怎么在所有的状态样式中**共享**你的样式呢?这个答案就是 CSS 模块的强力武器 - **组件**:

.common {  /* all the common styles you want */}.normal {  composes: common;  /* anything that only applies to Normal */}.disabled {  composes: common;  /* anything that only applies to Disabled */}.error {  composes: common;  /* anything that only applies to Error */}.inProgress {  composes: common;  /* anything that only applies to In Progress */}
登录后复制

composes这个关键词将会使.normal类将.common内的所有样式包含进来,这个有点像 Sass 的 @extends 语法。但是 Sass 依赖重写你的 CSS 文件达到效果,而 **CSS 模块最后会通过 JS 编译导出,不需要修改文件**(译者注:下面会有例子详细说明)。

Sass

按照 BEM 的命名规范,我用 Sass 的 @extends 写的话可能会像如下的代码:

.Button--common { /* font-sizes, padding, border-radius */ }.Button--normal {  @extends .Button--common;  /* blue color, light blue background */}.Button--error {  @extends .Button--common;  /* red color, light red background */}
登录后复制

编译后的 CSS 文件如下:

.Button--common, .Button--normal, .Button--error {  /* font-sizes, padding, border-radius */}.Button--normal {  /* blue color, light blue background */}.Button--error {  /* red color, light red background */}
登录后复制

你可以只需要**一**个类来标记你的元素

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

&lt; datalist&gt;的目的是什么。 元素? &lt; datalist&gt;的目的是什么。 元素? Mar 21, 2025 pm 12:33 PM

本文讨论了html&lt; datalist&gt;元素,通过提供自动完整建议,改善用户体验并减少错误来增强表格。Character计数:159

&gt; gt;的目的是什么 元素? &gt; gt;的目的是什么 元素? Mar 21, 2025 pm 12:34 PM

本文讨论了HTML&lt; Progress&gt;元素,其目的,样式和与&lt; meter&gt;元素。主要重点是使用&lt; progress&gt;为了完成任务和LT;仪表&gt;对于stati

&lt; meter&gt;的目的是什么。 元素? &lt; meter&gt;的目的是什么。 元素? Mar 21, 2025 pm 12:35 PM

本文讨论了HTML&lt; meter&gt;元素,用于在一个范围内显示标量或分数值及其在Web开发中的常见应用。它区分了&lt; meter&gt;从&lt; progress&gt;和前

视口元标签是什么?为什么对响应式设计很重要? 视口元标签是什么?为什么对响应式设计很重要? Mar 20, 2025 pm 05:56 PM

本文讨论了视口元标签,这对于移动设备上的响应式Web设计至关重要。它解释了如何正确使用确保最佳的内容缩放和用户交互,而滥用可能会导致设计和可访问性问题。

&lt; iframe&gt;的目的是什么。 标签?使用时的安全考虑是什么? &lt; iframe&gt;的目的是什么。 标签?使用时的安全考虑是什么? Mar 20, 2025 pm 06:05 PM

本文讨论了&lt; iframe&gt;将外部内容嵌入网页,其常见用途,安全风险以及诸如对象标签和API等替代方案的目的。

如何使用HTML5表单验证属性来验证用户输入? 如何使用HTML5表单验证属性来验证用户输入? Mar 17, 2025 pm 12:27 PM

本文讨论了使用HTML5表单验证属性,例如必需的,图案,最小,最大和长度限制,以直接在浏览器中验证用户输入。

我如何使用html5&lt; time&gt; 元素以语义表示日期和时间? 我如何使用html5&lt; time&gt; 元素以语义表示日期和时间? Mar 12, 2025 pm 04:05 PM

本文解释了HTML5&lt; time&gt;语义日期/时间表示的元素。 它强调了DateTime属性对机器可读性(ISO 8601格式)的重要性,并在人类可读文本旁边,增强Accessibilit

HTML5中跨浏览器兼容性的最佳实践是什么? HTML5中跨浏览器兼容性的最佳实践是什么? Mar 17, 2025 pm 12:20 PM

文章讨论了确保HTML5跨浏览器兼容性的最佳实践,重点是特征检测,进行性增强和测试方法。

See all articles