当前位置:

管理 CSS 类库 / 内裤

访客 2024-04-24 466 0

修正于2018-10-21。为了文章生动,之前用了太多过于夸张的修饰手法,以至于让很多朋友忽略了内容本身。基于网友的评论和指出的不足。略微修改了文风,删除了多余的废话,梳理了文章大纲。

命名是我认为CSS里最难的问题没有之一。

CSS是一个不强调逻辑,而更侧重表现的一门所见即所得的语言。你写了一个属性它就有一个样式,就好比嗑瓜子,你每嗑一下都能及时的得到一个奖励。这种愉悦感是别的开发语言所不具备的。

CSS也不像其它侧重逻辑的语言,有比较多的代码管理方式。你能管理CSS的工具只有两个,一个是文件引用,另一个是命名。通常为了减少页面HTTP的请求,我们会尽可能的将CSS文件合并。于是靠文件引用这个方式来管理CSS的这条路也就显得特别的窄了。

我们都知道CSS的作用域是全局的,只要你引用了一个CSS文件,它就会影响你整个页面。于是,CSS代码管理的重任就全压在了命名这一条路上。

所以简单的说,你能搞定CSS的命名,就能管理好CSS。

管理CSS就好比管理“内裤”

对于CSS的管理,我这边举个不恰当但是很贴切的类比,就是类似于日常生活中内裤的管理,是的就是日常穿的内裤,和CSS中的“类库”谐音(我太有才了)。

前面有讲到,对于CSS的管理我们基本只能通过命名的方式去管理。这听起来似乎是一件值得开心的事,因为只有一条路,所以大家都没得选。然而出乎我们意料的是,即使只有一条路,大家也是走得五花八门。

举个例子,比如我们有7条不一样的内裤,如果只用命名的方式去管理内裤,会出现多少种可能?

按日期按颜色按材质按花纹...
.星期一{}.红色{}.纯棉{}.格子{}...
.星期二{}.黄色{}.涤纶{}.横条纹{}...
.星期三{}.蓝色{}.氨纶{}.波点{}...
...............

就像一千个读者就有一千个哈姆雷特一样,不同的人对于同一件事物的命名方式是不一样的。因为对于自己喜欢和熟悉的东西,对于其它的人来说都基本上是不熟悉的。不信你可以问问你的同事,你们归纳和命名内裤的方式很大概率是不一样的。所以这个的可能性是无限的。

当然如果只有7条内裤,你和我的命名方式不一样就不一样呗,我只要能看懂基本也就还好。可是,当我们对于内裤的管理上升到了的概念的时候,一切就没有那么容易了。

假设你爸是挖矿的,你家很有钱。而你又特别喜欢买内裤,赤,橙,黄,绿,青,蓝,紫,彩色的,蕾丝的,莫代尔的,纯棉的,紧身的...各式各样的内裤共计100,请问你要怎么命名这100条内裤?

此时你会发现上面管理7条内裤的方式,任意一个方式都显得力不从心。所以要怎么办呢?

管理CSS“内裤”的通用方法

之前有讲到,管理CSS的问题就是CSS命名的问题。所以我们看看目前现有的最流行的解决CSS命名的通用解决方案BEM。

因为我不是BEM的拥护者,之前举的例子被网友评论打脸了,这边就直接讲结果吧。

.block__element--modifier{/**/}

很直观的可以看到引用了BEM之后,我们的CSS就有了,三级的作用域。这个怎么解释呢?

很简单,之前我们命名7条内裤的方式是一维的。但是用BEM之后,可以看作是一个长宽高各10的三维立方体。你要找一个东西,你只需要知道对应的长宽高对应的坐标就能找到。类似:

.长1__宽2--高3{/**/}

是不是一下子(指时间短暂或动作迅速)(指时间短暂或动作迅速)就简单了很多。BEM系统的解决了CSS的命名问题,并且它的维护性和拓展性也是非常棒。所以它是非常值得推荐的管理CSS代码的解决方案。感兴趣的同学可以下来自己了解一下。

这里呢,我是想说是我不喜欢BEM的点(感觉又要打脸了)。与其说不喜欢BEM,倒不如说我连CSS命名本身都不喜欢。为什么这么说呢?因为对我来说命名真是一件非常痛苦的事情。

在我写代码的时候经常会遇到这样的问题,有两个非常像的模块,但是它们又有些许的不同,为了公用他们相同的样式,你又必须将这部分抽象出来,可是抽象出来的这个部分,又不能倾向于这两者其中一个,你要怎么命名呢?就好比:

/*这个例子不是BEM的正确使用姿势,这里只是作为参考*/.柜1__屉2--内裤,.柜2__屉2--内裤{名称:贴身的下身内衣;大小:中号;颜色:粉色;}.柜1__屉2--内裤{适合性别:男;}.柜2__屉2--内裤{适合性别:女;款式:蕾丝;}<divstyle="柜1__屉2--内裤">一条内裤</div><divstyle="柜2__屉2--内裤">另一条内裤</div>

你想为上面这两条内裤公共的部分抽象一个通用的类,请问要怎么命名?然后更可怕的是,此时又来了第三条内裤:

.柜2__屉3--内裤{名称:贴身的下身内衣;大小:中号;颜色:红色;适合性别:女;款式:蕾丝;}<divstyle="柜2__屉3--内裤">又一条内裤</div>

然后你又发现,之前好不容易命名好的通用类名,不能用到这第三条内裤上。然而第二条内裤和第三条内裤又有了公用的部分,这部分是不是又可以进一步抽像呢?一旦抽象,就意味着又要取一个名字,然而此时你又该怎么取名呢?这次拓展两步,我的已经崩溃了。

当然在实际开发中,我相信大家有更优秀的命名方式,来解决这个实际的问题。这里只是用这种夸张的方式来证明命名是一件非常不容易的事情(不用较真我的使用姿势是否正确)。

你要的是内裤,不是内裤放在哪里

我们每次找不到自己内裤的时候,会本能问:“妈!我昨天穿的那条内裤在哪儿啊?”

妈妈通常会不耐烦的回答:“昨天不就告诉你了在第一个柜子的第二个抽屉,这样的问题你到底还要问几遍?”

.柜1__屉2--内裤{名称:贴身的下身内衣;大小:中号;适合性别:男;颜色:黑色;}

“第一个柜子第二抽屉”,这听起来很像BEM命名的的方式,当然它能非常简单直白的告诉你内裤放在哪里。

可是不知道大家有没有想过这样的问题,如果我们问:“妈!我昨天穿的那条内裤在哪儿啊?”啪!你妈妈直接就把内裤扔你脸上了,这种方式是不是才是我们更希望看到的结果。是的,要啥内裤坐标啊,直接把内裤给我不就好了。我要的是内裤,不是内裤放在哪里。

CSS是什么?CSS是层叠样式表,而class(类名)显然不是,它只是CSS和HTML之间的钩子

名称:贴身的下身内衣;大小:中号;适合性别:男;颜色:黑色;

这些东西,才是真正意义上的我们想要的“内裤”的样式。而.柜1__屉2--内裤只是一个告诉你“内裤”放在哪儿的坐标。

那在实际开发过程中,怎么样才算是想要内裤的时候,内裤就出现在我们手中呢?

<divstyle="名称:贴身的下身内衣;大小:中号;颜色:粉色;适合性别:男;">一条内裤</div><divstyle="名称:贴身的下身内衣;大小:中号;颜色:粉色;适合性别:女;款式:蕾丝;">另一条内裤</div><divstyle="名称:贴身的下身内衣;大小:中号;颜色:红色;适合性别:女;款式:蕾丝;">又一条内裤</div>

是的,通过style直接写CSS属性,就能简单粗暴的把“内裤放到别人手中”。而这也是我认为最符合CSS“所见即所得”的方式。

想要什么样式我就写什么样式,不用花时间去为我的样式创建一个自认为很好看,但是别人看不懂的类名。我也不用考虑命名污染的问题,因为根本连命名都没有。也正因为连命名都没有,所以也不需要纠结上面提到的任何关于命名让人头疼的问题。

只是因为我们大家都太习惯创建class了,导致我们在写样式的时候,第一步想不是样式本身而是创建一个class。在我看来这是有一点本末倒置的。

总结一下就是:当我想要“内裤”的时候,我希望的是“内裤”就直接出现在我的手里,而不是得到一个能精确告诉我“内裤”放在哪里的坐标。不管这个坐标的命名规则听起来是有多么的好。

一旦有了命名,我在管理100条“内裤”的同时,还得管理比“内裤”本身量级更复杂的这100个类名。

管理内裤的原材料而不是内裤

我们之所以会需要去管理代码,很大一部分原因是因为我们想要去复用它造成的。简单的来说,现买现用,穿完就扔的内裤,是不需要你花时间和精力去管理的。

上一节中我们放弃了复用样式这个想法,利用inlinecss,在解决代码管理问题的同时,还得到了一种将重心聚焦在CSS样式本身的编程体验。

正是因为我们放弃了命名,所以才解决了代码管理问题,可是想要复用就必定意味着要命名。这听起来似乎是一个悖论。

那有没有一种方式是可以跳出这个怪圈的呢?答案当然是有的,那就是放弃管理“内裤”,而是转向去管理“内裤”的原材料。我们将之前需要管理的100条内裤的原材料列举如下:

  • 布类型:棉,麻,涤纶,氨纶,莫代尔...
  • 颜色:赤,橙,黄,绿,青,蓝,紫...
  • ...

基于之前的例子,我们现在的代码会变成什么样的呢?

<style>.贴身的下身内衣{}.中号{}.男{}.女{}.黑色{}.红色{}.粉色{}.蕾丝{}</style><divclass="贴身的下身内衣中号粉男">一条内裤</div><divclass="贴身的下身内衣中号粉色女蕾丝">另一条内裤</div><divclass="贴身的下身内衣中号红色女蕾丝">又一条内裤</div><divclass="红色">一匹红色的马</div>

首先,因为这些原材料都已经是不能拆分的最小单元,所以他们的名字能非常容易的固化下来,形成一个通用的“类库”。每次创建新项目的时候,你只需要略微的修改就可以复用起来。

虽然为了解决样式复用的问题我们还是有创建类名,但因为这些命名是不可以拆分并且容易固化的,所以管理的难度会小很多。并且随着,时间的推移,原材料的膨胀率是非常小的。组件化如果做得好,原材料甚至可以做到只减不增。

更惊奇的是,这些原材料可不只用于内裤上,它还可以应用到衣服,裤子,鞋子...等等一系列的东西上。你甚至可以用这个原材料,把一匹马涂成红色。这就是我们视角改变了之后,整个思维方式的巨大改变。而是将复用发挥到极致。

这种将样式原子化的思维方式,是来自雅虎团队的AtomicCSS(简称ACSS)。毫不吹嘘的说,基于这套理论,我是我遇到的前端程序员中CSS原型稿写的最快的程序员(可能我认识的人本来就不多)。

在这里有必要解释一下,我全篇所有的论证都是基于“库”的概念的。如果你只是创建一个简单的运营活动页ACSS那你只能用到ACSS这一个特性,而它更大的优势代码管理这一块是体现不出来的。

因为组件化思维正是当下最流行的时候。而ACSS是和组件化思维特别Match的一种方式。所以特别希望ACSS能被大家看到。当然个人能力有限,如果不恰当的地方可以给我留言,我们一起探讨。

内裤是工业品不是艺术品

到这里可能有的同学会说,你这个原材料拆分的明显没对,布类型不是还有竹炭纤维,甚至太空材料的,颜色还有红蓝渐变或者五彩斑斓的黑。

对于我们大多数男性程序员来说,内裤无非就是棉的和不是棉的两种,颜色无非就是黑,白,灰。即使不是程序员,你也很难会发现,普通的人会买到,赤,橙,黄,绿,青,蓝,紫这么多种颜色的内裤。

举这个例子是想说明什么,内裤是工业品而不是艺术品。工业品注定会控制原材料的种类以降低成本的。而真正会把内裤当艺术品的人,也就不会因为没钱,而不会去考虑复用内裤的问题。

在我们网页的开发也是一样的,如果你的网站不是走艺术类的网站,你却发现你的原材料提供商(设计师),光是从颜色上就给你提供了超过了十几二十几种颜色,那他一定是有问题的。

如果你的设计师,是对自己的设计语言是有极致约束能力的,那对于我们开发者来说这真的是一件非常开心的事情。

相关阅读
  1. quickLayout.css-快速构建结构兼容的web页面@张鑫旭
    男神作品,强推;
  2. 「英」在组件化浪潮中重新思考CSS@johnpolacek
    虽然是英文,但是网页做得像PPT一样,通俗易懂,强推;
  3. 「CSS思维」组件化VS原子化@ziven27
    我的一篇专门解释“组件化思维”和“原子化思维”区别的文章;
  4. ACSS官网@雅虎
    这个思维最早应该是雅虎推出来的,最近他们有在推ReactACSS
  5. 关于HTML语义和前端架构@大漠;
  6. 「译」CSS通用类和“关注点分离”@adamwathan;
  7. 「英」StylingReact@SURVIVEJS;
  8. 「英」CSS最佳实践探讨-AtomicCSS@smashingmagazine;
解决方案

更新于2019/10/22

名称NPMgithubCDN
@_nu/css-acss

讲了这么多,感觉都只是空谈理论。这边我多年的使用经验,总结的一个ACSS的npm类库@_nu/css-acss供大家使用。

对于ACSS,bootstrap,material-ui,github...都有相关的类库,然后整个**类库**最完善的属于tailwindcss。当然他们都是基于style-system理论创建的。上手成本相对较高,且往往需要设计师的介入。

和这些项目相比,我这边的方案,优点在于简单和极致的CSS开发体验。简单到整个逻辑只落点在命名规则,看完文档5分钟就会用,甚至完全理解所有的逻辑。极致的CSS开发体验,体现在熟悉这套规则之后,你会开始怀疑,你的手指速度慢于你思考CSS的速度。

当然为了追求简单和开发体验这也是缺点,就是不够完善,没有处理类似hover,focus...等中间态,也没有添加任何自定义的响应点。这部分需要大家基于自己项目和命名规则自由扩展。

发表评论

  • 评论列表
还没有人评论,快来抢沙发吧~