起源
样式冲突问题在日常开发中十分常见,在vue和react开发中,样式经过打包,被放到了同一个css文件下,最后样式就会被全局使用。这时候,如果存在重名样式名,就很可能会产生冲突。
解决方案
今天要讲解的方案是目前较为主流的两种方案:1.css-in-js 2.module 他们都是通过给类名一段哈希值来使样式名不可能重复,从而解决冲突。
一、css-in-js
css-in-js 是一种将css也用js来使用的一种思想,他比较契合react all-in-js的思想。但是这种思想现在也仍存在争议。
目前主流的css-in-js库为 styled-components。styled-components通过创造组件应用我们所传递的样式属性。
创建style组件
import styled from "styled-components"
const Wrapper = styled.div`
width : ${props => props.width};
height : ${props => props.height};
background: ${props => props.color};
display: inline-block;
`
export default Wrapper;
应用style组件
import Wrapper from './pages/css-in-js';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<Wrapper width='100px' height='100px' color='red'></Wrapper>
</header>
</div>
);
}
export default App;
最终效果
从上图可以看出来,Wrapper组件最后变成了我们一开始指定的div,同时作为组件,我们可以通过传入属性值来控制他的样式。如果你想同时应用别的style组件,或许就需要再裹上一层组件,这样会破坏html元素的结构,style-components通过继承的思想解决了这个问题。创造的style组件可以通过继承,得到别的style组件的样式。这里属性名也被带到了标签上,个人觉得这样可能会存在一些隐患,同时也不利于阅读,完全没有展示的必要,如果大家有别的看法欢迎讨论。
二、module样式
这种方法在react开发中比较常用,只需要在样式文件名和css之间加上.module就可以生成。
App.module.css
.bar {
width: 100px;
height: 100px;
background: blue;
display: inline-block;
}
.bar .test{
color: red;
}
test.module.css
.bar {
width: 100px;
height: 100px;
background: blue;
display: inline-block;
}
应用
import './App.css';
import styled from './App.module.css';
import testStyled from './test.module.css';
function App() {
return (
<div className="App">
<header className="App-header">
<div className={styled.bar}>
<div className={styled.test}>11</div>
</div>
<div className={testStyled.bar}></div>
<div className={styled.test}>11</div>
</header>
</div>
);
}
export default App;
最终效果
从上图可以看到,module生成的样式名采用文件名+类名+哈希值生成,所以不会存在重复的样式名。同时我尝试使用子类选择器,最后,子类选择器同样是有效的。module样式的使用思路实际上和传统的思路是一样的,如果是想要使用多个样式,那重复指定就可以。