首页 > web前端 > html教程 > CSS 模块_html/css_WEB-ITnose

CSS 模块_html/css_WEB-ITnose

WBOY
发布: 2016-06-21 09:07:59
原创
1036 人浏览过

如果你想知道 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 */}
登录后复制

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

相关标签:
来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板