CSS Modules - CSS模块化

参考文章:
CSS Modules 用法教程-阮一峰
css module
css模块化及CSS Modules使用详解

背景-CSS 模块化

CSS 模块化的解决方案有很多,但主要有两类:
一类是彻底抛弃 CSS,使用 JS 或 JSON 来写样式。Radium,jsxstyle,react-style 属于这一类。

  • 优点是能给 CSS 提供 JS 同样强大的模块化能力;
  • 缺点是不能利用成熟的 CSS 预处理器(或后处理器) Sass/Less/PostCSS,:hover 和 :active 伪类处理起来复杂。

另一类是依旧使用 CSS但使用 JS 来管理样式依赖,代表是 CSS Modules。

  • CSS Modules 能最大化地结合现有 CSS 生态和 JS 模块化能力,API 简洁到几乎零学习成本。
  • 发布时依旧编译出单独的 JS和 CSS。
  • 它并不依赖于 React,只要你使用 Webpack,可以在 Vue/Angular/jQuery 中使用。
  • 是我认为目前最好的CSS 模块化解决方案

前言

CSS Modules 提供各种插件,支持不同的构建工具。
本文使用的是 Webpackcss-loader插件,因为它对 CSS Modules 的支持最好,而且很容易使用。

为什么需要CSS Modules

解决类名冲突问题
CSS的规则都是全局的,任何一个组件的样式规则,都对整个页面有效。因此,为了使用独特的样式,要保证元素的类名不冲突。这对于大型项目而言是很难的。
CSS Modules的思路:
产生一个独一无二的class的名字,不会与其他选择器重名

实现原理

  1. 开启了css module后,构建工具webpack的css-loader会将样式中的类名进行转换,转换为一个唯一的hash值
    在这里插入图片描述
    由于hash值是根据模块路径和类名生成的,因此,不同的css模块,哪怕具有相同的类名,转换后的hash值也不一样。

  2. 根据导出结果可知,我们就可以在js代码中获取到css模块导出的结果,从而应用类名

// src/index.js
import style from  "./assets/style.css"
console.log(style)
const div = document.getElementById("div1");
div.className = style.c1;

打印结果如下:
在这里插入图片描述

语法

参考CSS Modules 用法教程-阮一峰

0.配置

webpack.config.js文件如下:

module.exports = {
  entry: __dirname + '/index.js',
  output: {
    publicPath: '/',
    filename: './bundle.js'
  },
  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        loader: 'babel',
        query: {
          presets: ['es2015', 'stage-0', 'react']
        }
      },
      {
        test: /\.css$/,
        loader: "style-loader!css-loader?modules"
      },
    ]
  }
};

关键的一行是style-loader!css-loader?modules,它在css-loader后面加了一个查询参数modules,表示打开 CSS Modules 功能。

0.1初始代码

App.css:

.title {
  color: red;
}

React组件App.js:

import React from 'react';
import style from './App.css';

export default () => {
  return (
    <h1 className={style.title}>
      Hello World
    </h1>
  );
};

1. 局部作用域

使用了 CSS Modules 后,样式默认局部
相当于给每个 class 名外加加了一个 :local,以此来实现样式的局部化

.normal {
  color: green;
}

/* 以上与下面等价 */
:local(.normal) {
  color: green; 
}

同上。h1标题会显示为红色

2.全局作用域

CSS Modules 允许使用**:global(.className)**的语法,声明一个全局规则。
凡是这样声明的class,都不会被编译成哈希字符串。
e.g.
App.css加入一个全局class:

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

App.js使用普通的class的写法:

import React from 'react';
import styles from './App.css';

export default () => {
  return (
    <h1 className="title">
      Hello World
    </h1>
  );
};

h1标题显示为绿色。

CSS Modules 还提供一种显式的局部作用域语法:local(.className),等同于.className,所以上面的App.css也可以写成下面这样:

:local(.title) {
  color: red;
}

:global(.title) {
  color: green;
}

3.定制哈希类名

css-loader默认的哈希算法是[hash:base64],这会将.title编译成._3zyde4l1yATCOkgn-DBWEL这样的字符串。

webpack.config.js里面可以定制哈希字符串的格式:

module: {
  loaders: [
    // ...
    {
      test: /\.css$/,
      loader: "style-loader!css-loader?modules&localIdentName=[path][name]---[local]---[hash:base64:5]"
    },
  ]
}

你会发现.title被编译成了demo03-components-App---title---GpMto

4.Class的组合

在 CSS Modules 中,一个选择器可以继承另一个选择器的规则,这称为"组合"(“composition”)
在App.css中,让.title继承.className

.className {
  background-color: blue;
}

.title {
  composes: className;
  color: red;
}

运行,会看到红色的h1在蓝色的背景上。

打印App.js中导入的style,结果如下:
在这里插入图片描述

5.输入其他模块

选择器也可以继承其他CSS文件里面的规则
e.g. another.css文件

.className {
  background-color: blue;
}

App.css继承another.css里面的规则

.title {
  composes: className from './another.css';
  color: red;
}

蓝色的背景上有一个红色的h1(相当于class的组合,只不过来自另一个文件)

6.输入变量

CSS Modules 支持使用变量,不过需要安装 PostCSS 和 postcss-modules-values

  1. 把postcss-loader加入webpack.config.js:

var values = require('postcss-modules-values');

module.exports = {
  entry: __dirname + '/index.js',
  output: {
    publicPath: '/',
    filename: './bundle.js'
  },
  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        loader: 'babel',
        query: {
          presets: ['es2015', 'stage-0', 'react']
        }
      },
      {
        test: /\.css$/,
        loader: "style-loader!css-loader?modules!postcss-loader"
      },
    ]
  },
  postcss: [
    values
  ]
};
  1. 在colors.css里面定义变量
@value blue: #0c77f8;
@value red: #ff0000;
@value green: #aaf200;
  1. App.css可以引用这些变量
@value colors: "./colors.css";
@value blue, red, green from colors;

.title {
  color: red;
  background-color: blue;
}

会看到蓝色的背景上有一个红色的h1

项目使用

一般的脚手架都默认集成了 CSS Modules,比如 React 官方的脚手架create-react-app,已经将 CSS Modules 集成进来了,可以直接使用。
我有个问题,蚂蚁的前端脚手架Ant Design Pro是基于react的,这是不是意味着它默认也集成了 CSS Modules。(当然,它的确是集成了的,只是,是不是基于react的脚手架也都默认集成了CSS Modules)

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要在 Vite 中使用 PostCSS Modules,你需要执行以下步骤: 1. 安装 `postcss-modules` 插件: ```bash npm install postcss-modules --save-dev ``` 2. 在 `vite.config.js` 中配置 PostCSS: ```javascript import vue from '@vitejs/plugin-vue' import postcssModules from 'postcss-modules' export default { plugins: [ vue(), ], css: { postcss: { plugins: [ postcssModules({ generateScopedName: '[name]__[local]___[hash:base64:5]', }), ], }, }, } ``` 在上面的配置中,我们使用 `postcss-modules` 插件并设置 `generateScopedName` 选项以生成唯一的 CSS 类名。 3. 在 Vue 组件中使用 CSS Modules: ```vue <template> <div :class="$style.title">Hello world!</div> </template> <style module> .title { font-size: 24px; color: red; } </style> ``` 在上面的示例中,我们使用 `module` 属性启用了 CSS Modules,并使用 `$style` 对象来引用生成的唯一类名。 注意,如果你使用的是 Vue 3,你需要使用 `@vue/compiler-sfc` 版本 `^3.0.0-0` 或更高版本,并在 `vue.config.js` 中设置 `compilerOptions` 选项: ```javascript module.exports = { ... compilerOptions: { moduleIds: 'module', ... }, } ``` ### 回答2: vite是一个快速的Web开发工具,它提供了许多配置选项来满足不同项目的需求。其中之一是配置postcss-modules。 PostCSS是一个用于对CSS进行处理的工具,它可以通过插件来实现不同的功能,例如自动添加浏览器前缀、转换CSS变量等。而postcss-modules则是其中的一个插件,它可以让我们在编写CSS时使用类似于JavaScript模块的方式来管理样式。 在vite项目中配置postcss-modules需要以下几个步骤: 1. 首先,安装postcss-modules和postcss插件。可以使用npm或者yarn来安装。 ```shell npm install postcss-modules postcss --save ``` 2. 在项目的根目录下创建一个postcss.config.js文件,在该文件中进行postcss-modules的配置。 ```javascript module.exports = { plugins: [ require('postcss-modules')({ // 配置postcss-modules的选项 // 这里可以配置一些自定义的CSS类名生成规则等 }), // 其他的postcss插件可以在这里添加 ], }; ``` 3. 在vite的配置文件vite.config.js中引入postcss插件,并将postcss-modules添加到它的插件数组中。 ```javascript import { defineConfig } from 'vite'; import postcss from 'rollup-plugin-postcss'; export default defineConfig({ plugins: [ postcss(), // 其他的插件可以在这里添加 ], }); ``` 这样就完成了vite项目中postcss-modules的配置。接下来,我们可以在编写CSS样式时使用类似于JavaScript模块的导入和导出语法来管理样式。 总结:通过在vite项目中进行postcss-modules的配置,我们可以使用类似于JavaScript模块的方式来管理样式。这样可以提高样式的可读性和维护性,并且可以避免全局命名空间的冲突问题。 ### 回答3: vite配置postcss-modules可以通过以下步骤实现: 1. 首先,确认你已经在项目中安装了vite。如果没有安装,可以在命令行中运行以下命令进行安装: ``` npm install -g create-vite ``` 2. 创建一个新的vite项目。在命令行中运行以下命令: ``` create-vite my-project ``` 这将创建一个名为`my-project`的新文件夹,并在其中初始化一个新的vite项目。 3. 进入新创建的项目文件夹。在命令行中运行以下命令: ``` cd my-project ``` 4. 安装postcss-modules。在命令行中运行以下命令: ``` npm install postcss-modules ``` 5. 打开vite配置文件`vite.config.js`,并添加postcss-modules的配置。可以使用ES模块的方式导入postcss-modules,并在`css`插件中进行配置。示例代码如下所示: ```js import { defineConfig } from 'vite'; import postcssModules from 'postcss-modules'; export default defineConfig({ plugins: [ // ... postcss({ plugins: [ postcssModules({ generateScopedName: '[name]__[local]--[hash:base64:5]' }) ] }) ] }); ``` 在上面的配置中,`generateScopedName`属性用于定义生成CSS作用域的名称。你可以根据自己的需求进行调整。 6. 保存并关闭`vite.config.js`文件。重新启动项目(如果已经启动的话),以使配置生效。 完成以上步骤后,你的vite项目就已经成功配置了postcss-modules。现在,你可以在项目中使用postcss-modules来管理CSS模块和样式作用域了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值