CSS Modules - CSS模块化

这篇具有很好参考价值的文章主要介绍了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值
    css模块化,# CSS,css,webpack,javascript
    由于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模块化,# CSS,css,webpack,javascript

语法

参考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,结果如下:
css模块化,# CSS,css,webpack,javascript

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)文章来源地址https://www.toymoban.com/news/detail-744779.html

到了这里,关于CSS Modules - CSS模块化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 20230728----重返学习-跨域-模块化-webpack初步

    跨域 为什么要跨域? 浏览器为了安全,不能让我们的html文件可以随意引用别的服务器中的文件,只允许我们的html或js文件中,请求我们自己服务器。这个就是浏览器的同源策略。 因为我们的网页是一个html文件,这个html是在一个域名里的。而这个html会引用各种文件,如图片

    2024年02月15日
    浏览(48)
  • vue - vuex详细讲解和modules模块化的使用

    vuex 简介 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 通俗的来说,vuex是用于当某一状态需要在多个组件中共享,方便我们使用并追踪这些状态时使用。 1,vuex的

    2024年02月06日
    浏览(43)
  • 网页爬虫之WebPack模块化解密(JS逆向)

    WebPack打包: webpack是一个基于模块化的打包(构建)工具, 它把一切都视作模块。 概念: webpack是 JavaScript 应用程序的模块打包器,可以把开发中的所有资源(图片、js文件、css文件等)都看成模块,通过loader(加载器)和plugins(插件)对资源进行处理,打包成符合生产环境部署

    2024年02月02日
    浏览(46)
  • ES6之Promise、Class类与模块化(Modules)

    Promise 是 ES6 引入的一种用于 处理异步操作 的对象。 它解决了传统回调函数(callback)模式中容易出现的 回调地狱 和代码可读性差的问题。 Promise 对象有三种状态: Pending (进行中): 初始化状态,表示异步操作还在进行中。 Fulfilled (已成功): 表示异步操作执行成功,并

    2024年02月10日
    浏览(48)
  • JavaScript模块化

    JavaScript模块化,让我们通过一个实际的例子来更好地理解。 假设我们正在开发一个简单的购物车应用,需要实现计算商品总价和展示购物车列表的功能。我们可以将这个应用划分为两个模块:`cart.js`和`main.js`。 1. cart.js模块: ```javascript // cart.js // 定义一个私有变量,用于存

    2024年02月14日
    浏览(57)
  • JavaScript中的模块化编程

    JavaScript是一种强大的编程语言,它可以在浏览器中进行客户端脚本编写,并且在服务器端也有广泛的应用。随着JavaScript应用的增多,JavaScript代码的复杂度也不断增加。为了提高代码的可维护性和重用性,模块化编程变得越来越重要。本文将讨论JavaScript中的模块化编程,包括

    2024年02月02日
    浏览(65)
  • 深入理解JavaScript模块化开发

    前言: 随着JavaScript应用程序的复杂性不断增加,模块化开发成为了一种必备的技术。通过将代码划分为模块,我们可以提高代码的可维护性、可重用性和可扩展性。在本文中,我们将深入探讨JavaScript模块化开发的概念、优势和不同的模块化方案。 模块化开发是将一个大型应

    2024年02月08日
    浏览(92)
  • JavaScript:模块化【CommonJS与ES6】

    在 JavaScript 编程中,随着项目的复杂性增加,代码的组织和管理变得至关重要。模块化是一种强大的编程概念,它允许我们将代码划分为独立的模块,提高了可维护性和可扩展性。本文将详细介绍 CommonJS 和 ES6 模块,帮助你理解它们的特点和用法。 1. CommonJS 模块化 CommonJS 是

    2024年02月13日
    浏览(54)
  • 前端10年进化 Node.js、模块化、CommonJS、AMD、CMD、Webpack、Vue-cli、Electron-vue

    模块化的概念在软件开发领域已经存在很长时间,但在 JavaScript 中的模块化发展相对较晚。以下是对您提出的问题的回答: 提出时间:JavaScript 中的模块化概念相对较早地提出于 CommonJS 规范。CommonJS 是一种 JavaScript 模块化规范,最早在 2009 年由 Ryan Dahl 和其他社区成

    2024年02月11日
    浏览(79)
  • 什么是模块化?为什么要进行模块化开发?

    模块化是一种软件开发的设计模式,它将一个大型的软件系统划分成多个独立的模块,每个模块都有自己的功能和接口,并且能够与其他模块独立地工作。  先来一段八股文 模块化开发可以带来以下好处: 提高代码的复用性:模块化可以将代码划分成可重用的部分,降低代

    2023年04月12日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包