内容简介:命名是我认为 CSS 里最难的问题没有之一,特别是别人的命名。我们都知道,CSS 是一个不强调CSS 的作用域是全局的,这样我们能很轻易的覆盖一个 CSS 样式,即使之前的人代码写的不是那么的优雅。可是也正因为这样,当我们不想覆盖别人的样式,或者自己之前写的样式的时候,这就变成了一个世界难题。因为此时我们面临的问题不再是写样式这么简单,而是升级成了
命名是我认为 CSS 里最难的问题没有之一,特别是别人的命名。
管理 CSS 就好比管理“内裤”
我们都知道,CSS 是一个不强调 逻辑 ,而更看中表现的一种 所见即所得 的语言。你写了一个属性它就有了这个样式,你之前写了,你现在又写一个,它就以你最新写的这个为准(在不考虑选择器优先级的情况下)。这种愉悦感是别的开发语言所不具备的。就好比你嗑瓜子一下,你嗑一下都会能给你一个反馈,你就能一直嗑下去。而这也是 CSS 让我着迷的原因之一。
CSS 的作用域是全局的,这样我们能很轻易的覆盖一个 CSS 样式,即使之前的人代码写的不是那么的优雅。可是也正因为这样,当我们不想覆盖别人的样式,或者自己之前写的样式的时候,这就变成了一个世界难题。因为此时我们面临的问题不再是写样式这么简单,而是升级成了 代码管理 的问题。
CSS 不像其它有逻辑性的语言,有比较多的代码管理方式。你能管理 CSS 的 工具 只有两个,一个是 文件引用 ,另一个则是 命名 。所以你能看到的所有讲 CSS 命名规则的方法不管是BEM 还是SMACSS ,其实都是在讲 CSS 代码管理的问题。
对于CSS的管理,我这边举个不恰当但是很贴切的方式,就是类似于日常生活中内裤的管理,是的就是你日常穿的内裤,和 CSS 中的“类库”谐音(我太有才了)。
假设你爸是挖矿的,你家很有钱。而你又特别喜欢买内裤,赤,橙,黄,绿,青,蓝,紫,彩色的,蕾丝的,莫代尔的,纯棉的,紧身的... 各式各样的内裤共计9999条(加上你现在身上穿的那一条,刚好10000条)。请问你要怎么管理这10000条内裤?
你家有钱,很简单,你买 100 间房间,按照自己“喜欢”的分类,每个房间各放100条内裤。然后每间房间里面又按照自己“熟悉”的规则,把内裤进行排列。有钱就是任性有没有?
而这一个个的房间就好比我们 CSS 中的一个个文件,房间里内裤的编号,就好比我们的 class
类名。这边可以看到,我有把“喜欢”,和“熟悉”加上引号。因为对于自己喜欢和熟悉的东西,对于其它的人来说都基本上是不熟悉的。不信你可以问问你的同事,你们归类内裤的规则很大概率和你是不一样的(最好问同性的同事吧,不然小心被告职场性骚扰)。
你妈比你更会管理你的“内裤”
所以要怎么办呢?此时老妈就派上用场了。你妈妈的生活经历肯定比你丰富,并且她的生活经历也有可能和楼下广场舞大妈们聊过的,所以说称得上是一项通用技能。于是遇到找内裤的问题,我们大家的第一反应通常是问妈妈。
在 CSS 世界里也是一样的。有很多管理 CSS “内裤”的妈妈,而这边我举一个相对比较有名的阿姨 BEM :
<styles> .brief{ /* 描述:贴身的下身内衣; */ } .brief--type{ /* 大小:中号; */ } .brief--male{ /* 适合性别:男; */ } .brief--male__type{ /* 颜色:黑色; */} </styles> <div class="brief brief--male"> <div class="brief__type brief--male__type">一条黑色的男式中号内裤</div> </div> 复制代码
可以看到这位阿姨管理“内裤”还是很有一套的,首先它的可读性是非常好的,也能解决不同人员之间,命名不规范的问题。然后你上午逛街看上了一条红色女士内裤,准备买来送给女朋友。
<styles> .brief{ /* 描述:贴身的下身内衣; */ } .brief--type{ /* 大小:中号; */ } .brief--male{ /* 适合性别:男; */ } .brief--male__type{ /* 颜色:黑色; */} .brief--female{ /* 适合性别:女; */ } .brief--female__type{ /* 颜色:红色; */ } </styles> <div class="brief brief--male"> <div class="brief__type brief--male__type">一条黑色的男式中号内裤</div> </div> <div class="brief brief--female"> <div class="brief__type brief--female__type">一条黑色的男式中号内裤</div> </div> 复制代码
BEM 阿姨到这里表现都是非常不错的,在保证代码可读性的情况下,拓展性也是很好的。
晚上吃完宵夜的时候,怕自己上午买的内裤女友不喜欢,又多买了“一条粉色的蕾丝女士内裤”。
<styles> .brief{ /* 描述:贴身的下身内衣; */ } .brief--type{ /* 大小:中号; */ } .brief--male{ /* 适合性别:男; */ } .brief--male__type{ /* 颜色:黑色; */} .brief--female{ /* 适合性别:女; */ } .brief--female__type{ /* 颜色:红色; */ } .brief--female2{ /* 类型:蕾丝; */ } .brief--female2__type{ /* 颜色:粉色; */ } </styles> <div class="brief brief--male"> <div class="brief__type brief--male__type">一条黑色的男式内裤</div> </div> <div class="brief brief--female"> <div class="brief__type brief--female__type">一条红色的女式内裤</div> </div> <div class="brief brief--female brief--female2"> <div class="brief__type brief--female2__type">一条粉色的蕾丝女式内裤</div> </div> 复制代码
可能你妈妈不知道蕾丝是啥,就不知道怎么管理你的内裤了?但是妈妈项来是不愿意承认自己的错误的,于是她肯定会开骂了:你上午不是刚买了内裤吗,怎么又买?我才懒得管你。你自己买的内裤你自己弄吧!
而此时你就悲剧了,“一条粉色的蕾丝女式内裤”,请问用你妈妈的 BEM 方式要怎么命名?像这样 .brief--female__type--lace
? 我想此时你是崩溃的。
到这里不知道大家有没有发现这件事情不对的地方?当引入 BEM 之后,我们已经完全不能享受到买内裤和使用内裤的乐趣了。
我们更多在做的事情是什么?是 命名 ,还有 维护 这套命名规则。如果换到工作场合,妈妈这个角色可就是你的同事了。如果你同事看到你用了一个 .brief--female__type--lace
这样的类名来管理你的“内裤”,你只能感谢他的不杀之恩了。
我们每次找不到自己内裤的时候,会本能问:“妈!我昨天穿的那条内裤在哪儿啊?”
妈妈通常会不耐烦的回答:“昨天不就告诉你了在第一个柜子的第二个抽屉的第一格,这样的问题你到底还要问几遍?”
这是不是很像工作中,你问你同事:“诶,你昨天给我说的,你之前封装的那个让按钮爆炸的那个 class
叫啥啊?”
发现问题没有?我们要的是内裤,而内裤放在哪里这件事,并不是我们关心的重点。
“妈,你能把我昨天穿的那条内裤给我一下吗?”
啪,你妈直接就把内裤扔给你了。
这是不是你更希望得到的结果。
把你的内裤都换成一次性内裤
只是因为我们都太习惯创建 class
类名了,导致我们在写样式的时候,第一步竟然不是样式本身而是创建一个 class
。
就好比你一条内裤都还没有买,你妈妈都已经提前给你订好了,按照各种款式命名的装内裤的盒子。能做到连你自己都不知道要买啥样的内裤,却能帮你无中生有的归好类的人也只有你妈妈了。
你有没有想过,你都是能买得起上万条内裤的人了,为啥不自己建了一个内裤工厂,你想要什么样的内裤,你直接打个电话给你的助手,他就直接送到你的面前,穿完了你就扔掉。
每天都穿新内裤还不带重样的。管理内裤什么的,与你无关,也解放了你妈妈时间。家庭一下子就和睦了,有没有?
而这种方式换到 CSS 里面就是类似于这样:
<div style="/* 描述:贴身的下身内衣;大小:中号;适合性别:男; 颜色:黑色;*/ ">一条黑色的男士内裤</div> <div style="/* 描述:贴身的下身内衣;大小:中号;适合性别:女; 颜色:红色;*/ ">一条红色的女式内裤</div> <div style="/* 描述:贴身的下身内衣;大小:中号;适合性别:女; 类型:蕾丝; 颜色:粉色;*/ ">一条粉色的蕾丝女式内裤</div> 复制代码
是的,不要怀疑你的眼睛,我们通过 style
直接写属性,就能最直接的告诉别人 “一条粉色的蕾丝女式内裤” 的样子。是不是任何人都能看懂?而这也是我认为最符合 CSS “所见即所得” 的方式。
这里还有一个更值得思考的问题,我们在这里甚至都弱化了内裤本身这个名字。我都把一个你想要的黑色的可以遮挡私处的贴身内衣给你穿上了,你觉得你还在乎它叫啥吗?
而此时本文的重点来了,CSS 是什么?CSS 是 层叠样式表 ,而 class
(类名)显然不是,它只是 CSS 和 HTML 之间的 钩子 。而真正的样式其实是这些:
描述:贴身的下身内衣; 大小:中号; 适合性别:男; 颜色:黑色; /* ... */ 复制代码
我们之所以会需要去 管理代码 ,很大一部分原因是因为我们想要去 复用 它造成的。这个理论不仅限于 CSS,对于大多数的语言都是适用的。
简单的来说,现买现用,穿完就扔的内裤,是不需要你花时间和精力去管理的。你之所以需要用箱子去装你的内裤,甚至还需要给不同的箱子编上不同的名字,就是希望下次想穿的时候能够快速的找到它。
如果你不想管理你的内裤,最简单直接的方式就是,把它们都换成一次性内裤。
说得高级一点就是完全放弃空间复杂度(浪费存储资源),以换取时间复杂度(管理时间)的自由。
管理内裤的原材料而不是内裤
所以 代码复用 和 代码管理 其实是不是我们以为的 从属 关系,而是两个 对立 面的关系。那我们要怎么平衡这两个点呢?
在代码的世界里,只要对方的“内裤”是我“裆下”需要的,我们甚至巴不得复用(不好意思,忍不住开车了)。因为对于CSS来说复用样式,其实是成本很低的一件事情,我们只需要知道一个样式的 class
,就能通过这个 class
复用我们想要的样式。真正的噩梦是 class
的命名和维护 class
。你想象要复用10000条内裤,我们在管理这10000条内裤的同时,还得管理用来管理这10000条内裤的 命名规则 。这是一件多么痛苦的事情?
这听起来真的是绕口,然而 CSS 的现状就是这样。那有没有一种方式是可以跳出这个怪圈的呢?答案当然是有的,就是放弃复用“内裤”这个想法,而是要思考怎么复用制作内裤的 原材料 。
当我们的视角进入到复用内裤原材料这个更微观的世界的时候,你就会发现之前的问题都迎刃而解了。很简单,来我们尝试着把10000条内裤,拆解为可复用的原材料。
- 布类型:棉,麻,涤纶,氨纶,莫代尔...
- 颜色:赤,橙,黄,绿,青,蓝,紫...
- ...
基于之前的例子,我们现在的代码会变成什么样的呢?
<style> .贴身的下身内衣{ } .中号{ } .男{ } .女{ } .黑色{ } .红色{ } .粉色{ } .蕾丝{ } </style> <div class="/* 贴身的下身内衣 中号 男 黑色 */ ">一条黑色的男士内裤</div> <div class="/* 贴身的下身内衣 中号 女 红色 */ ">一条红色的女式内裤</div> <div class="/* 贴身的下身内衣 中号 女 粉色 蕾丝 */ ">一条粉色的蕾丝女式内裤</div> <div class="/* 红色 */">一匹红色的马</div> 复制代码
可以看到我们需要维护的东西,一下从 10000 条内裤降到了几十种原材料。这些原材料是不需要你去思考它们名字的。更惊奇的是,这些原材料可不只用于内裤上,它还可以应用到内衣,衣服,裤子,鞋子...等等一系列的东西上。
你甚至可以用这个原材料,把一匹马涂成红色的。发现没有,这就是我们视角改变了之后,整个 思维方式 的巨大改变。
之前有讲过,在 CSS 世界里,复用是成本很低的事情,也就是说,我们复用1个原材料和复用10个原材料是没有本质区别的。
内裤是工业品不是艺术品
到这里可能有的同学会说,你这个原材料拆分的明显没对,布类型不是还有竹炭纤维,甚至太空材料的,颜色还有红蓝渐变或者五彩斑斓的黑。
对于我们大多数男性 程序员 来说,内裤无非就是棉的和不是棉的两种,颜色无非就是黑,白,灰。即使不是程序员,你也很难会发现,普通的人会买到,赤,橙,黄,绿,青,蓝,紫这么多种颜色的内裤。
举这个例子是想说明什么,内裤是 工业品 而不是 艺术品 。工业品注定会控制原材料的种类以降低成本的。而真正会把内裤当艺术品的人,也就不会因为没钱,而不会去考虑复用内裤的问题。
在我们网页的开发也是一样的,如果你的网站不是走艺术类的网站,你却发现你的原材料提供商(设计师),光是从颜色上就给你提供了超过了十几二十几种颜色,那他一定是有问题的。
如果你的设计师,是对自己的设计语言是有极致约束能力的,那对于我们开发者来说这真的是一件非常开心的事情。
内裤原材料管理方法论Atomic CSS
这种将样式原子化的思维方式就叫做 Atomic CSS (简称 ACSS )。 我花了这么大的篇幅,还花了这么多的心思去借用“内裤”举例子,就是希望大家能先明白这是一种 思维方式 。而不只是一个 工具 这么简单。
我在团队里至少分享了四五次关于 ACSS 主题,也依然存在着非常大的争议,就好比你想让一个一直基于 DOM 开发的前端程序员,在一瞬间就完全接受 React 的组件化思维一样是很困难的。
要接受 ACSS 都已经是很难的事情,更何况要深入去思考它的优劣。在国内我几乎只看到我的男神 “张鑫旭”有略微深入的介绍过这套理论(当然有可能是我只关注了他一个人的原因)。
而我是 12 年还没有毕业的时候就已经在研究 OOCSS(和 ACSS 角度不同,但是思维方式却是高度一致的)了。毫不吹嘘的说,基于这套理论,我是我遇到的前端程序员中 CSS 原型稿写的最快的程序员(可能我认识的人本来就不多)。有兴趣的同学可以去我的 github 看一下 。因为最近一直在用 SASS,所以很多新的思考和沉淀,已经很久没有更新了,这里只是为自己打个广告,重点是实现方式,代码和文档后续我会再跟进一下。
为啥这么多年我没有推 ACSS 呢?没有名气:joy:,你说的话就很少有人会静下心来听,更别提会去思考了。因为最近发的一篇文章在掘金上得到满多同学支持的,所以觉得可以蹭蹭热度,略微试着努力推一下 ACSS。
当然更主要的原因是,目前组件化思维正是当下最流行的时候。而 ACSS 是和组件化思维特别 Match 的一种方式。所以特别希望 ACSS 能被大家看到。我会尽自己最大的努力从不同的角度,写几篇文章,来帮助大家了解 ACSS。当然个人能力有限,如果不恰当的地方可以给我留言,我们一起探讨。用不用 ACSS 大家可以根据自己实际项目来定,但是这种思维方式,错过了真的是种遗憾。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。