css模块化的解决方案_使用CSS模块解决您的专业性难题

css模块化的解决方案

“ CSS模块”与W3C无关,而是建议的构建过程的一部分。 它会编译您的项目,重命名选择器和类,以使它们变得唯一,范围仅限于各个组件。 样式已锁定在这些组件中,除非您特别声明,否则不能在其他地方使用!

前言

如今,我们已经非常习惯于将网络技术作为应用程序背后的推动力。 网络应用,移动和桌面应用。 但是与简单的静态网站不同,应用程序通常更具动态性,复杂性,并且甚至由Bootstrap或ZURB Foundation提供的组件组成。 随着应用程序复杂性的增长,管理其CSS可能是一项艰巨的任务。

随着时间的流逝,已经开发了无数策略,例如OOCSS,ITCSS,BEM,Atomic CSS等,以保持CSS的组织性,可重用性和(关键地) 可扩展性 。 这些策略要求您和团队中的每个人都认真遵守这些约定。

但是,迟早,复杂性将再次蔓延,您将遇到如下样式规则:

html.progressive-image.js [data-progressive-image],html.progressive-image.js [data-progressive-image] * {
    background-image: none !important;
    mask-image: none !important;
    opacity: 0
}
.main #section-enhanced-gallery-heroes.homepage-section.enhanced-gallery .with-single-item {
    transform: translate(0, 0) !important
}

许多大型网站和应用程序上CSS的问题在于,要保持较低的特异性是如此困难,以至于在某种程度上,无法避免添加!important 。 而且在大型代码库上重构CSS十分棘手,因为删除样式可能会破坏其他组件。

在本教程中,我们将研究“ CSS模块”以及它如何帮助我们减少这些臭名昭著CSS问题。

注意在Github上查看仓库以获取支持的代码示例。

使用CSS模块

简而言之,“ CSS模块 ”是一种将CSS类和ID重命名为唯一选择器的工具,从而可以将样式规则本地隔离到已分配的元素或组件。 假设我们有一个按钮,通常可以如下编写其样式规则:

.button {
    background-color: #9b4dca;
    border: 0.1rem solid #9b4dca;
    border-radius: .4rem;
    color: #fff;
    cursor: pointer;
    display: inline-block;
}
.button:focus,
.button:hover {
    background-color: #606c76;
    border-color: #606c76;
    color: #fff;
    outline: 0;
}

使用CSS模块,这些样式规则将重命名为:

._12We30_button {
    background-color: #9b4dca;
    border: 0.1rem solid #9b4dca;
    border-radius: .4rem;
    color: #fff;
    cursor: pointer;
    display: inline-block;
}
._12We30_button:focus,
._12We30_button:hover {
    background-color: #606c76;
    border-color: #606c76;
    color: #fff;
    outline: 0;
}

如果通过浏览器的DevTools浏览Facebook,Instagram或Airbnb等大型网站,您会发现CSS类和ID就是用这种模式命名的。 这是Airbnb主页上的示例:

多种成分

如果我们只有一个组件,那么使用CSS模块就没有多大意义,因此让我们将示例扩展到三个组件,并了解如何配置我们的项目以实现CSS模块。

创建一个组件

在第二个示例中,我们将构建三个组件。 具有三种不同样式的按钮。 我们将它们称为“主按钮”,“概述按钮”(也称为“鬼按钮”)和“清除按钮”。 我们将这些按钮放在单独的目录中。 每个目录将包含index.cssindex.js

index.js ,我们创建元素并将类分配给该元素,如下所示:

// 1. Import the styles from index.css file.
import styles from './index.css';

/**
 * 2. Creating a button element and add the class from index.css.
 * @type {String}
 */
const button = `<button class="${styles['button']}">Save Changes</button>`;

// 3. Export the button to be used in the other files.
export default button;

使用ES6中的新import指令,我们导入样式表,并将类和ID读取为JavaScript对象。 然后,我们创建一个元素,并使用本机JavaScript模板化添加名为.button的类,该类也在ES6中引入。 最后,我们导出元素,以便也可以在其他JavaScript文件中导入和重用该元素。

在撰写本文时,并不是每个浏览器都实现了ES6规范中的最新JavaScript功能和语法。 因此,我们需要Babel将这些代码段转换为大多数浏览器都兼容JavaScript语法。

我们的样式表index.css是纯CSS。 它包含许多用于设置按钮元素样式的选择器。

/* 1. Primary Button */
.button {
    background-color: #9b4dca;
    border: 0.1rem solid #9b4dca;
    border-radius: .4rem;
    color: #fff;
    cursor: pointer;
    display: inline-block;
    font-size: 1.1rem;
    font-weight: 700;
    height: 3.8rem;
    letter-spacing: .1rem;
    line-height: 3.8rem;
    padding: 0 3.0rem;
    text-align: center;
    text-decoration: none;
    text-transform: uppercase;
    white-space: nowrap;
}
/* More styles of the Primary Button here */

使用CSS模块的优点之一是,我们不必担心命名约定。 您仍然可以使用自己喜欢CSS方法(如BEM或OOCSS),但不强制执行任何操作。 您可以用最实用的方式为组件编写样式规则,因为类名最终将得到命名空间

在此示例中,我们将按钮组件的所有类命名为.button而不是.button-primary.button-outline

使用Webpack编译模块

当我们在HTML页面上加载index.js时,浏览器中将不会显示任何内容。 在这种情况下,我们将必须编译代码以使其起作用。 我们将需要安装BabelES2015(ES6)的Babel预设Webpack以及以下所谓的“加载程序”,以允许Webpack处理我们的源文件。

  • babel-loader :使用Babel核心模块加载.js文件并转换源代码。
  • css-loader :加载.css文件。
  • style-loader :使用<style>将来自css-loader内部样式注入HTML页面。

我们使用NPM安装这些软件包,并将其保存为package.json文件作为我们的开发依赖项。

Webpack配置

与带有gruntfile.js Grunt或带有gruntfile.js Gulp gulpfile.js ,我们现在需要使用名为webpack.config.js的文件来设置webpack.config.js 。 以下是我们项目中完整的Webpack配置:

var path = require('path');

module.exports = {
    entry: './src/main.js', // 1.
    output: {
        path: path.resolve(__dirname, 'dist/js'),
        filename: 'main.js'
    },
    module: {
        loaders: [ // 4.
            {
                test: /\.css$/,
                use: [
                    {
                        loader: 'style-loader'
                    }, {
                        loader: 'css-loader',
                        options: {
                            modules: true,
                            localIdentName: '[hash:base64:5]__[local]'
                        }
                    }
                ]
            }, {
                test: /\.js$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: {
                            presets: ['es2015']
                        }
                    }
                ]
            }
        ]
    }
}

该配置告诉Webpack将我们的主要JavaScript文件main.js编译到/dist/js目录。 我们还启用了css-loadermodules选项,并将类和ID命名模式设置为[hash:base64:5]__[local] 。 我们使用babel-loader来编译我们的ES6 JavaScript文件。

一旦安装了依赖项并设置了配置,就将所有三个按钮都导入main.js文件中。

// Import the button elements;
import ButtonPrimary from './button-primary';
import ButtonOutline from './button-outline';
import ButtonClear from './button-clear';

// Add the element to the content;
document.getElementById('content').innerHTML = `${ButtonPrimary}${ButtonOutline}${ButtonClear}`;

然后运行webpack命令,如下所示:

./node_modules/.bin/webpack

当在浏览器中加载/dist/js/main.js时,我们应该看到按钮被添加了类,这些类的名称与我们在css-loader设置的模式相同。 我们还可以找到通过styles元素添加到页面的styles

组成

诸如LESS和Sass之类CSS预处理器允许我们通过扩展其他样式表中的另一个类或ID来重用样式。 使用CSS模块,我们可以使用compose指令执行相同的操作。 在此示例中,我将在三个按钮之间共享的通用样式规则放置在另一个文件中,并从新文件中导入了该类,如下所示:

.button {
        
    /* Extend .button class to apply the basic button styles */
    composes: button from "./button.css";
    
    color: #fff;
    background-color: #9b4dca;
    border: 0.1rem solid #9b4dca;
}

一旦代码重新编译并加载到浏览器中,我们可以发现按钮具有两个类。 现在,页面中还注入了四个style元素,其中包括_3f6Pb__button类,其中包含我们组件的通用样式规则。

在Vue中使用CSS模块

在实际的项目中,我们可能不会使用纯JavaScriptCSS模块。 相反,我们将使用像Vue这样JavaScript框架。 幸运的是,CSS模块已通过vue-loader集成到Vue; 一个Webpack加载器,它将编译.vue 。 以下是如何将主按钮移植到.vue组件中的.vue

<template>
<button v-bind:class="$style.button"><slot></slot></button>
</template>

<script>
export default {
    name: 'button-primary'
}
</script>

<style module>
.button {
    
    /* Extend .button class to apply the basic button styles */
    composes: button from "./button.css";
    
    color: #fff;
    background-color: #9b4dca;
    border: 0.1rem solid #9b4dca;
}

.button[disabled] {
    cursor: default;
    opacity: .5;
}

.button[disabled]:focus,
.button[disabled]:hover {
    background-color: #606c76;
    border-color: #606c76;
}

.button:focus,
.button:hover {
    background-color: #606c76;
    border-color: #606c76;
    color: #fff;
    outline: 0;
}
</style>

在Vue中,我们将module属性添加到style元素,如上所示,以启用CSS模块。 当我们编译这段代码时,我们将得到几乎相同的结果。

结语

对于某些人来说,这将是全新的东西。 乍看之下,如果CSS模块的概念有点让人头疼,那是完全可以理解的。 因此,让我们回顾一下我们在CSS模块中学到的知识。

  • “ CSS模块”允许我们通过重命名或namespacing类名称来封装样式规则,从而最大程度地减少随着代码库增长而对选择器特异性的冲突。
  • 这也使我们可以更舒适地编写类名,而不必遵循一种特定的方法。
  • 最后,由于样式规则已耦合到每个组件,因此当我们不再使用组件时,样式也会被删除。

在本文中,我们几乎没有涉及CSS模块和其他现代Web开发工具(如Babel,Webpack和Vue)的表面。 因此,在这里,我整理了一些参考资料以进一步研究这些工具。

进一步参考

翻译自: https://webdesign.tutsplus.com/tutorials/solve-your-specificity-headaches-with-css-modules--cms-28973

css模块化的解决方案

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值