美文网首页
CSS-Modules

CSS-Modules

作者: 风之化身呀 | 来源:发表于2018-05-16 23:17 被阅读76次
CSS-Modules概览

介绍

  • 是什么?
    CSS模块化的一种解决方案(对css类名限定作用域的一种,只限定类选择器,对id、元素等选择器不管)
  • 原理?
    通过 webpack 在构建过程中,给类名起一个独一无二的名字,这个名字可以通过webpack配置
  • 好处?
    1、避免类名重复导致样式覆盖问题;
    2、JS & CSS 共享变量
    3、健壮可扩展
  • 怎么启用
// 在css-loader后面加上下面这句即表示启用:
css?modules&localIdentName=[name]__[local]-[hash:base64:5]

// 例子
import styles from './Button.css';
console.log(styles);
buttonElem.outerHTML = `<button class=${styles.normal}>Submit</button>`
// 实际渲染成如下:
<button class="button--normal-abc53">Submit</button>
  • css 代码怎么写
    1、使用了 CSS Modules 后,就相当于给每个 class 名外加加了一个 :local,以此来实现样式的局部化,如果你想切换到全局模式,使用对应的 :global
.normal {
  color: green;
}
/* 以上与下面等价 */
:local(.normal) {
  color: green; 
}

/* 定义全局样式 */
:global(.btn) {
  color: red;
}
/* 定义多个全局样式 */
:global {
  .link {
    color: green;
  }
  .box {
    color: yellow;
  }
}

2、使用Compose 来组合样式

/* components/Button.css */
.base { /* 所有通用的样式 */ }
.normal {
  composes: base;
  /* normal 其它样式 */
}
.disabled {
  composes: base;
  /* disabled 其它样式 */
}

import styles from './Button.css';
buttonElem.outerHTML = `<button class=${styles.normal}>Submit</button>`
// 编译结果
<button class="button--base-daf62 button--normal-abc53">Submit</button>

3、使用:export 实现CSS,JS变量共享

/* config.scss */
$primary-color: #f40;

:export {
  primaryColor: $primary-color;
}

/* app.js */
import style from 'config.scss';
// 会输出 #F40
console.log(style.primaryColor);

4、外部如何覆盖局部样式
当生成混淆的 class 名后,可以解决命名冲突,但因为无法预知最终 class 名,不能通过一般选择器覆盖。我们现在项目中的实践是可以给组件关键节点加上 data-role 属性,然后通过属性选择器来覆盖样式。如

// dialog.js
  return <div className={styles.root} data-role='dialog-root'>
      <a className={styles.disabledConfirm} data-role='dialog-confirm-btn'>Confirm</a>
      ...
  </div>
// dialog.css
[data-role="dialog-root"] {
  // override style
}

因为 CSS Modules 只会转变类选择器,所以这里的属性选择器不需要添加 :global。
5、如何与全局样式共存
前端项目不可避免会引入 normalize.css 或其它一类全局 css 文件。使用 Webpack 可以让全局样式和 CSS Modules 的局部样式和谐共存。下面是我们项目中使用的 webpack 部分配置代码:
module: {
loaders: [{
test: /.jsx?$/,
loader: 'babel'
}, {
test: /.scss$/,
exclude: path.resolve(dirname, 'src/styles'), // 通过exclude让这个目录下的scss不走css-modules
loader: 'style!css?modules&localIdentName=[name]
[local]!sass?sourceMap=true'
}, {
test: /.scss$/,
include: path.resolve(__dirname, 'src/styles'),
loader: 'style!css!sass?sourceMap=true'
}]
}
/* src/app.js */
import './styles/app.scss';
import Component from './view/Component'

/* src/views/Component.js */
// 以下为组件相关样式
import './Component.scss';

  • 嵌套支持的不够好,建议不使用嵌套
  • 若某个类名对应的css代码为空,则该类名不会写到html的class中

相关文章

网友评论

      本文标题:CSS-Modules

      本文链接:https://www.haomeiwen.com/subject/mwpirftx.html