我们知道,简单的class名称容易造成css命名重复,比如你定义一个class:
<style>
.main { float: left; }
</style>
如果别人刚好也定义了一个className:.main,你的float:left就会影响到它。
所以vue中发明了css_scoped,其原理就是在class名称后加上一个data属性选择器:
<style scoped>
.main { float: left; }
</style>
//转义后变成
<style>
.main[>float: left }
</style>
css_scoped是Vue的专用方案,如果你使用react等其它UI框架,那么你可以使用更通用的css_module,其原理是为样式名加hash字符串后缀,从而保证class名全局唯一:
<style module>
.main { float: left; }
</style>
//转义后变成
<style>
.main_3FI3s6uz { float: left; }
</style>
相比于css_scoped,css_module方案更通用,不改变其本身的权重,而且渲染性能要比前者好很多,所以更推荐大家使用css_module。
然而不管是css_scoped还是css_module,都绕不开2大缺点:
我们来回忆一下,在css_scoped和css_module出现之前,人们是如何避免css命名冲突的?
对,就是人为的定义一些css命名空间。
那个时候,对每个Component组件都会在其根节点上定义一个不重复的ID或者class作为其命名空间,然后其内部的其它class都会以此命名空间作为前置限定,比如:
<div class="table-list">
<div class="hd"></div>
<div class="bd"></div>
<div class="ft"></div>
</div>
<style>
.table-list {
> .hd {
color: red
}
> .bd {
color: blue
}
}
</style>
这样一来,只要保证根节点的class不重复,其子节点的class就不会重复。
而对于一些全局样式,人们习惯加上一个g-作为命名空间,比如:
<style>
.g-hd {
color: red
}
</style>
这种依靠人为约定的css命名空间,虽然比较原始,但有其优点:
如果我们把css_module和css_命名空间结合起来,组件的命名空间由css_module自动生成,那岂不是一种更优雅的解决css冲突的方案么?
css_module中有2个特别的作用域限定符:
:global {
.test1 { color: blue; }
.test2 { color: red; }
}
//编译后
.test1 { color: blue; }
.test2 { color: red; }
:local {
.test1 { color: blue; }
.test2 { color: red; }
}
//编译后
.test1_3zyde4l1y { color: blue; }
.test2_2DHwuiHWM { color: red; }
如果我们使用css_namespace + css_module:
<div :class="styles.root">
<div class="hd"></div>
<div class="bd"></div>
<div class="ft"></div>
</div>
<style module>
:global {
:local(.root) {
> .hd {
color: red;
.title {
font-size: 18px;
}
}
> .bd { color: blue; }
}
}
</style>
//css编译后
<style>
.root_3zyde4l1y > .hd{ color: red; }
.root_3zyde4l1y > .hd .title{ font-size: 18px; }
.root_3zyde4l1y > .bd{ color: blue; }
</style>
这样的意思是:
<style>
.root_3zyde4l1y > .hd{ color: red; }
.root_3zyde4l1y > .hd .title{ font-size: 18px; }
.root_3zyde4l1y > .bd{ color: blue; }
</style>
根节点上的class命名带个hash小尾巴,仍然很不优雅。其实hash字符只是为了保证这个名称全局唯一而已,你也可以使用另外的方法来保证。如果你为工程设计一个有意义的目录结构,那么完全可以使用目录路径来替代hash字符串,比如你的工程目录如下:
src
├── components
│ ├── moduleA
│ │ ├── componentX
│ │ ├── componentY
│ ├── moduleB
│ │ ├── componentZ
那么:components-moduleA-componentX这个目录路径一定是全局唯一的,所以你可以使用这个路径来替代hash字符,css_module提供了自定义转换className的方法:
type getLocalIdent = (
context: LoaderContext,
localIdentName: string,
localName: string
) : string;
你可以通过该方法来将目录路径映射为class名称,并替换掉一些固定的目录,比如工程目录如下:
src
├── assets
│ ├── css
│ ├── global.module.scss //全局样式
│ ├── :local(.loading) {} //全局样式只需要加个g-前缀,编译成.g-loading
├── components
│ ├── NavBar
│ ├── index.module.scss
│ ├── :local(.root) {} //根据目录路径可编译成即可.comp-NavBar
│
├── modules
│ ├── user
│ ├── components
│ ├── LoginForm
│ ├── index.module.scss
│ ├── :local(.root) {} //根据目录路径可编译成.user-LoginForm,
│
注意的是src/modules/user/components/LoginForm/index.module.scss,根据目录路径可以生成:modules-user-components-LoginForm,但因为user是一个module,其名称是唯一的,且内部结构遵循约定,所以可以简化为:user-LoginForm
如果你也使用类似的工程目录,那么可以直接使用我封装好了的路径映射函数getCssScopedName:
const {getCssScopedName} = require('@elux/cli-utils');
const srcPath = path.resolve(__dirname, '../src');
// webpack css-loader
{
loader: 'css-loader',
options: {
importLoaders: 2,
modules: {
getLocalIdent: (context, localIdentName, localName) => {
return getCssScopedName(srcPath, localName, context.resourcePath);
},
localIdentContext: srcPath,
},
},
};
当然你也可自己实现个性化的getLocalIdent,无非就是一些正则匹配与替换罢了...
采用css_namespace + css_module的实际案例:
或者使用任意一个elux工程模版:npm create elux@latest 或 yarn create elux
如图所示,通过class名称基本上就能推测出组件位置...
CSS 算不上是最优美的『语言』,但迄今二十多年来,它都是美化 web 举足轻重的工具。尽管如此,CSS 写得越多,你越容易发现一个巨大的弊端。因为维护 CSS 真是老大难。
在web前端开发中遇到不知道给元素或变量起什么名字的问题,中文拼音太俗气,随便敲几个字母又影响代码的查读性。于是总结这些命名规范。
CSS命名规范(规则)常用的CSS命名规则 ,注意事项:1.一律小写; 2.尽量用英文; 3.不加中横和下划线; 4.尽量不缩写,除非一看就明白的单词。
不论var f 与function f 的先后顺序如何,该代码执行的结果总是弹出function f 的字符串,为什么呢?像这种函数与变量命名冲突时JS的处理原则又是什么?
BEM的意识就是块(block)、元素(element)、修饰符(modifier),是由yandex团队提出的一种CSS Class命名方法。但至少他可以使我们命名的时候达到一定的统一,我们可以学习其优秀的方面将其纳为己用。
CSS 的命名规范又叫做BEM规范,为的是结束混乱的命名方式,达到一个语义化的CSS命名方式。 BEM是三个单词的缩写:Block(块)代表更高级别的抽象或组件,Element(元素) Block的后代,以及Modifier(修饰) 不同状态的修饰符
应该很多人都会有PO这种东西,但是对刚学CSS的人真的很重要,尤其像我这种英文不好的人,这些是必背的的单字喔^^,这些数据只是我在学习的时候,参考别人的数据之后用自己的思考整理出来的,像参考书写的真的都看不懂
最近,LinkedIn 的 JavaScript 组提出了一个有趣的问题:是否需要重新命名 JavaScript?众所周知,JavaScript 与 Java 无关。数十年来,这使非技术经理和招聘人员感到困惑。
思考来源于要给切图网 qietu.com 改一次版,作为前端开发服务商,我觉得应该要有自己的一款前端CSS框架,并且这个框架不应该只是随便写写,最好能够用在官网上,拿官网做背书,于是在研究了火狐
大驼峰命名规则又称骆驼式命名法(Camel-Case),是电脑程式编写时的一套命名规则(惯例)。是指混合使用大小写字母来构成变量和函数的名字。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!