CSS Modules使用方法

css modules调研

css模块化解决方案

  • 抛弃css (Radium,jsxstyle,react-style)
  • 利用js来管理样式依赖(css Modules)

css模块化面临的问题

  • 全局污染
  • 命名混乱
  • 依赖管理不彻底
  • 无法共享变量
  • 代码压缩不彻底

启用CSS Modules,webpack配置

...
{
    test: /\.css$/,
    use: [
        {
            loader: 'style-loader'
        },
        {
            loader: 'css-loader?modules&localIdentName=[name]-[hash:base64:5]'
        }
    ]
},
...

在项目当中使用

Test.jsx

import React, { Component } from 'react';
// 将样式文件当成模块引入
import styles from "./test.css";


export default class Test extends Component {
    render() {
        return (
            <div>
                <div className={styles.test}>测试</div>
            </div>
        )
    }
}

test.css

.test {
    color: red;
}

以上就是CSS Modules的基本用法

用法进阶

全局样式和局部样式

开启CSS Modules之后默认的样式都为局部样式

// css 样式
(:global)(.test1) {
    color: blue;
}
或者如下(定义多个全局样式)
:global {
    .test1 {
        color: blue;
    }
    .test2 {
        color: red;
    }
}

// 全局样式写法和之前一样
import React, { Component } from 'react';
import styles from "./test.css";
export default class Test extends Component {
    render() {
        return (
            <div>
                <div className="test1">测试</div>
            </div>
        )
    }
}

Compose 组合样式

// 样式文件
.base { 
    font-size: 20px;
 }

.normal {
  composes: base;
  color: #333;
}

.disabled {
  composes: base;
  color: #ddd;
}
// 组件中
import React, { Component } from 'react';
import styles from "./test.css";
export default class Test extends Component {
    render() {
        return (
            <div>
                <div className="normal">测试</div>
            </div>
        )
    }
}
// 编译后的html文件
<d class="div--base-daf62 div--normal-abc53">测试</div>
// 由于在 .normal 中 composes 了 .base,编译后会 normal 会变成两个 class。

CSS Modules 使用技巧

  • 不使用选择器,只使用class名来定义样式
  • 不叠加多个class
  • 所有样式通过composes组合来实现复用
  • 不嵌套

CSS Modules React 项目实践

import classNames from 'classnames';
import styles from './dialog.css';

export default class Dialog extends React.Component {
  render() {
    const cx = classNames({
      [styles.confirm]: !this.state.disabled,
      [styles.disabledConfirm]: this.state.disabled
    });

    return <div className={styles.root}>
      <a className={cx}>Confirm</a>
      ...
    </div>
  }
}

关于样式覆盖问题

因为CSS Modules 不会覆盖属性选择器,所以可以利用属性选择器来解决这个问题

// 组件中
...
return (
    <div data-role='test'>
        测试
    </div>
)
...
// 样式
[data-role="test"] {
    color: red;
}

如何与全局样式共存

import Component from './view/Component'
// 全局样式
import './styles/app.scss';
// 以下为组件相关样式(局部样式)
import './Component.scss';

SASS与CSS Modules配合使用

module: {
  loaders: [{
    test: /\.jsx?$/,
    loader: 'babel'
  }, {
    test: /\.scss$/,
    exclude: path.resolve(__dirname, 'src/styles'),
    loader: 'style-loader!css-loader?modules&localIdentName=[name]__[local]!sass?sourceMap=true'
  }, {
    test: /\.scss$/,
    include: path.resolve(__dirname, 'src/styles'),
    loader: 'style-loader!css-loader!sass-loader?sourceMap=true'
  }]
}
posted @ 2017-11-24 09:31  无情码字员  阅读(19860)  评论(0编辑  收藏  举报