在React项目中使用 CSS Module

简介: 在React项目中使用 CSS Module

穷尽一生,一事无成是常态,更是这个世界上99%的人真实写照

大家好,我是柒八九

前言

就在前几天,写了一篇CSS 20大酷刑,然后看后台数据,反馈还是挺好的,看来大家还是对这个最熟悉的陌生人,有种食之无味,弃之可惜的感觉。在上篇中,我们就说过,由于CSS庞杂的体系和令人眼花缭乱的属性,总是让人望而却步。但是,它也是我们翻身农奴做主人,势必要翻过的四座大山之一 CSS/Html/JavaScript/WebAsssembly。(自认为,WebAssembly也会成为一座我们需要逾越的大山,有关它的介绍,可以看我们之前写的浏览器第四种语言-WebAssembly)

而,今天我们讲点轻松的东西,内容有点少,可以在茶余饭后,当个配菜来品尝

React中,CSS模块(CSS Module)只是一个.css文件,类似于JavaScript中的局部变量。它减少了React样式的全局作用域。此外,它是一种通过生成一个随机字符串作为className名称并添加一个唯一的哈希来使每个className都唯一的工具,从而防止和全局作用域冲突。我们可以使用CSS模块来防止CSS类的命名冲突。只需将CSS模块文件导入到我们的组件中,就可以在各种CSS文件中使用相同的CSS类

任何CSS文件都可以安全地更新,而无需担心会影响其他页面,因为它只具有局部作用域,只能影响使用了更改后的CSS模块文件的其他组件。当使用CSS模块在浏览器中呈现时,它会生成随机的CSS类,只有在仔细检查页面时才可见。

你能所学到的知识点

  1. 前置知识点
  2. CSS模块的红与黑
  3. CSS模块使用语法
  4. 创建一下CSS模块
  5. 在React中使用 CSS 模块
  6. 全局 CSS

好了,天不早了,干点正事哇。



1. 前置知识点

前置知识点,只是做一个概念的介绍,不会做深度解释。因为,这些概念在下面文章中会有出现,为了让行文更加的顺畅,所以将本该在文内的概念解释放到前面来。如果大家对这些概念熟悉,可以直接忽略

CSS-in-JS简介

CSS-in-JS 是一种前端开发方法,它将样式表达式嵌入到 JavaScript 中,以便更好地管理和组织样式。这种方法的主要思想是将组件的样式与组件本身紧密耦合在一起,以提高可维护性、可读性和复用性CSS-in-JS 有许多不同的库和工具,每个都有自己的语法和特性,但核心思想是相似的。

以下是 CSS-in-JS 的一些主要特点和优势:

  1. 组件化样式CSS-in-JS 允许我们将样式与组件一起定义,将它们封装在一起。这使得代码更具可读性,因为我们可以在组件的定义中直接查看和理解样式。
  2. 动态样式:与传统的 CSS 不同,CSS-in-JS 允许我们根据组件的状态或属性来动态生成样式。这使得样式更加灵活,能够根据应用的不同情况进行调整。
  3. 自动前缀:许多 CSS-in-JS 库会自动添加浏览器前缀,以确保样式在不同浏览器中都能正常工作。
  4. 组件级别作用域样式是组件级别的,不会与其他组件的样式冲突,从而避免全局样式表的问题。
  5. 性能优化:某些 CSS-in-JS 库会使用类似于样式提取style extraction)的技术,将样式提取为单独的 CSS 文件,以提高性能。
  6. 可维护性:将样式与组件紧密结合使得代码更易于维护,因为我们可以在同一个文件中查找组件的样式定义,而不必在多个文件之间跳转。

像比较常见的库有

由于它们的语法还有使用方式相差无几,所以我们就挑一个比较常见的库进行演示。如果想了解其它的使用方式,可以根据上面链接,直接访问其官网。

Styled Component

下面展示了如何使用 styled-components 创建一个简单的按钮组件:

首先,我们需要安装 styled-components

npm install styled-components

然后,我们可以创建一个按钮组件:

// 导入 styled-components 库
import styled from 'styled-components';
// 创建一个样式化的按钮组件
const Button = styled.button`
  background-color: #007bff;
  color: #fff;
  border: none;
  padding: 10px 20px;
  cursor: pointer;
  &:hover {
    background-color: #0056b3;
  }
`;
// 在我们的应用中使用这个按钮组件
function App() {
  return (
    <div>
      <h1>前端柒八九</h1>
      <Button onClick={() => alert('Helllo, 骚年')}>关注走一波</Button>
    </div>
  );
}
export default App;

在上面的示例中,我们导入 styled-components 库,然后使用 styled.button 创建一个按钮组件。我们使用模板字符串定义了按钮的样式,包括背景颜色、文字颜色等。&:hover 是一个伪类选择器,用于定义按钮的鼠标悬停样式。

最后,在应用中使用这个按钮组件,就像使用普通的 React 组件一样。


2. CSS模块的红与黑

优点:

  • 通过使用CSS模块,可以避免CSS类的命名空间冲突多个CSS文件可以包含相同的CSS类
  • CSS模块中,我们可以将类发送到多个组件。
  • 使用CSS模块的一个关键优点是,我们可以放心地编辑任何CSS文件,而不必担心它会影响其他模块。
  • 使用CSS模块创建可移植可重用的CSS文件。不再需要担心规则会影响其他组件的样式或选择器名称冲突。
  • 尽管项目复杂,但CSS模块可以使我们的代码看起来整洁,以便其他开发人员可以阅读和理解它。

缺点:

  • 在将样式集成到项目中时,必须将样式包含为带有点号方括号表示法的对象。
  • Styled Components不同,CSS模块不接受props

那么,为什么要使用CSS模块呢?

  • 在使用CSS模块时,我们可以确保给定组件的每个样式都位于一个位置,并且仅适用于导入它的组件。
  • 借助CSS模块和默认的局部作用域概念,可以避免全局作用域的问题。
  • 在编写样式时,我们总是怕和别人起了相同的类名影响现有的业务,总是畏首畏尾,战战兢兢的编写自己的样式代码。

3. CSS模块使用语法

现在属于SPA的天下,那在使用框架时候就绕不开,模块化构建工具(如WebpackviteRspack)来管理样式。

下面我们简单分别介绍一下,它们对CSS模块的支持程度。

当我们安装create-React-app时,React会为我们处理一切;因此,我们目前不需要为Webpack配置CSS模块

在使用CSS模块时,不需要额外的代码或添加到CSS模块的第三方代码。我们只需要将CSS文件的名称更改为[文件名].Modules.css;我们可以用任何其他名称替代[文件名]。在使用CSS模块时,我们必须使用import关键字将文件导入到特定组件中。在将CSS模块集成到我们的React项目中时,我们必须指定类,就像在标准JavaScript中使用点符号或方括号语法访问对象的属性一样

使用点符号表示法:

<div className={classes.parent_div}></div>

如果我们的CSS类包含连字符,应使用方括号表示法

<div className={classes["parent-div"]}></div>

我们可以组合样式:

const buttonClasses = classes.myBtn + " " + classes.extra_classes;

这些是纯粹的普通JavaScript对象的基本概念。

Vite天然支持CSS模块

image.png

Rspack也天然支持CSS模块

image.png


4. 创建一下CSS模块

Styled ComponentEmotionstyled-jsx等CSS库现在都广泛使用。但是,我认为CSS模块是会在未来大放异彩,特别是全局范围可重用性,这使得我们以后写样式时,不用如履薄冰。CSS模块越来越广泛地用于在特定组件中本地描述样式并避免全局作用域。

让我们从一个简单的项目开始。我们将创建一个[文件名].module.css文件。我们将导入我们的[文件名].module.css的组件如下所示。

TypeScript用户必须添加一个.d.ts文件;在这种情况下,我们将创建[文件名].module.css.d.ts”。

// [fileName].module.css.d.ts
export const styles: string;
export const someStyles: string;
export const moreStyles: string;

这个文件定义了一些CSS模块中的样式类,可以在组件中使用。

[fileName].module.css的内容如下所示:

.container {
    width: 500px;
    padding: 20px;
    background-color: white;
    box-shadow: 17px 18px 10px #767676;
    text-align: center;
    line-height: 3;
    margin: 20px;
}
.border_radius {
    border-radius: 40px;
}
.counter-title {
    color: cornflowerblue;
    font-family: cursive;
    font-weight: bolder;
}
.container button {
    background-color: cornflowerblue;
    padding: 15px 20px;
    border-radius: 10px;
    color: white;
    border: none;
    outline: none;
}

要将CSS模块的样式表导入到组件中,最好在[classes][styles]前缀下导入它。样式或类的前缀并不是强制性的,但我们将使用类以符合最佳实践。要使用样式,请确保路径包含./[fileName].module.css对应的文件。

import classes from "./Styles.module.css";

5. 在React中使用 CSS 模块

在使用CSS 模块时,可以将样式写在CSS文件中,然后使用上面所示的点号方括号表示法来引用导入的CSS模块。在下面的代码中,我们演示了如何在React组件中利用CSS Modules

函数组件

在React函数组件中,我们将使用CSS Modules。下面的代码增加了计数器的值并使用useState在将要创建的FunctionCounter.js组件中。

import React, { useState } from "react";
import classes from "./Styles.module.css";
const FunctionCounter = () => {
    const [counter, setCounter] = useState(0);
    const handleClick = () => {
        setCounter(counter + 2);
    };
    return (
      <>
        <div className={classes.container}>
            <p className={classes["paragraph-text"]}>前端柒八九</p>
            <h2 className={classes["counter-title"]}>{counter}</h2>
            <button onClick={handleClick}>数字加2</button>
        </div>
      </>
    );
};
export default FunctionCounter;

这个组件使用了从CSS模块导入的样式类,并且在点击按钮时会增加计数器的值。这样,我们可以在React函数组件中利用CSS模块来管理样式。

类组件

我们将看到一个使用CSS模块的类组件。我们将创建一个名为ClassCounter.js的Class组件。下面的代码会将计数值增加2。

import React from "react";
import classes from "./Styles.module.css";
class ClassCounter extends React.Component {
    constructor() {
        super();
        this.state = { counter: 0 };
        // 这个绑定是必要的,以使`this`在回调中正常工作
        this.handleClick = this.handleClick.bind(this);
    }
    handleClick = () => {
        this.setState({
            counter: this.state.counter + 1,
        });
    };
    render() {
        return (
            <div className={`${classes.container} ${classes.border_radius}`}>
                <p className={classes["paragraph-text"]}>前端柒八九</p>
                <h2 className={classes["counter-title"]}>{this.state.counter}</h2>
                <button onClick={this.handleClick}>数字加1</button>
            </div>
        );
    }
}
export default ClassCounter;

最后,让我们看一下App.js组件。我们将在App.js组件中导入FunctionCounter.jsClassCounter.js组件。

import React from "react";
import ClassCounter from "./ClassCounter";
import FunctionCounter from "./FunctionCounter";
const App = () => {
    return (
        <div>
            <FunctionCounter />
            <br />
            <ClassCounter />
        </div>
    );
};
export default App;

以下是我们的CSS模块中的ClassFunction组件的输出。

image.png

并且我们在浏览器中进行元素审查时,可以看到指定元素中的class使用从CSS模块获取的哈希值。


6. 全局 CSS

CSS模块并不禁止使用全局CSS。我们可以使用与导入ES6相同的方法导入样式表。

import './App.css'

此外,我们可以使用关键字global来更改类的范围,以防止CSS模块修改它。

:global(.class) {
    color:red;
}
:global .button {}

以下是上面代码的解释:

  1. :global(.class):这是一个CSS Modules中的语法,:global 告诉CSS模块不要将此类名限制在模块范围内,而是将其视为全局CSS类名。这意味着任何地方都可以使用 .class 类名,而不受模块化的限制。
/* 在CSS模块中 */
.class {
  color:red;
}
  1. 在这里,.class 类名的样式会在整个应用程序中全局生效。
  2. :global .button:这也是使用:global将样式声明为全局的示例。.button 类名可以在整个应用程序中任何地方使用,不受模块化的限制。
/* 在CSS模块中 */
.button {
  /* 样式规则 */
}
  1. 在这里,.button 类名的样式也会在整个应用程序中全局生效。

需要注意的是,:global 是一种逃逸机制,用于在CSS模块中定义全局样式。通常情况下,CSS Modules的目标是将样式局部化,以避免全局污染和冲突。但有些情况下,我们可能需要使用全局样式,这时可以使用:global


7. 多个 CSS模块混合使用

CSS模块不限制使用多个类;我们可以按照以下方式使用CSS模块来添加多个类:

<div className={`${classes.container} ${classes.border_radius}`}></div>
function Footer( props) {
    return (
        <div className={styles.section}>
            <div className={`${styles.description} ${styles.black}`}>
                <p>CSS模块的使用说明</p>
            </div>
        </div>
    );
}

8. 伪类选择器

伪类选择器用于选择处于特定状态的元素。由于CSS模块通过为我们的元素添加类来工作,因此添加伪类选择器非常简单。

// Button.module.css
.button:hover {background-color;: }
.button:disabled {color: #ddd}
.button:active {color: grau}
//============
import classes from "./Button.module.css";
import React, { Component } from "react";
export default class Text extends Component {
    render() {
    return <button className={classes.button}>关注我,给你一个不一样的技术分享</button>;
    }
}

后记

分享是一种态度

参考资料:

  1. Styled Component
  2. Emotion
  3. css-modules
  4. vite-css-module
  5. rspack-css-module

全文完,既然看到这里了,如果觉得不错,随手点个赞和“在看”吧。

相关文章
|
2天前
|
前端开发 JavaScript 开发者
【专栏:HTML与CSS前端技术趋势篇】前端框架(React/Vue/Angular)与HTML/CSS的结合使用
【4月更文挑战第30天】前端框架React、Vue和Angular助力UI开发,通过组件化、状态管理和虚拟DOM提升效率。这些框架与HTML/CSS结合,使用模板语法、样式管理及组件化思想。未来趋势包括框架简化、Web组件标准采用和CSS在框架中角色的演变。开发者需紧跟技术发展,掌握新工具,提升开发效能。
|
2天前
|
前端开发 UED
【专栏:HTML与CSS实战项目篇】创建一个具有复杂布局的电商详情页
【4月更文挑战第30天】构建复杂布局的电商详情页涉及页面结构规划、样式设计和交互效果实现。首先规划顶部导航栏、商品图片展示区、商品信息区、用户评价区和相关商品推荐区。在样式设计上,注重色彩搭配、字体选择、布局与间距及图片处理。交互效果包括图片放大、添加到购物车按钮、滚动监听和评论互动,以提升用户体验。实际开发中需考虑跨设备兼容性和用户体验优化。
|
2天前
|
移动开发 前端开发 JavaScript
【专栏:HTML与CSS实战项目篇】使用HTML5与CSS3制作一个动态表单验证页面
【4月更文挑战第30天】本文介绍了使用HTML5和CSS3创建动态表单验证页面的方法。首先,简述HTML5用于构建网页内容,CSS3用于描述样式。接着,分四步展示实现过程:1) 设计包含输入框和提示信息的表单结构;2) 使用CSS3创建样式,增强视觉效果;3) 使用JavaScript监听输入事件,动态验证表单并显示错误信息;4) 测试和调试确保跨平台兼容性。通过学习,开发者能掌握创建带验证功能的表单,提升用户体验。
|
2天前
|
编解码 前端开发 JavaScript
【专栏:HTML与CSS实战项目篇】打造一个动态新闻网站
【4月更文挑战第30天】构建动态新闻网站,运用HTML和CSS提升编程技能和网页设计理解。项目包括首页、新闻列表页和详情页,设计简洁易用,包含顶部导航、轮播图和新闻列表。页面布局注重吸引力和易用性,色彩搭配选用冷色调为主,辅以亮色点缀。字体选择清晰易读,布局保持整洁。交互效果如轮播图、导航栏高亮和响应式设计增强用户体验。本文提供基础新闻网站构建指南,为进一步功能扩展和优化打下基础。
|
2天前
|
前端开发 JavaScript 安全
【亮剑】如何在 React TypeScript 中将 CSS 样式作为道具传递?
【4月更文挑战第30天】本文探讨了在React TypeScript应用中如何通过道具(props)传递CSS样式,以实现模块化、主题化和动态样式。文章分为三部分:首先解释了样式传递的必要性,包括模块化、主题化和动态样式以及TypeScript集成。接着介绍了内联样式的基本用法和最佳实践,展示了一个使用内联样式自定义按钮颜色的例子。最后,讨论了使用CSS模块和TypeScript接口处理复杂样式的方案,强调了它们在组织和重用样式方面的优势。结合TypeScript,确保了样式的正确性和可维护性,为开发者提供了灵活的样式管理策略。
|
3天前
|
前端开发
【专栏】create-react-app 如何使用 less/sass 和 react-css-modules?
【4月更文挑战第29天】本文介绍了在 create-react-app 中集成 less/sass 预处理器和 react-css-modules 的方法。首先,通过 `npm` 安装 less 或 sass 依赖,然后修改 `config-overrides.js` 配置文件以支持 less/sass 编译。接着,详细阐述如何使用 less/sass 编写样式。再者,安装 react-css-modules 并配置 webpack,使能样式模块化。最后,展示了如何结合使用 less/sass 和 react-css-modules,以提升前端开发的效率和代码质量。
|
20天前
|
资源调度 前端开发 JavaScript
Tailwind CSS如何在vue项目中使用
Tailwind CSS如何在vue项目中使用
38 8
|
2月前
|
运维 JavaScript 前端开发
发现了一款宝藏学习项目,包含了Web全栈的知识体系,JS、Vue、React知识就靠它了!
发现了一款宝藏学习项目,包含了Web全栈的知识体系,JS、Vue、React知识就靠它了!
|
2月前
会员项目定价卡css3特效
会员项目定价卡css3特效
16 2
会员项目定价卡css3特效
|
2月前
|
存储 JSON 前端开发
react保姆级搭建新项目
此文主要以ts+vite+router6+antd 快速搭建一个react项目,适用于初学者,用于学习交流