CSS架构的理想与现实

本文基于工作学习与交流,做的整理笔记
当我们在搭建一个项目的时候,我们考虑的一个主要部分就是CSS架构问题。每当我们做完一个项目的时候,我们去不断维护一个项目的时候,让我们感觉到无比头痛的还是CSS架构问题。上周,在公司前端组内发起了一次关于“CSS架构”的探讨。结合自己的理解,整理后的内容如下。

前提条件:
只要会CSS就行,这里只是讨论如何让项目中的CSS更理想。

编码环境:
系统:OS X EI Capitan
版本:10.12.5

CSS Architecture.png

目录
| - 0.背景
| - 1.现有框架
| - 2.理想架构
| - 3.项目中实际问题
| - 4.结构梳理
| - 5.命名规范
| - 6.构建工具
| - 7.待讨论问题
| - 8.结束

由于当天有临时工作需要,并没有参加公司内部的这次讨论。我是在会议后阅读各位小伙伴为这次讨论准备的文档,以及正常讨论的会议纪要。文中内容的书写过程为:先进行个人思考,然后阅读小伙伴的文档和纪要,再进行内容优化及调整。

0.背景

当我们准备搭建一个项目时,以及做完一个项目进入到维护期时,我们都需要注意和思考的其中一个问题,就是关于CSS的问题。

项目开始前,我们思考:
该如何对一个项目的CSS进行架构,结构如何,命名如何,构建工具如何?

我们理想中的架构是怎么样的,而现实中我们遇到的实际问题,导致最终呈现出来的结果又是怎么样的。

1.现有框架

现在社会中常说的一句话就是“前端圈真乱”,各种前端脚手架、构建工具、UI框架层出不穷。说说UI框架,常用的就有Bootstrap,Foundation,Pure,Ant-Design,Semantic-UI,Material-UI,Element-UI,WeUI等等,好多好多,它们分别适用jQuery,React,Vue,Angular,WeApp,以及针对移动端等等。

每次我们在项目使用的时候,总有组件没有场景使用,也总有组件满足不了我们的需要,我们便开始在框架的CSS基础上不断扩展。

知乎上有个回答者说:“少用框架,会被框架绑架的。我觉得,用最少的代码实现轻巧的UI,才是王道”。大概我们理想中也是这样的,但是我们另一方面却还想快,项目的进度赶,找一个合适的框架就满足了这样的快。

2.理想架构

大概每个前端的心中都有一个理想架构,那个架构是随着开发经验的累积,不断优化,不断清晰的。那到底,我们想要的理想架构具有哪些特点?

  • 结构清晰,一目了然,符合通用性,看后能马上清楚定位
  • 命名规范,语义清晰,能分清全局还是局部,用在什么场景
  • 低耦合,一方面是css类之间的耦合度降低,另一方面是和html代码之间的耦合降低
  • 高复用,可扩展,多处可以使用,又可以轻易抽离

后面2点,其实不太好理解,甚至是有些矛盾。我们在实际应用中,不经意间就会加强类和类之间的耦合,会渗透污染,变得不易维护。高复用带来的是不敢轻易修改,因为不确定影响范围有多大。

查阅一些文献文章,我看到一些比较好的建议。一起看一下,在书写css的时候,我们应该避免哪些问题。以下用法应尽量避免,从而降低维护难度,不建议使用:

  • 基于父组件来修改组件
.widget {  
  background: yellow;  
  border: 1px solid black;  
  color: black;  
  width: 50%;  
}  

//错误的
#sidebar .widget {  
  width: 200px;  
}  

//正确的
.widget-sidebar {
  width: 200px;  
}
  • 过于复杂的选择器
//和html耦合太紧了,只要修改html结构必须要调整css
#main-nav ul li ul li div { }  
#content article h1:first-child { }  
#sidebar > div > h3 + p { } 
  • 过于通用的类名
//看起来没错,它阻止了样式影响相同类名的其他元素,被限制在widget元素内
//但是没有组织外部相同类名可能会影响它
.widget {}  
.widget .title {}  
.widget .contents {}  
.widget .action {} 

//如果外部有如下这个样式,则会污染它
.title {}
  • 一个规则做太多事
//这个规则既控制了位置,又控制了外观
//外观一般可复用,但位置不行
.widget {  
  position: absolute;  
  top: 20px;  
  left: 20px;  
  background-color: red;  
  font-size: 1.5em;  
  text-transform: uppercase;  
} 

3.项目中实际问题

项目中,我们遇到最头痛的问题就是“越维护,越臃肿”,到最后,自己都不想看,想整理重构却又觉得时间不够,有心无力到放弃。

首先,我们按照分析事情的逻辑法则“谁、怎么样、为什么、怎么办”去看一下,我们去想想为什么会发生这种事:

  • 贪图快,就修改一点样式或增加一点样式,随便扩展或增加一个class就好了
  • 修改样式时为了避免影响其他地方的样式,我们只能.class .class对某一个样式进行扩展,甚至使用!important去强制
  • 命名不规范,结构混乱,自己都很难找,很难确定
  • 还有可能是设计师的锅,到处都不复用,到处个性化
  • ...

可能还有好多原因,反正不知不觉间我们就埋了一个大坑留着日后自己跳进去。那个坑随着项目的页面增多、功能迭代,越挖越深,最后无力应对。

我们是否有一些好的原则,去应对导致这一结果的原因:

  • 结构合理,命名规范
//这个是一开始就要考虑的问题,在执行过程要严格的遵守
  • 专注,也就是类直接控制某一个元素的效果,这样容易预测,不会因为混乱
//不好的方式(容易引起混乱)
#main-nav ul li ul { }  
 
//直接(可预测)
.subnav { } 
  • 模块化
//常见的就是使用页面类、容器类做限制
  • 给类进行命名空间
//不好
.widget { }  
.widget .title { }  
 
//好
.widget { }  
.widget-title { } 
  • 创建修饰符类来扩展组件
//不好
.widget { }  
#sidebar .widget { }  
 
//好
.widget { }  
.widget-sidebar { } 

4.结构梳理

一般按照文件的分类进行结构划分,大致如下:

   |- style.sass  入口
   |- _variable.sass  变量类
   |- _normalize.sass  重置类
   |- _base.sass  基础类
   |- _layout.sass  布局类
   |- _mixin.sass  mixin
   |- _media.sass  媒体类
   |- _theme.sass  主题类
   |- component  组件
      |- index.sass  入口
      |- _alert.sass  警告
      |- _table.sass  选项卡
      |- ...
   |- page  页面/模块
      |- index.sass  入口
      |- _dashboard.sass  看板
      |- _user.sass  用户
      |- ...

具体根据自己的架构调整,没有一个标准。

5.命名规范

我们给自己的项目制定一套命名规范,其实就是希望能够更有逻辑的命名。这里,可以去阅读部分UI框架的命名,去参照。比如命名规范如下:

  • 以‘-’为主,不建议过多‘-’,最多3个
  • 配合‘--’表示分类
  • 配合‘__’表示内部标签

我们通常把css分为几类,比如基础(base)、布局(layout)、模块(modules)、状态(state),以及JS使用的钩子类。要么通过前缀区分,要么通过结构实现。

再进行类名的命名时,我们还应该避免比如fs-14fs-16p-20等命名,原因是那样子后续修改维护可能会带来困难。比如之前引用fs-14的所有地方,我要把字号变成16,你需要修改所有引用的class,还是把fs-14直接改为font-size:16px。所以,应该通过更具备语义化等命名,比如:

  • size (xs/sm/md/lg)
  • status (default/primary/warning/danger/success/info)
  • color (dark/gray/purple)

命名举例,以tab组件为例:

.ui-tab         代表正常大小
.ui-tab-title   代表内部title
.ui-tab-content 代表内部content
.ui-tab__span   代表内部的span
.ui-tab__icon   代表内部的icon
.ui-tab--lg  代表大型
.ui-tab--sm  代表小型
.ui-tab--xs   代表超小型

6.构建工具

构建打包,这里就不详细说明了,比如使用grunt,gulp,webpack等等都可以,萝卜青菜各有所爱。

7.待讨论问题

遗留了一个关于类命名的争议点,就是如何去在OOCSS和BEM两种命名方式中去做取舍,去取一个平衡点。

8.结束

这篇文章主要讨论了一下CSS架构的相关问题。可以说,我们想的是一回事,但在实践中可能为了某些方便、快捷、或者是潇洒任性,我们慢慢的就跑偏了,这是理想和现实差距。不管怎么说,通过这样一次讨论,我们又开始留意到某些东西。那些曾被我们忽视的细节,再次引起了我们的注意,我们会一步步让项目的CSS架构优化,不断贴近可维护、可扩展的目标。

如有不对的地方,请留言指导,谢谢。

到这里,就先结束了。


学习是一条漫漫长路,每天不求一大步,进步一点点就是好的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,616评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,020评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,078评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,040评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,154评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,265评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,298评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,072评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,491评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,795评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,970评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,654评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,272评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,985评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,815评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,852评论 2 351

推荐阅读更多精彩内容