当前位置: 首页 > Web前端 > HTML5

如何写一个轻量级的CSS框架

时间:2023-04-05 19:46:39 HTML5

Github:https://github.com/nzbin/snackDocs:https://nzbin.github.io/snack前言这篇文章我酝酿了半年,还是拖拖拉拉的这么久了有很多话想说,却又无从谈起。如今,轻量级框架如雨后春笋般涌现,层出不穷。我觉得大家应该总结一下工作中常见的需求,写出适合自己的CSS框架。在之前的文章中,我提到了面向对象的CSS(比如BEM、OOCSS、SMACSS,详见http://vanseodesign.com/css/d...)。这是一个思路,不涉及具体的CSS问题,主要是类命名的策略!还有很多人对前端框架的了解还很肤浅,认为Bootstrap只是给后端人员用的,不需要前端之类的。我不知道这个说法是从哪里来的。一开始我不喜欢使用框架。可能是害怕新知识,害怕难以掌控,害怕遇到问题无法解决等等。最重要的一点,很多人认为框架的风格是固定的,修改起来太麻烦。最好按照设计图来写。为什么使用框架为什么使用框架?答案很明显,效率。此外,使用框架或研究框架还有很多意义,比如面向对象思想的具体实现。在上一家公司工作的时候,我也是用最原始的方式为前几个项目编写CSS。项目中最让我头疼的就是类的命名。我觉得大部分人都是按照功能来命名的,这样就造成了很多冗余,同一个组件可能会写很多次。举个简单的例子,如下图,个人中心的登录界面。包括我在内的很多人一开始可能会选择下面的类命名和布局方式,通用性很差      

    请点击登录  
不过了解Bootstrap的人应该一眼就能发现,上图是一个media对象,无非就是一些需要调整的小细节
请点击登录在为了让文字和图片居中,我们可以使用Bootstrap的.media-middle辅助类。如果在工作中需要根据自己的需要自定义一些辅助类调整细节,当然这是移动端的例子,可以选择移动端框架相关的媒体对象。另外,项目改版的时候,修改原来的方法更是惨不忍睹,可以说是一场噩梦,冗长的CSS文件,混乱的功能划分,类名,颜色值等等。最后,只能硬着头皮一点一点修改。那一刻,我意识到了框架的意义和前端工具的重要性。我从工作中得出的结论是,要么你可以熟练使用某个框架,要么你自己实现一个框架。前端框架对比目前市面上的前端框架主要分为重量级和轻量级。重量级的主要有Bootstrap、Semantic、UIkit、Foundation等,轻量级的有Pure、Skeleton、Miligram等。经常关注前端动态的工程师会发现,轻量级框架每年层出不穷。除了我上面提到的主流轻量级框架之外,还有很多类似的框架。我一直在问自己,为什么要重新发明轮子。经过研究,我发现这些轻量级的框架,其实大部分都达不到工作要求,模仿的痕迹很重,基本上都或多或少有Bootstrap的影子。那么这些轻量级框架有意义吗?当然有。但是在我个人看来,选择一个轻量级的框架不如自己实现一个框架。因为大多数轻量级框架就像是工作总结,根据自己的业务需求来实现。所以它们中的大多数都不是通用的。前端框架的比较主要是Bootstrap、Semantic、UIkit,因为个人觉得这三个最有代表性,它们的设计风格各有特点。Foundation也被很多大公司使用,但个人认为,无论是框架的易用性还是设计风格,都略逊于其他框架。其中Bootstrap和Semantic是面向对象最好的体现。先说说Bootstrap的优点,不是设计风格,不是模块,不是特效,而是网格,响应式网格。与其他框架相比,Bootstrap的网格具有绝对的优势。无论是网格的划分还是类名的样式都很经典。如果读者看一下Bootstrap的Less源文件,就会感受到Bootstrap对于响应式网格的独创性。其实在Bootstrap之前有很多网格解决方案,但是感觉不够工整,类名比较繁琐,不好记。而后来的很多框架,尤其是轻量级框架,大多都有Bootstrap的影子。下面通过几个框架的grids和buttons的对比,来看看类的命名策略。引导程序按钮语义PrimaryFoundationPrimaryUIkitPrimaryPureAPrimaryButton通过上面的对比,你应该发现了这几个命名策略的区别frameworks不可否认Bootstrap的命名是最经典的,之前在网上看到有人讨论框架的易用性,也有人说Bootstrap的类名太长了,但是通过比较以上框架,Bootstrap的类并不繁琐,使用了预处理器的嵌套,写框架的时候会更加灵活,Semantic的类名最为简洁,通过修饰成句真的很有意思多个属性。但是修改类太多,写框架的时候会有点乱,有利缺点,因人而异。Foundation的grid应该是最丰富的,在策略上类似Bootstrap,但是公共属性是拆分的,也可以看看具体的细节。UIkit和Pure的策略相同,都添加了前缀来区别其他框架,但显然类名过于冗长。写框架的时候也是这么想的,最后放弃了这样。关于CSS预处理器CSS预处理器并不是什么新鲜事物,但是又有多少人能够真正在工作中使用它呢?有多少人精通使用预处理器功能?我工作的时候并没有用到预处理器,因为没有用到,所以没有实现预处理器。好处。主要是比较麻烦,因为需要用编译器编译,直接写css没有那么方便。但是当项目维护的时候,我才意识到预处理器的好处。后来在几个项目中尝试了预处理器,但是模块化的写法不是很清楚。预处理器作为一种工具,可以实现CSS的模块化编写,那么模块应该如何划分呢?另外,预处理器有很多特性,但大多数人一开始只用到变量和嵌套,其他特性很少用到。相信在自己实现一个轻量级框架的过程中,能够对预处理器有一个全面的了解。目前比较流行的预处理器有Less、Sass、Stylus三种,首先,选择哪一种完全看自己的习惯。最开始接触Less是因为Bootstrap,后来因为习惯选择了Sass。其次,Sass的功能更全面。无论是工作还是自己写项目,都必须搭建项目环境,也就是安装一系列的npm包。与刀耕火种的开发方式相比,工具开发的准备过程有点麻烦。但是一旦环境搭建好了,后面的开发就很容易了。Miligram,一个轻量级的框架,在Github上很流行,但是说实话,用处不大。但是框架的构建方式非常值得学习。虽然CSS对很多人来说很简单,但是写一个框架还是很棘手的。这个时候就需要借鉴一些优秀的框架。会用来写框架的npm如下:--autoprefixer--node-sass--npm-run-all--rimraf--onchange其实最重要的是一个node-sass,还有其他都是辅助CSS文件生成修改,有兴趣的可以去npm官网搜索这些插件了解具体用法。有不懂的可以给我留言,我就不啰嗦了。写一个轻量级的框架终于到了本文的重头戏。简单介绍一下,我把自己写的框架命名为Snack,本意是“快餐”,主要表达简单的意思。虽然是轻量级的框架,但我不想把轻量级当成噱头。毕竟,轻量化意味着某些功能的缺失和遗漏。这个框架的意义更多的是交流和学习。我尝试学习其他框架的优秀之处,尽量简化类名,尝试探索一些更通用的组件。大多数轻量级框架只是CSS框架,不涉及JS部分,主要用于网页的布局。之所以打算自己写框架,是因为工作中重复的东西太多了,而这些分散的组件可以通过框架很好的整合起来。另一方面,编写一个小项目并学习新东西很有趣。写框架是我去年就想做的事情,但是由于时间原因,拖了很久。刚开始写框架的时候,陷入了一个误区。本来打算设计一些比较前卫的风格,比如立体按钮,悬浮面板等等,比如下图中的风格。https://dribbble.com/shots/524593-Soft-Interface-Black但是在断断续续写框架的过程中,渐渐的找到了方向。上图中的样式只是一个皮肤。刚开始写框架的时候,重点不应该放在这上面。当然,好的UI设计也是框架成功的一部分。模块划分编写框架的第一步是确定框架应该包含哪些模块。因为是轻量级框架,模块肯定没有重量级框架全面,只有一些核心组件。通过比较一些轻量级的框架和工作总结,常用的模块包括grid、media、button、typography、form、table、panel和辅助工具。在常用的组件中,需要重点关注网格、表单和面板。媒体组件也很重要,但自由发挥的空间不大。我直接使用了Bootstrap的媒体组件。命名策略从类命名的层次结构开始。类命名一直是我纠结的地方。刚开始工作的时候,总是绞尽脑汁想出一个既熟悉又简洁的类名。我在写框架的时候尽量避免和Bootstrap的类名重叠,但是也不能完全避免。对比其他框架,我们会发现这种情况是不可避免的。毕竟类名会有一定的规律性和层次性。在这一点上我更喜欢Bootstrap的风格。我们拿Bootstrap的形式做个对比。Bootstrap的表单结构和类名--div.form-horizo??ntal--div.form-group--label.control-label--input.form-controlSnack的表单结构和类名--div.form-horizo??ntal--div。form-item--label.form-label--input.form-field这个表单结构总体来说还不错,就是有些地方需要修改一下。有些框架不给输入等元素起类名,而是给父元素起类名。就我个人而言,我对这种方法持怀疑态度。没有类名会降低框架编写和使用的灵活性。第二种策略是修改组件。例如,按钮和面板有多个上下文(颜色、大小等)。至此,我在写框架的时候做了一些简化,风格上有一些Semantic的影子。primary......关于修改class最好的策略是众说纷纭。至于哪种方法更好,需要在写框架的过程中摸索。网格系统演示示例:https://nzbin.github.io/snack/#grid任何框架都必须基于网格才能拥有灵活的布局。前面提到过,Bootstrap的本质是网格系统。网格系统的编程需要使用预处理器的循环功能,否则会造成不必要的重复工作。我遇到过一些用Less写的轻量级框架,网格系统没有使用循环。这样的源码有点突兀,可能作者对Less的循环函数不熟悉。当然,Less本身的循环是比较弱的。使用起来有点别扭。关于预处理器的循环,可以参考我之前翻译的《CSS 预处理器中的循环》,比较详细的比较了三种流行的预处理器的循环功能。简单的说,Less没有循环,但是可以用递归来实现,而Sass和Stylus有真正的循环。我写的网格系统也是默认12列的,后来发现12列的网格缺少最常用的列宽(比如10%、20%、30%等)。比如下面CodePen展示的例子,使用12列的网格是做不到的,所以我又在网格中加了10列,还是不够全面,但是足够灵活了。看Pensnack-grid网格的使用和Bootstrap一样。除了12列格子外,还要加上10列格子和均分格子。cols-class这个网格不是响应式的,只有一个断点,所有网格在小屏手机上会显示在一行中。一方面,这种设计符合大多数轻量级框架的初衷;另一方面,我打算再写一个移动端的框架。毕竟web端和移动端的风格差别很大,还是根据业务需要分开比较好。但是最近我更改了源文件以保留响应性的扩展方法。表单演示示例:https://nzbin.github.io/snack/#forms在上面的命名策略中,已经展示了Snack表单的基本结构。除了结构之外,关于基本形式的风格就不多讨论了。.这里先说下表单中checkbox的结构调整,先看Bootstrap的checkbox结构。checkbox上面两个结构不能有偏差,有的话样式会乱稍有偏差,弹性差。其次,我在思考是否可以将这两种结构结合起来,增强灵活性。想了半天,找到了办法。Snack的结构如下:也可以直接给标签添加样式标签。另外,如果input移到label标签外也没有问题,如下:checkboxcheckbox这种结构有个好处,就是可以自定义输入样式,具体见下面的CodePenscss文件。radio的设置与checkBox相同。参见Pensnack-forms辅助类辅助类是字体大小、颜色值、padding、margin、左右浮动等一系列类的组合。在一些Bootstrap搭建的后台管理系统中尤为常见,这样布局会更加灵活。以下是边框的辅助类。.border-left-right{border-left:1pxsolid#eee;border-right:1pxsolid#eee;}.border-top-bottom{border-top:1pxsolid#eee;border-bottom:1pxsolid#eee;}.border-left{border-left:1pxsolid#eee;}.border-right{border-right:1pxsolid#eee;}.border-top{border-top:1pxsolid#eee;}.border-bottom{border-bottom:1pxsolid#eee;}辅助类的更多信息可以看这篇文章《如何编写通用的 Helper Class》box组件demo:https://nzbin.github.io/snack/#boxesBoxes是我整个框架中比较满意的一个模块。制作这个组件的主要原因是可以将Bootstrap的列表组件和面板组件集成在一起。当然,这种方法有利也有弊。盒子组件在后台管理系统的布局中尤为突出。它的命名也多种多样,有panel、widget、portlet、ibox、card等,各个后台管理系统框架都会对这个组件进行深入开发,可见其在布局上的重要性。给组件一个合适的类名也很重要。想了很久,最后还是用了box这个类名。当然一般情况下尽量不要用box,因为这个类名比较宽泛。下面的CodePen模拟了Bootstrap的列表和面板组件。查看Pen零食盒主题为框架设置主题很有趣。Snack默认的主题是白色的,因为我喜欢黑色,最后加了个暗夜主题。写一个主题,只需要改变组件的颜色。演示文档页面使用暗夜主题,点击上方红色按钮切换主题。总结如果你问我哪个框架更好,我会毫不犹豫地选择Bootstrap。在工作中,可以根据需求的难易程度来选择框架。如果业务比较重,最好基于Bootstrap进行二次开发;相反,你可以选择一些轻量级的框架。最好根据自己的需要造轮子。如果您愿意选择或借鉴我的框架将是我的荣幸。