一、文件结构
常见文件结构
一个项目的css最基本结构通常是下面这样的:
- base.css
- common.css
- pages.css
复杂一点的项目可能是这样分:
- base.css
- header.css
- footer.css
- sidebar.css
- forms.css
- buttons.css
- dropdown.css
- modals.css
- layout.css
- index.css
- user.css
- admin.css
- pages.css
如果后期不打算合并css的,建议尽可能减少css文件的数量。
如果要做合并压缩css文件,则可以对css文件进行适当的组织,这是css模块化最简单有效的方法。
建议根据项目情况使用上述的两种或是其他文件组织方案。
SMACSS
SMACSS 的全称叫Scalable and modular Architecture for css。即可扩展和模块化的css构架。
SMACSS将样式分成5种类型:Base,Layout,Module,State,Theme,下面说说每一种类型表示什么:
- Base:基础样式表,定义了基本的样式,我们平时写css比如reset.css就是属于基础样式表,另外我认为清除浮动,一些动画也可以归类为基础样式。
- Layout:布局样式,用于实现网页的基本布局,搭起整个网页的基本骨架。
- Module:网页中不同的区域有这个不同的功能,这些功能是相对独立的,我们可以称其为模块。模块是独立的,可重用的组件,它们不依赖于布局组件,可以安全地删除修改而不影响其他模块。
- State:状态样式,通常和js一起配合使用,表示某个组件或功能不同的状态,比如菜单选中状态,按钮不可用状态等。
- Theme:主题皮肤,对于可更换的皮肤的站点来说,这是很有必要的,分离了结构和皮肤,根据不同的皮肤应用不同的样式文件。
关于更多SMACSS的信息参见它的官网。
二、命名
命名的重要性
- 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_log{float:left;}
相同的模块使用前缀限制,这是最常见的做法:
.det_top{padding:.1rem;}
.det_top h2 a{font-size:18px;color:#2db7f5;}
.det_top_right button{border:1px;}
.det_box{margin-bottom:.2rem;background:#fff;}
.det_box .box_hd{height:.22rem;}
.det_box .hd_tt{float:left;font-size:14px;}
一来起到命名空间的作用,二来模块化效果和清晰。
下面是一些常用的模块命名,可适当地使用单词缩写:
头: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
注册:register
状态: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都放在头部。
项目中存在的问题
- 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;
}
.top_right li{
display:block;
line-height:22px;
height:22px;
}
上面的代码很容易出现重名的情况,导致样式相互影响。
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{}
.product-details__price--sale{}
最后的修饰位,通常会加入各种标记,大的、小的、红的、绿的等等。但是这样的命名,卖相不太好。
模块之间的关系
嵌套
在写css的过程中,通常会遇到两个模块之间相互嵌套,比如说表单里面有按钮,按钮是一个组件,也是一个小的模块。
四、css预处理 SASS
SASS是一种css预处理器,用它的语法书写样式,在编译成css文件。它自身兼容css语法,也就是说,把你的css文件复制到scss文件中也可以正常使用。
SASS使用了很多模块化和面向对象的思想,使得我们的样式更加易维护。下面讲一下SASS的常用特性。
基本用法
变量
声明变量,所有变量以$开头:
//color
$gray-darker: #333;
$gray-dark:#666;
$gray:#999;
$gray-light:#ccc;
//文字主色
$main-bg:#f6f6f6;
$mod-bg:#fcfcfc;有内容模块背景色
//常用色
$orange:#f90;
$red:#cb000;
计算
body {
margin:(14px/2);
top:50px+100px;
right:$var*10%;
}
嵌套
div{
h1{
color:red;
}
}
编译后:
div h1{
color:red;
}
获取父元素:
a{
&:hover{color:#ffb3ff}
}
使用@at-root规则:
.zc_about{
@at-root .zc_about_list{
`background-color:$mod-bg;
text-align:center;
overflow:hidden;
}
}
继承
SASS可以用@extend继承一个选择器:
.uc_btn_default,.uc_btn_orange{
color:#fff;
&:visited{
@extend .uc_btn_orange;
}
}
Mixin
Mixin用于定义一些公用部分,定义一个Mixin:
@mixin layout{
padding-left:10px;
padding-right:10px;
}
通过@include使用:
div{
@include layout;
height:1rem;
}
Mixin还可以指定参数:
//icon基本样式
@mixin icon-base($size){
display:inline-block;
width:$size;
height:$size;
vertical-align:middle;
background-repeat:no-repeat;
background-size:contain;
}
颜色处理
lighten(#cc3,10%)//#d6d65c
darken(#cc3,10%)//a3a329
grayscale(#cc3)//#808080
流程控制
条件判断:
@if lightness($color)>30%{
background-color:#100;
}@else{
background-color:#fff;
}
function
SASS还可以编写函数:
@function double($n){
@return $n*2;
}
sidebar{
width:double(5px);
}
由于SASS的预处理特性,我们可以把模块单独放到一个文件里面,使用文件夹来分类,更加方便管理,以下是一份比较完整的SASS文件结构组织:
sass/
|
|-base/
| |- _reset.scss #reset/normalize
| |- _typography.scss #Typography rules
| ... #Etc...
|
|-components/
| |- _buttons.scss #button
| |- _carousel.scss #carousel
| |- _cover.scss #cover
| |- _navigation.scss #Navigation
| |- _dropdown.scss #Dropdown
| ... #Etc...
|-helpers/
| |- _variables.scss #sass variables
| |- _functions.scss #sass functions
| |- _mixins.scss #sass Mixins
| |- _helpers.scss #Class &placeholders
| ...
|
| -pages/
| |- _home.scss #Home specific styles
| |- _contact.scss #Contact specific styles
| -themes/
| |- _theme.scss #Default theme
| |- _admin.scss #Admin theme
| ...
|
| -vendors/
| |- bootstrap.scss #Bootstrap
| |- _jquery-ui.scss #jQuery UI
| ...
| -main.scss #primary Sass file