css模块化思想初探
前言
前端模块化是个非常大的话题了,我们可以简单的分为html模块化、javascript模块化、css模块化;那么我们先从css模块化开始,css模块化基础却必不可少。希望能通过理解css的模块化,窥探出模块化的意义与思想。
提纲
当项目稍微复杂点的时候,项目迭代时,css的编写会让人痛苦不已,css模块化可以让项目中的样式,管理起来优雅、轻松。
本文仅解析css模块化
思想与技巧,构建工具
与动态样式语言
本身这两样是必不可少,篇幅有限就不展开讨论了。
事例中使用sass作为参考。
痛点
对于一个迭代周期长的复杂项目,甚至只是频繁更改的小项目(你懂的),样式的维护都是前端无法言说的痛。大致可以归于以下几类
- 选择器繁琐冗长
- 命名冲突
- 层级结构不清晰
- 代码难以复用
- ...
手段
解决这些问题的核心思想在于代码复用
,没有或者不用动态样式语言构建项目时,往往也能看到大家会提取出公共的样式,比如common.css、form.css、fxckpm.css等等。但是纯粹的靠css静态的文件结构重组,也只能是轻微缓解了以上的各个症状。
用公用样式,而各个公共样式对于不同页面来说,有可能太冗余,有可能还缺少许多东西,那么最终项目依然抵不过时间的摧残,慢慢狗带。
曙光
得利于构建工具和动态样式语言,css的模块化变得容易操作。
干翻一切的武器:@import,面向对象式的编码方式,变量、函数、继承等等。
这里要提一句的是,很早css本身就支持@import,但是生产环境里直接写在css里,对性能有影响,浏览器表现也不一致,具体问题请度娘谷嫂。
开始使用
说了那么多,接下来就从代码与项目结构上,逐步分析如何模块化。
我这里根目录为scss,下面贴出一个简单的模块化的目录结构。
PS:scss文件前加上下划线_
是表示此文件不需要生成对应的css文件。@import时可忽略文件名中的下划线直接引用
│ style.scss
│ _main.scss
│
├─base // 底层文件目录,组件的基本属性,最小零件单位的仓库
│ │ _reset.scss
│ │
│ ├─mixin // 定义@mixin
│ │ _border-radius.scss
│ │ _clearfix.scss
│ │ _flex.scss
│ │ _gradients.scss
│ │ _set-arrow.scss
│ │ _set-onepx.scss
│ │ _text-overflow.scss
│ │
│ └─variable // 元素的基本变量
│ _color.scss
│ _global.scss
│ _size.scss
│
└─widget // 组件 根据最小零件组合成的页面元素组件
_agree.scss
_animation.scss
_btn.scss
_effect.scss
_form.scss
解析
代码复用
依旧是我们最核心的目的,复用的同时要结构清晰方便维护,以达到所谓的模块化。
上面介绍了文件夹的结构,接下来我们分析一下各个目录结构代表了什么。
统一组件
我们从组件目录widget里开始分析,这里放的文件都是我们所需要的页面元素组件,有_btn.scss(页面按钮)_form.scss(表单元素)_animation.scss(页面动画)等等。
以 widget文件夹 下的 _btn.scss 为例
有可调用的class、id、animation 等等,生成后可以直接或继承使用。
这些组件高矮胖瘦谁来定义呢?事例中放在了base文件夹中。
基本属性
和属性相关的东西全部在base文件夹下。
以 mixin文件夹 下的 _border-radius.scss 为例
以 variable文件夹 下的 _color.scss 为例
这些文件定义了元素的基本属性,color、size、border等等。
只定义了元素的属性,不可直接使用。
这里需要注意的是,通常元素属性会分为两类:
variable是简单的变量定义如$red:#ff0000;
而mixin里放的是更为复杂的属性,如border,需要根据多个参数定义出此属性。
按需引用
widget里的组件只是定义了可复用的,统一的元素样式,还是需要进行补充、精修以供页面实际使用。上面_main.scss就是这个作用。
最后我们将页面需要的组件,加上对应页面UI做了补充和完善的_main.scss完成封装。
style.scss
@charset "utf-8";
@import "./base/reset";
@import "./widget/animation";
@import "./widget/btn";
@import "./widget/form";
@import "./widget/agree";
@import "./widget/effect";
@import "main";
style.scss文件即使我们最终需要的生成文件,最终的文件和补充文件可能是多个,本文只以一个页面需要引用为例,所以最后只有一个_main.scss和style.scss,实际情况下这可能是不够的。
深入技巧
简单的介绍了css模块化的实现。强化相关能力需要多看多想多做,拿到设计图时要多思考,不要抄起键盘就是干。多看看目前开源UI库的源码,如bootstrap、Foundation、material等等的源码,看看他们是如何组织相关文件。
在命名上也是非常需要注意的点,篇幅有限不展开。
请查阅: 编码规范:http://codeguide.bootcss.com/,
网易NEC:http://nec.netease.com/
本文的项目结构不具备代表性,针对不同的项目我们需要根据实际情况定制更加容易维护的模块化结构。
总结
如果你的项目中有十个甚至更多的页面,页面元素风格相同或相近的,那么你可以用模块化的思想,写一个定制的UI库。以后若此项目页面风格主题更改时,那么你可以选择殴打产品经理让其撤销需求,或者只需要添加新组件、修改某些变量即可优雅的完成迭代工作。
欢迎讨论,欢迎大佬焦作人!