前言
作用域
CSS的规则都是全局的,任何一个组件的样式规则,都对整个页面有效。
产生局部作用域的唯一方法,就是使用一个独一无二的className的名字,不会与其他选择器重名。
编译过程
import React from 'react';
import style from './App.css';
export default () => {
return (
<h1 className={style.title}>
Hello World
</h1>
);
};
构建工具会将类名style.title编译成一个哈希字符串。
<h1 class="_3zyde4l1yATCOkgn-DBWEL">
Hello World
</h1>
这样一来,这个类名就变成独一无二了,只对App组件有效。这样也导致了一些问题比如css穿透,如果要改一些第三方的东西
样式穿透
vue怎么实现当前组件范围内有效的:在style上加一个scoped修饰符,这个样式就只在当前组件的范围内有效
在每个dom元素上,有一个data-v-xxxxxxxx的标识符,这个标识符就是保证scoped有效的根本!我们定位到button上,查看css样式:
解决方法: vue用sass语法/less语法 : 在要修改的样式前添加::v-deep ,/deep/也是可用的
.wrap /deep/ .el-card__header{
border:none;
}
react如何解决:可以用global(.className)来做到样式穿透,就是让被global包裹住的class不被样式隔离化,维持原有的名称,写法的话类似这样就可以生效了
// Father的scss文件
.father {
:global(.btnStyle){
// 一些样式
}
// 或者
:global(#btnStyle){
// 一些样式
}
}
// Father
<div className={styles.father}>
<Son/>
</div>
// Son
<div className={styles.btnStyle} id='btnStyle'>
这是一个按钮
</div>
使用方法
Webpack 的[css-loader]插件
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 功能。