css modular conflict resolution
CSS scope is global, projects are getting bigger and bigger, and there are more and more people. Naming has gradually become a problem. It is inevitable that duplication of names will occur, so corresponding modular solutions were born.
Currently there are these categories:
- 1. CSS naming methodology: Agree on naming rules manually.
- 2.CSS Modules: A CSS file is an independent module.
- 3.CSS-in-JS: Write CSS in JS.
- 4.HTML5 style scoped
CSS Naming Methodology
GOOD
BEM is the block element modifier (Block Element Modifier), named in the form of .block__element–modifier, that is, the three parts of .module name__element name – modifier name . Use double underline__ to clearly distinguish the module name and element name. Use double dashes - to clearly distinguish element names from modifier names.
.box__menu-item--active {
}
This kind of naming is mainly artificial to comply with naming constraints.
Atomic CSS
Atomic CSS is atomic CSS, which encapsulates a single attribute into a Class to ensure that there are no duplicate styles. This facilitates the reuse of attributes, but also causes the Class of elements with complex styles to be very bloated.
<div class="mt-10 w-100 h-15"></div>
CSS Modules
css module follows the following ideas to resolve class name conflicts:
- CSS class name conflicts often occur in large projects
- Large projects often use build tools (webpack, etc.) to build projects
- Build tools allow css styles to be split into more granular modules
- Like JS variables, conflicting class names are difficult to appear in each css module file. Conflicting class names often occur in different css module files.
- Just make sure that the build tool does not have class name conflicts after merging the style code.
CSS Modules
It is neither an official standard nor a browser feature, but a way to scope CSS class name selectors (implementing a namespace-like method through hashing) during the build step (such as using Webpack or Browserify).
webpack
The built-in css-loader
components are included CSS Modules
and can be used through simple configuration.
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true,
}
}
],
},
]
}
};
The default hash algorithm for custom-generated class names
css-loader
is [hash:base64], but we may need to customize the desired class name format, which css-loader
provides us with localIdentName
parameters to specify the generated name format.
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]__[local]-[hash:base64:5]'
},
}
],
},
]
}
};
Vue uses modules
<template>
<p :class="$style.gray">
Im gray
</p>
</template>
<style module>
.gray {
color: gray;
}
</style>
Compiled result:
<p class="gray_3FI3s6uz">Im gray</p>
.gray_3FI3s6uz {
color: gray;
}
Scope
CSS Modules
:local
The localization of styles is achieved through the default local scope , and the global scope is used :global
to achieve globalization of styles. At the same time, the global class name packaging will not be compiled into a hash string.
// 局部样式(可以省略:local)
.normal {
color: green;
}
:local(.normal) {
color: green;
}
// 全局样式
:global(.btn) {
color: red;
}
Global class name
Some class names are global and static and do not require conversion. You only need to use a special syntax in the class name position:
:global(.main){
...
}
Class names that use global will not be converted. On the contrary, class names that do not use global mean that local is used by default.
:local(.main){
...
}
The local class name is used to represent the local class name. It is a class name that may cause conflicts and will be converted by the css module.
important point
When processing keyframes of animation animation, the animation name must be written first. For example, animation: deni .5s will compile normally; animation: .5s deni will compile abnormally.
Remember to configure css-loader, otherwise it will not take effect.
If you are using style-loader, you need to configure and change it to vue-style-loader for it to take effect.
How do css modules solve the weight problem?
Advantages: Allows style rules to be encapsulated through renaming or namespaces, reducing constraints on selectors, so that class names can be used comfortably without specific methods. When style rules are coupled to each component, the styles are also removed when the component is no longer used.
CSS in JS
Ditch it entirely CSS
, use JavaScript
written CSS
rules, and inline styles. React: CSS in JS // Speaker Deck. Radium, react-style falls into this category. But there are the following problems:
- Unable to use pseudo-classes, media queries, etc.
- There is also a lot of duplication of style code.
- Cannot take advantage of full-blown CSS preprocessors (or postprocessors)
Use JS to manage style modules.
Use JS to compile native CSS files to make them modular.
css scoped
Vue achieves the purpose of privatizing and modularizing styles by adding unique and non-repeating tags to the DOM structure and CSS styles to ensure uniqueness. It is impossible to completely avoid the problem of css weight and class name duplication.
<style scoped>
.example {
color: red;
}
</style>
<template>
<div class="example">hi</div>
</template>
Convert
<style>
.example[data-v-f3f3eg9] {
color: red;
}
</style>
<template>
<div class="example" data-v-f3f3eg9>hi</div>
</template>
Notice:
1. scoped在DOM中添加了一个唯一的属性data-v-f3f3eg9,在css中也添加了一个属性.example[data-v-f3f3eg9]
来保证唯一性,这样如果外部使用了同名的class,依然有可能影响组件的样式
2. scoped使用了属性选择器,会使得选择的效率降低
3. scoped在html和css中都添加了哈希值,会使得两者的提交都变大,降低加载速度,影响渲染效率
4. scoped修改子组件的样式,必须使用深度选择器
shortcoming:
If the user defines the same class name elsewhere, it may still affect the component's style.
According to the characteristics of CSS style priority, scoped processing will increase the weight of each style. Referring to a scoped component
as a subcomponent, it becomes difficult to modify the style of the subcomponent, and you may have to use it! important
scoped will slow down tag selector rendering many times. When using tag selectors, scoped will seriously reduce performance, but using class or id will not.
Overall, CSS Modules is better than scoped, and it is recommended to use CSS Modules.
Finally, I would like to recommend a plug-in to everyone, which can greatly improve our development efficiency. When writing styles.
Hover the mouse with ctrl+click to jump to the style.
Reference article: https://juejin.cn/post/6994046975851102239