Date: January 30, 2025
CSS
先介绍下普通 CSS,再简明介绍下 css module 的使用
普通 CSS
内联 style
定义:
- 内联
style
是通过在元素的style
属性中直接设置 CSS 样式。 - 这种方式允许我们直接在 JSX 中为组件或元素添加样式。
写法:
<div style={{ color: 'red', fontSize: '20px' }}>This is a red text with font size 20px.
</div>
className
定义:
className
是通过 CSS 类为元素设置样式。在 React 中,使用className
替代传统的class
属性。className
通过引用外部样式表来定义样式,适合复用和组织大规模的样式。
写法:
<div className="red-text large-text">This is a styled text.
</div>
CSS Module
概念:
CSS Module 是一种局部作用域的CSS方案,它通过将CSS类名局部化,避免了全局命名冲突的问题。每个CSS类都默认是局部的,只有在特定的组件中才有效。
特点:
- 局部作用域:每个CSS类都只作用于当前组件,避免了全局样式污染。
- 自动命名:CSS类名会自动生成一个唯一的标识符,以确保类名不重复。
- 与组件绑定:CSS模块与React(或其他框架)中的组件紧密绑定,每个组件都有独立的样式。
工作原理:
CSS文件中的类名会被编译器处理成唯一的类名(例如:Button__primary__1k2jd
),这个类名与组件的作用域绑定,避免了全局命名冲突。
使用方式:
-
创建一个
.module.css
的CSS文件:css">/* Button.module.css */ .primary {color: red;background-color: blue; }
-
在组件中导入并使用:
import styles from './Button.module.css';function Button() {return <button className={styles.primary}>Click me</button>; }
-
自动生成的类名:
styles.primary
实际上会被编译成一个唯一的类名,如Button_primary__1k2jd
。
特点:
优点:
- 避免类名冲突:每个组件的样式是局部的,不会与其他组件的样式发生冲突。
- 模块化管理:样式与组件紧密绑定,便于管理和维护。
缺点:
- 不能全局复用:样式是局部的,如果需要全局样式,则需要使用全局CSS或CSS变量。
- 需要构建工具支持:如Webpack配置支持CSS Module(通过
css-loader
等)。
安装与配置
webpack配置 css-module
如果你正在使用 Webpack,需要安装 css-loader
和 style-loader
:
npm install css-loader style-loader --save-dev
在 webpack.config.js
中配置 CSS Module:
module.exports = {module: {rules: [{test: /\\.module\\.css$/, // 只针对带有 .module.css 的文件use: ['style-loader', 'css-loader?modules'] // 启用 CSS Module}]}
};
创建 CSS Module 文件
创建一个带有 .module.css
扩展名的 CSS 文件。注意,.module.css
表示这个文件是一个 CSS Module 文件。
css">/* Button.module.css */
.button {background-color: blue;color: white;padding: 10px;border-radius: 5px;
}.buttonHover {background-color: darkblue;
}
具体使用
导入和使用 CSS Module:
在组件中导入 CSS Module 文件,并应用类名。CSS类名将会被本地化,避免全局污染。
// Button.jsx
import React from 'react';
import styles from './Button.module.css'; // 导入CSS Moduleconst Button = () => {return (<button className={styles.button}>Click Me</button> // 使用样式);
};export default Button;
生成的类名:
CSS Module 在编译时会为每个类名生成唯一的哈希值。例如,button
类可能会变成 Button_button__1a2b3
,从而保证不会与其他组件的样式产生冲突。
<button className="Button_button__1a2b3">Click Me</button>
高级用法
动态类名
CSS Module 可以和 JavaScript 动态交互,允许根据状态或条件动态设置类名。
import React, { useState } from 'react';
import styles from './Button.module.css';const Button = () => {const [isHovered, setIsHovered] = useState(false);return (<buttonclassName={isHovered ? styles.buttonHover : styles.button}onMouseEnter={() => setIsHovered(true)}onMouseLeave={() => setIsHovered(false)}>Hover Over Me</button>);
};export default Button;
合并多个类名:
有时你可能需要将多个类名结合起来,可以使用 JavaScript 的 classnames
库(或者其他库)来处理这种情况。
npm install classnames
import React from 'react';
import classNames from 'classnames';
import styles from './Button.module.css';const Button = ({ isPrimary, isDisabled }) => {const buttonClass = classNames(styles.button, {[styles.primary]: isPrimary,[styles.disabled]: isDisabled,});return <button className={buttonClass}>Click Me</button>;
};export default Button;
样式组合:
CSS Module 中可以引入其他 CSS 文件,避免代码重复。在 CSS Module 中也可以使用 composes
关键字来合并其他类。
css">/* BaseButton.module.css */
.baseButton {padding: 10px;font-size: 16px;border: none;
}.primary {composes: baseButton from './BaseButton.module.css';background-color: blue;color: white;
}.secondary {composes: baseButton from './BaseButton.module.css';background-color: gray;color: black;
}
处理全局样式
CSS Module 默认样式是局部的,但有时你可能希望某些样式是全局的,可以使用 :global
来标记全局样式。
css">/* Global.module.css */
:global .global-class {color: red;
}
// App.jsx
import './Global.module.css';function App() {return <div className="global-class">This is a global style</div>;
}
总结:
- CSS Module 通过将每个 CSS 类的作用域限制在组件内部,避免了全局样式的污染。
- 它支持动态类名、样式组合以及通过
composes
关键字复用样式。 - 适用于大型应用中的样式管理,尤其在组件化的开发中能大大提高维护性和可扩展性。
- 对于全局样式需求,可以通过
:global
来解决。