【UI开发大观】一份友好样式的缘起与归宿

前阵子写了篇文章,记录参加第四届CSS大会的见闻,里面有个话题——“我不想写CSS”,谁曾想,有同行抓住我就问——“我的确不想写页面,设计给的视觉稿里面很多字体大小和颜色,不胜其烦,关于多页面的样式,你们是怎么管理的呢?”

真是前人挖坑,后人栽树~开个玩笑。

这个问题没有标准答案,一个公司的不同部门,一个团队的不同个人,都会有不同看法和做法,所以,本文所述,仅代表我个人的经历和经验,试图给大家一个合理的方向。

缘起

CSS是一门略显尴尬的编程技术,通过选择器和属性的堆砌,就能让页面更加整齐和漂亮,你可以什么都不讲究,但是,什么都不讲究显然不是程序员的脾性,程序员向来追求“美”~所以,这个话题得先从设计说起。

一个项目或者产品,外观设计到功能设计应该是一体的,样式主要负责外观。

外观是一种基本的审美,每个人都有分辨美丑的能力,就是那种批量生产的建站公司都知道,颜色和风格需要跟站点分类相称,网页和网页之间的风格需要统一,一个logo,一种颜色,就是一款产品甚至一个公司的标志。

所以,网页始于设计,那么从视觉到页面需要一个怎样的过程?

审思

有人喜欢先写结构后写样式,有人喜欢同时写,这看个人习惯,也看娴熟程度。

但不论怎么写,最好都先进行审视:它是什么风格?产品,活动,介绍,游戏?

这就决定了页面是静态元素居多,还是动态元素居多,是文案居多,还是图片居多,或者图文混排。

然后在脑海中对其进行区域和类型划分:(示例)

头部:导航和banner,或者logo和banner、slogan等。

中部:介绍、资讯、产品等。

底部:底部导航,或者版权信息、小提示、跳转链接、二维码等。

粗分之后是细分,这里的细分是:

1、公用部分——包括背景、边框、阴影等。

2、同类元素——标题、正文、按钮、图片、图标。

3、是否有交互和不同状态——展开/收起、弹出层、小动画、作废/过期/空/不可用状态。

这样就有了规划样式的大概思路:Reset——公用样式——个性化样式。

这里是要利用好样式表的层叠特性,以避免样式冲突,也避免为了修正错误无谓地增加权重。

还有另外一个需要注意的问题,以怎样的策略进行命名?这个问题,看似头疼,可以回想一下,我们给它们归类是按什么分的呢?——视觉效果,所以,命名时依然如此就好,这样以来,更可读,也不会与内容紧密相关,提高了复用性。(某些情况下这样也会有隐患,暂时不讲)

应变

完成了前面的事情,问题大都解决了,但是,随着页面越来越多,样式文件也越来越大,会带来两个问题:

  • 文件加载速度变慢
  • 人工维护成本增高

怎么办?分组。

标准有两种:业务类型、文件类型。

将不同业务的html、css、js、图片,都进行分拆,只共用全局通用的部分,相互之间不依赖、不影响,减小单个文件大小的同时,使每部分文件更易维护。

这一次的分组,看起来是应需而变,但它又何尝不是跟“审思”的过程相辅相成?进行了这一步之后,第一步就不单单是根据视觉元素来规划,还要加上分组情况,比如,属于哪个功能/业务模块的,应该放到哪里,它是属于之前的某个大的文件,还是需要单独新建。

封装

分类完成之后,貌似还是不够,还可以做点什么呢?

如果把一个网站比喻成一台机器,它就是由很多部件组成的,同样一种部件,可能在不同地方反复出现,可以作为组件被分出来。

比如,我们现在抽离出来的组件有:按钮、弹窗、图标、表单、箭头等。

组件的样式代码会被添加到公用代码文件里,这样的话,样式只要写一次,就可以到处使用。

要特别注意的是,这些组件的命名是跟上下文无关的独立存在,这样不会跟任何特定项目产生牵连,还能够利用作用域进行特异化改造。

组件分离了之后,还有什么可以分吗?答案是肯定的。

粒度

为什么还要分,其实到了这一步,才比较接近那位朋友提的问题,当文件和代码都已经组织得足够好,还会为什么而头疼呢?

工程师最喜欢的是相同,而设计师喜欢制造不同。

设计师:“这个字体能大一点吗?”“这几个字能突出一些吗?”“这里能不能加个圆角?”

你:“你就不能统一一下吗?这么多种我很难做啊!”

矛盾在哪里?

工程师有代码洁癖,想用最简洁干净的代码,写出高质量页面。
设计师有创意欲望,在整齐划一的基本审美前提之下,还肩负着“特色”使命。

  • 都是白色界面,出现一个黄条,肯定就更能吸引眼球,用来放一些“警示/公告”之类;
  • 都是黑色字体,中间加个红色、蓝色或者橙色,就会让人明显注意特殊字眼;
  • 都是文字,有大号、中号和小号,就能增加层次感,也能帮助用户分出主次。
    等等

怎么办呢?举我们组为例:

字体大小,有这么几种定义,超小、小号、正常、大号,超大,分别对应:10px、12px、14px、16px、18px。

首先它们牵扯到的属性很少,或者所要完成的使命很单一。

再者,可以用在你实在不知道该如何命名或者没必要占用一个类名的地方,如果把它们划归到具体模块或元素里面,每次重复书写,还要多个类名,还要多层嵌套选择器,就显得得不偿失,因为你只是控制一个很通用的属性,却新加了两个需要维护的地方。

同理:一像素边框、水平垂直居中、不同字体颜色、清除浮动、flex布局、文字溢出省略等等,都可以抽离单独的类来解决。

关于这种方法,知乎有个话题专门讨论,https://www.zhihu.com/question/22110291 有人反对,有人赞同。

有人说难维护,事实上,你可能写了就没改过;

有人说背离了结构和样式分离,实际上它又恰恰利用了表现和内容分离。

忽略一种方法的优点或者故意放大一种方法的缺点去否定它,就是为了否定而否定,是没有积极意义的。

我还是搬出那句话,脱离实际的最佳实践就是耍流氓。在谈设计模式的时候我就分享过,只用和不用某一种都是武断的,应该博采众长。

根据自身业务的代码积累、迭代,进行不同粒度的样式抽离,是非常明智的做法。当然,还可以使用预处理器来进行更加通用和灵活的改进,这里不多说。

所以,最终的结论是:

从源头开始规范化,在视觉素材的基础上进行布局和规划,根据业务和功能的不同对文件进行分组,针对不同频次和范围的规则去划分粒度,应用合理的命名方法减少联动影响。

遵循此法,便能写出一份还不错的样式文件吧。

时间空间有限,不能涵盖所有情况,有问题再具体交流。