掌握模块化开发的思想是我们进行模块化开发的基础。他有以下几部分组成:
1.css模块化
2.html模块化
3.js模块化
模块化开发的优势
1.更好的组织和维护代码
2.按需加载
3.避免命名冲突
css模块化
css模块化编程语言
说到css的编程语言我们就需要了解一下css预处理器,它用一种专门的编程语言,为 CSS 增加了一些编程的特性,将 CSS 作为目标生成文件,然后开发者就只要使用这种语言进行编码工作。
css模块化编程语言的的种类
1.sass
2.less
3.stylus
4.Turbine
5.Swithch CSS
6.CSS Cacheer
7.DT CSS
……
现阶段流行的编程语言
1.sass(建议使用)
sass的最新版本scss,这个语言有和css相似的结构,直接用*.css文件改文件名为*.scss,就可以进行编译使用
2.less
sass编程语言组成
1.变量
2.嵌套
3.混合
4.继承
5.函数
6.运算
7.条件判断与循环
8.注释
使用的工具
1.命令行
ruby
安装使用教程:http://www.imooc.com/code/6389
2.可视化工具
koala
下载地址:http://koala-app.com/index-zh.html
使方用法:http://www.w3cplus.com/blog/777.html
css开发中的规范(BEM)
1.B(block):模块化
2.E(element):元素标签
3.M(modify):属性修饰
结构:
.block{}
.block__element{}
.block--modifier{}
详细介绍见 参考资料 BEM
参考资料和视频教程
css预处理器相关文档
http://www.w3cplus.com/bookmarks/css-preprocessor.html
sass
http://www.sass-zh.com/docs.html (官方文档跳转)
http://www.w3cplus.com/sassguide/syntax.html(文档)
http://www.imooc.com/learn/311(视频)
http://www.imooc.com/learn/436(视频)
http://www.imooc.com/learn/371(视频)
less
http://lesscss.cn/ (官方文档跳转)
http://www.imooc.com/learn/61(视频)
http://www.imooc.com/learn/102(视频)
BEM
http://www.w3cplus.com/preprocessor/getting-sass-y-with-bem.html
http://www.w3cplus.com/css/battling-bem-extended-edition-common-problems-and-how-to-avoid-them.html
一个页面由基本结构体构成:框架、模块、原件。
框架:是构成页面的基础结构,是页面的骨架。框架就可以描述出一个页面的基本轮廓了。如:index.html最外围有一个div(.g-index),页头(.g-hd),主体(.g-bd)。页脚(.g-ft)
模块:是页面上数量最多的,也是最重要的一部分,是代码复用的主体部分,模块就是按照功能划分的,如:导航栏、轮播图、登录窗口等。模块之间相互独立分布在页面上,嵌在框架的各个部分。构成丰富的页面。
一般常见的index.html,页头有导航栏模块(.m-nav),主体有新闻列表模块(.m-news),页脚有个版权声明模块(.m-copy-right).
元件:元件是独立的,可复用的。如一个按钮、logo等。
在某种意义上,元件也可以等同于模块。模块强调一个功能完整的整体,元件强调独立性。
如:index.html页面的导航栏放置一个logo(.u-logo)和登录按钮(.u-login_btn)。
其中框架元素命名以g-开头、模块以m-开头、元件以u-开头
语义化:
1、框架的命名以g-开头,如:index.html,框架的最外层是 .g-index
about.html则是g-about 。其他的内部结构有g-hd(header)、g-bd(body)、g-ft(footer)、g-sd(side)、g-mn(main) 等。
2、模块命名以m-开头。一般以功能用途来命名。如:导航栏m-nav、新闻m-news、版权m-copy_right等。模块名是独立,唯一的。模块本身是可以重复使用的。
3、元件命名以u- 开头,一般以自身含义命名。如:logo 命名为u-logo, u-btn表示一个按钮。
这是框架、模块、元件的相关命名,
还有以下几个命名规范:
1、命名尽量缩写,简洁明了的表达。如:bd表示body。使用长长的单词显得多余又臃肿;
2、前缀与名称之间用-链接,名称之间用_链接(组合单词除外如:side-menu);
3、z-开头表示状态,如:z-active、z-succ等;
4、根据需要定制其他的开头。单尽量将分类控制在少量,太多的分类会容易造成混乱和不必要的分类开销。
命名的重要性
- CSS 不像一般的编程语言,具有作用域和使名空间概念,它的每一条规则都是全局的,在 CSS 预处理出现之前,这很容易造成命名上的冲突。
- 如果为了减少命名上的冲突,使用很长的名称,很可能会造成 CSS 文件异常宏大。
- 涉及到多人维护同一段 CSS 代码时,命名的意义表达,也会影响到维护效率。
CSS 的规则命名通常有以下几条原则:
- 使用独一无二的规则
- 使用简短的命名
- 嵌套层级不宜过深,建议控制在3层以内
独一无二的规则
最完美的做法是,每条规则只使用一个选择器,并且每个选择器的命名唯一(有一些工具可以实现),但是会造成 CSS 文件过大,得不偿失。更好的做法是适当的使用嵌套:
.module_header { background:#fff; font-size:16px; }
.module_header .header_inner { }
.module_header .header_inner .header_logo { float:left; }
简短的命名
在能表达意思的前提下,使用单词的缩写,这是 CSS 的最佳实践之一。如上面的例子可以改成:
.mod_header { background:#fff; font-size:16px; }
.mod_header .hd_inner { }
.mod_header .hd_logo { float:left; }
相同的模块使用前缀限制,这是最常见的做法:
.det_top { padding:.1rem; }
.det_top h2 a { font-size:18px; color:#2db7f5; }
.det_top_right{float:right;}
.det_top_right button{border: 1px solid #C7CACC;padding: 4px 30px;background-color: #fff;border-radius: 3px;outline:none;}
.det_box { margin-bottom:.2rem; background:#ffffff; border:1px solid #e3e5ea; border-radius:4px; padding:0 .1rem; }
.det_box:last-child { margin-bottom: 0; }
.det_box .box_hd { height:.22rem; line-height: .22rem; padding:.1rem .2rem; border-bottom:1px solid #ecedee; overflow:hidden; }
.det_box .hd_tt { float:left; font-size:14px; color:#4f555c; }
.det_box .hd_edit { float:right; font-size:12px; color:#7b8791; }
一来起到命名空间的作用,二来模块化效果很清晰。
下面是一些常用的模块命名,可适当地使用单词缩写:
头:header
内容:content/container
尾:footer
导航:nav
侧栏:sidebar
栏目:column
页面外围控制整体布局宽度:wrapper
左右中:left right center
登录条:loginbar
标志:logo
广告:banner
页面主体:main
热点:hot
新闻:news
下载:download
子导航:subnav
菜单:menu
子菜单:submenu
搜索:search
友情链接:friendlink
页脚:footer
版权:copyright
滚动:scroll
内容:content
标签页:tab
文章列表:list
提示信息:msg
小技巧:tips
栏目标题:title
加入:joinus
指南:guild
服务:service
注册:regsiter
状态:status
投票:vote
合作伙伴:partner
浅嵌套
还是上面的例子:
.module_header { background:#fff; font-size:16px; }
.module_header .header_inner { }
.module_header .header_inner .header_logo { float:left; }
第三条规则的选择器可以缩减一下,变成:
.module_header .header_logo { float:left; }
因为一般不会有两个 logo 都放在头部。
更多关于 CSS 命名,请看这篇文章
在上面“命名的重要性”里面提到的缺点,可以通过使用名称缩写,还有选择器嵌套,保证每条规则的唯一性。
项目中存在的问题
- class 前面加标签:
.top_left p span.top_left_num label:first-child{
font-size: 20px;
}
看上面的例子,由于浏览器是从右向左解析 CSS 规则的,所以在找到 .top_left_num
后还要去判断是不是 span, CSS 解析反而是更慢的。一般只有两种情况下会用到多个选择器限定:
- 为了提高优先级
- 为了与同样选择器的元素区分,如下面为了区分展示状态和可编辑状态:
.det_box .bd_table .val { display: inline-block; padding:6px; line-height:1; border:1px solid transparent; box-sizing:border-box; }
.det_box .bd_table input.val { width:1.8rem; border:1px solid #e3e5ea; border-radius:4px; background:#eee; }
- 选择器太大:
.top_right{
float:right;
min-width:400px;
margin-top: 25px;
border-left: 1px dashed #e0ddd4;
padding-left: 20px;
}
.top_right li{
display: block;
line-height: 22px;
height: 22px;
}
上面的代码很容易出现重名的情况,导致样式互相影响。
- 原子类与模块样式混用:
.admin_childpages_header .f_l span{
font-weight: 700;
color: rgb(46,46,46);
padding: 0 1.75rem;
border-right: 2px solid rgb(191,191,191);
cursor: pointer;
font-size: 14px;
}
.admin_childpages_header .f_l span:last-of-type{
border: none;
}
原子类 .f_l
用于控制元素的 float:left;
,一般与其他原子类组合使用。上面的代码中,当这个元素不再需要 .f_l
时,所有使用 .f_l
的规则都会受到影响。建议用一个单独的 class 来控制样式。
- 模块之间区分不明显,不知道哪里的样式是同一个模块的。
- 模块没有添加注释说明
BEM
BEM是Block,Element,Modifier的缩写。是比较流行的一种 CSS 命名方式。下面分别介绍这三个概念:
- Block:在BEM的理论中,一个网页是由block组成的,比如头部是个block,内容是block,logo也是block,一个block可能由几个子block组成。
- Element:element是block的一部分,具有某种功能,element依赖于block,比如在logo中,img是logo的一个element,在菜单中,菜单项是菜单的一个element
- Modifier:modifier是用来修饰block或者element的,它表示block或者element在外观或行为上的改变
根据 BEM 原则,CSS 的命名应该是像下面这样的:
.block {}
.block__element {}
.block--modifier {}
上面的例子展示了一个BEM项目的类结构,下划线(__)被用来区分元素,而用连字符(--)是用来修饰元素的。再看一个例子:
.product-details {}
.product-details__price {}
.product-details__price--sale {}
最后的修饰位,通常会加入各种标记,大的、小的、红的、绿的等等。但是这样的命名,卖相不太好。
SUIT
Suit起源于BEM,但是它对组件名使用驼峰式和连字号把组件从他们的修饰和子孙后代中区分出来:
.u-utility {}
.ComponentName {}
.ComponentName-modifierName {}
.ComponentName-descendantName {}
.ComponentName.is-someState {}
三、模块之间的关系
嵌套
在写 CSS 的过程中,通常会遇到两个模块之间相互嵌套,比如说表单里面有按钮,按钮是一个组件,也是一个小的模块。
解耦
其他
原子类
在阿当的《编写高质量代码 Web前段开发修炼之道》这本书中,提倡并提供了一套原子类,相信很多前端开发者都有所了解。它提供了一套包含高度复用样式的 class ,下面截取一段书中的 base.css 的代码:
/*文字排版*/
.f12{font-size:12px;}
.f20{font-size:20px;}
.fb{font-weight:bold}
.fn{font-weight:normal;}
.t2{text-indent:2em;}
.lh150{line-height:150%;}
.unl{text-decoration:underlline;}
.no_unl{text-decoration:none;}
/*定位*/
.tl{text-align:left;}
.tc{text-align:center;}
.tr{text-align:right;}
.bc{margin-left:0;margin-right:0;}
.fl{float:left;display:inline;}
.fr{float:right;display:inline;}
.cb{clear:both;}
.cl{clear:left;}
.cr{clear:rigth;}
.vm{verticle-align:middle;}
.abs-right{position:absolute;right:0}
.zoom{zoom:1;}
.hidden{visiility:hidden;}
.none{display:none;}
/*长度高度*/
.w10{width:10px;}
.w{width:100%}
.h50{width:50px;}
.h{height:100%}
/*边距*/
.m10{margin:10px;}
.m15{margin:15px;}
.m30{margin:30px;}
.mt5{margin-top:5px;}
.mt10{margin-top:10px;}
.mt15{margin-top:15px;}
基于这些原子类,我们可以在项目中非常自由、灵活地组合使用,好处就是几乎不怎么需要你再写 CSS 代码了。但是,这种做法的缺点也是很明显的:
-
维护困难
试想,当你在很多个地方用了.w100
,如果要将这些宽度改为150px
,怎么做? -
代码冗余
经常会出现这样一种情况,在一个元素上添加好多个 class ,导致HTML代码很长。如很简单的一个按钮:
<a href="#" class="h30 w30 tc f14 unl p10 fl">按钮</a>
如果是这样,其实和直接写行内样式有什么区别:
<a href="#" style="width:30px;text-align:center;padding:10px;">按钮</a>
参考: https://blog.csdn.net/xuelian3015/article/details/81387087