目录
1.CSS样式覆盖顺序
2. CSS样式书序顺序
3. CSS样式命名规范
4.CSS编码规范
1.CSS样式覆盖顺序
层叠样式覆盖优先顺序:浏览器默认样式 < 浏览器用户自定义样式 < 外部样式表 < 内部样式表 < 内联样式表
内部选择器优先顺序:类选择器 < 类派生选择器 < ID选择器 < ID派生选择器
链接的样式请严格按照如下顺序添加:a:link -> a:visited -> a:hover -> a:active
生效规则:
1. 样式表的元素选择器选择越精确,则其中的样式优先级越高。
id选择器指定的样式 > 类选择器指定的样式 > 元素类型选择器指定的样式
2. 对于相同类型选择器指定的样式,在样式表文件中,越靠后的优先级越高。
3. 一个元素同时应用多个class,后定义的优先(即近者优先)
4. 如果要让某个样式的优先级变高,可以使用!important来指定。
其他细节:
、
、
组织列表,不要使用一堆 或者
;
- 每个包含附加文字的表单输入框都应该利用
标签,特别是 radio
、checkbox
元素;
- 使用
标签包裹 radio
/ checkbox
,不需要设置 for
属性;
- 避免写关闭标签注释,如
,大多编辑器都支持开闭标签高亮;
- 不要手动设置
tabindex
,浏览器会自动设置顺序。
2. CSS样式书序顺序
单个样式规则下的属性在书写时,应按功能进行分组,组之间需要有一个空行。
同时要以 全局属性 > 定位属性 > 自身属性 > 文本样式 >文本效果> 背景属性 > 渲染属性 > 其他 的顺序书写。
.demo {
/*全局属性*/
display: block;
float: none;
list-style: none;
/*定位属性*/
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
z-index: 0;
/*自身属性*/
box-sizing: border-box;
margin: 0 auto;
padding: 0;
width: inherit;
min-width: none;
max-width: none;
height: inherit;
min-height: inherit;
max-height: none;
border: none;
border-radius: inherit;
/*文本样式*/
font: "微软雅黑";
color: #000000;
font-size: 12px;
font-style: inherit;
font-family: "new york";
font-weight: bold;
/*文本效果*/
line-height: 32px;
text-align: center;
vertical-align: middle;
white-space: normal;
letter-spacing: normal;
word-spacing: normal;
word-break: break-all;
/*背景属性*/
background: no-repeat;
background-clip: inherit;
background-color: #000000;
background-origin: border-box;
background-size: cover;
background-position: left top;
/*渲染效果属性*/
opacity: inherit;
outline: none;
box-shadow: none;
transition: all;
transform: inherit;
animation: .25s, 100ms;
/*其他属性*/
cursor: pointer;
}
目的:减少浏览器reflow(回流),提升浏览器渲染dom的性能
原理:浏览器的渲染流程为——
①解析html构建dom树,解析css构建css树:将html解析成树形的数据结构,将css解析成树形的数据结构
②构建render树:DOM树和CSS树合并之后形成的render树。
③布局render树:有了render树,浏览器已经知道那些网页中有哪些节点,各个节点的css定义和以及它们的从属关系,从而计算出每个节点在屏幕中的位置。
④绘制render树:按照计算出来的规则,通过显卡把内容画在屏幕上。
css样式解析到显示至浏览器屏幕上就发生在②③④步骤,可见浏览器并不是一获取到css样式就立马开始解析而是根据css样式的书写顺序将之按照dom树的结构分布render样式,完成第②步,然后开始遍历每个树结点的css样式进行解析,此时的css样式的遍历顺序完全是按照之前的书写顺序。在解析过程中,一旦浏览器发现某个元素的定位变化影响布局,则需要倒回去重新渲染正如按照这样的书写书序:
width: 100px;
height: 100px;
background-color: red ;
position: absolute;
当浏览器解析到position的时候突然发现该元素是绝对定位元素需要脱离文档流,而之前却是按照普通元素进行解析的,所以不得不重新渲染,解除该元素在文档中所占位置,然而由于该元素的占位发生变化,其他元素也可能会受到它回流的影响而重新排位。最终导致③步骤花费的时间太久而影响到④步骤的显示,影响了用户体验。
所以规范的的css书写顺序对于文档渲染来说一定是事半功倍的!
扩展:还有一个会影响浏览器渲染性能的词汇“repaint(重绘)”
repaint(重绘):改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,但是元素的几何尺寸没有变。
注意:
a.render树的结构不等同于DOM树的结构,一些设置display:none的节点不会被放在render树中,但会在dom树中。
b.有些情况,比如修改了元素的样式,浏览器并不会理科reflow或repaint,而是把这些操作积攒一批,然后做一次reflow,这也叫做异步reflow.但在有些情况下,比如改变窗口,改变页面默认的字体等,对于这些情况,浏览器会马上进行reflow.
c.为了更好的用户体验,渲染引擎将会尽可能早的将内容呈现到屏幕上,并不会等到所有的html都解析完成之后再去构建和布局render树。它是解析完一部分内容就显示一部分内容,同时,可能还在通过网络下载其余内容。
3. CSS样式命名规范
分类式命名法(在前端组件化下尤为重要)
布局(grid)(.g-):将页面分割为几个大块,通常有头部、主体、主栏、侧栏、尾部等!
模块(module)(.m-):通常是一个语义化的可以重复使用的较大的整体!比如导航、登录、注册等
元件(unit)(.u-):通常是一个不可再分的较为小巧的个体,通常被重复用于各种模块中!比如按钮、输 入框、loading等!
功能(function)(.f-):为方便一些常用样式的使用,我们将这些使用率较高的样式剥离出来,按需使用,通常这些选择器具有固定样式表现,比如清除浮动等!不可滥用!
状态(.z-):为状态类样式加入前缀,统一标识,方便识别,她只能组合使用或作为后代出现(.u-ipt.z-dis{},.m-list li.z-sel{})
javascript(.j-):.j-将被专用于JS获取节点,请勿使用.j-定义样式
不要使用 " _ " 下划线来命名css
能良好的区分javascript变量名
输入的时候少按一个shift键
浏览器兼容性问题(比如使用_tips的选择器命名,在IE6是无效的)
id采用驼峰式命名(不要乱用id)
scss中的变量、函数、混合、placeholder采用驼峰式命名
相同语义的不同类命名方法:
直接加数字或字母区分即可(如:.m-list、.m-list2、.m-list3等,都是列表模块,但是是完全不一样的模块)。其他举例:.f-fw0、.f-fw1、.s-fc0、.s-fc1、.m-logo2、.m-logo3、u-btn、u-btn2等等。
命名方式(BEM):类-体(例:g-head)、类-体-修饰符(例:u-btn-active)
后代选择器:体-修饰符即可(例:.m-page .cut{})注:后代选择器不要在页面布局中使用,因为污染的可能性较大;
3.1 最佳写法
/* 这是某个模块 */ .
.m-nav{}/* 模块容器 */ .
.m-nav li,.m-nav a{}/* 先共性 优化组合 */ .
.m-nav li{}/* 后个性 语义化标签选择器 */ .
.m-nav a{}/* 后个性中的共性 按结构顺序 */ .
.m-nav a.a1{}/* 后个性中的个性 */
.m-nav a.a2{}/* 后个性中的个性 */ .
.m-nav .z-crt a{}/* 交互状态变化 */ .
.m-nav .z-crt a.a1{} .m-nav .z-crt a.a2{}
.m-nav .btn{}/* 典型后代选择器 */
.m-nav .btn-1{}/* 典型后代选择器扩展 */
.m-nav .btn-dis{}/* 典型后代选择器扩展(状态) */
.m-nav .btn.z-dis{}/* 作用同上,请二选一(如果可以不兼容IE6时使用) */
.m-nav .m-sch{}/* 控制内部其他模块位置 */
.m-nav .u-sel{}/* 控制内部其他元件位置 */
.m-nav-1{}/* 模块扩展 */
.m-nav-1 li{} .m-nav-dis{}/* 模块扩展(状态) */ .
.m-nav.z-dis{}/* 作用同上,请二选一(如果可以不兼容IE6时使用) */
3.2 统一语义理解和命名
页面结构
- 容器: container
- 页头:header
- 内容:content / container
- 页面主体:main
- 页尾:footer
- 导航:nav
- 侧栏:sidebar
- 栏目:column
- 页面外围控制整体佈局宽度:wrapper
- 左右中:left right center
布局(.g-)
- 语义:命名(简写)
- 文档: doc(doc)
- 头部 :header (hd)
- 主体 :body(bd)
- 尾部 :foot (ft)
- 主栏 :main(mn)
- 主栏子容器: mainc(mnc)
- 侧栏: side(sd)
- 侧栏子容器: sidec(sdc)
- 盒容器: wrap / box (warap/box)
模块(.m-)、元件(.u-)
- 导航 :nav(nav)
- 子导航: subnav(snav)
- 顶导航:topnav
- 边导航:sidebar
- 左导航:leftsidebar
- 右导航:rightsidebar
- 面包屑: crumb(crm)
- 菜单 :menu (menu)
- 子菜单:submenu
- 选项卡/标签页: tab(tab)
- 标题区 :head / title (hd/tt)
- 内容区 :body / content(bd/ct)
- 列表: list(list)
- 表格: table(tb)
- 表单: form(fm)
- 热点 :hot (hot)
- 排行: top (top)
- 登录 :login (log)
- 登录条:loginbar
- 标志: logo (logo)
- 广告: advertise / banner (ad)
- 搜索 :search (sch)
- 幻灯: slide (sld)
- 提示/小技巧: tips (tips)
- 帮助: help(help)
- 新闻 :news(news)
- 下载: download(dld)
- 注册 :register (reg)
- 投票 :vote(vote)
- 版权 :vcopyright (copr)
- 结果: result(rst)
- 标题: title (tt)
- 按钮: button (btn)
- 输入: input (ipt)
- 摘要: summary
- 功能区:shop
- 加入:joinus
- 状态:status
- 滚动:scroll
- 提示信息:msg
- 当前的: current
- 图标: icon
- 注释:note
- 指南:guild
- 服务:service
- 合作伙伴:partner
- 友情链接:link
功能:(.f-)
- 清除浮动: clear:both(cb)
- 左浮动: float:left (fl)
- 内联 :inline:block (ib)
- 文本居中: text-align:center (tac)
- 垂直居中: vertical-align:middle (vam)
- 溢出隐藏 :overflow:hidden (oh)
- 完全消失 :display:none (dn)
- 字体大小 :font-size(fz)
- 字体粗细 :font-weight (fs)
皮肤:(.s-)
- 字体颜色: font-color(fc)
- 背景颜色: background-color(bgc)
- 边框颜色: border-color(bdc)
状态(.z-)
- 选中 :selected (se)
- 当前: current (srt)
- 显示: show (show)
- 隐藏 :hide (hide)
- 打开 :open (open)
- 关闭 :close (close)
- 出错 :error (err)
- 不可用 :disabled(dis)
CSS样式表文件命名
- 主要的: master.css
- 模块 module.css
- 基本共用 :base.css
- 布局、版面: layout.css
- 主题: themes.css
- 专栏: columns.css
- 文字: font.css
- 表单: forms.css
- 补丁: mend.css
- 打印: print.css
注意事项
- 一律小写,中划线
- 尽量不用缩写
- 不要随便使用id
- 去掉小数点前面的0: 0.9rem => .9rem
- 使用简写:margin: 0 1rem 3rem
4.CSS编码规范
- 尽可能的精确。
- 合理的避免使用ID。
- CSS选择器中避免标签名。
- 属性名的冒号后使用一个空格。
- 属性选择器或属性值用双引号(””)。
- 每个声明应该用分号结束,每个声明换行。
- 每个选择器和属性声明总是使用新的一行。
- 规则之间始终有一个空行(双换行符)分隔。
- CSS提供了各种缩写属性(如 font 字体)应该尽可能使用。
- 省略“0”值后面的单位。不要在0值后面使用单位,除非有值。
1.合理的避免使用ID
一般情况下ID不应该被应用于样式。
ID的样式不能被复用并且每个页面中你只能使用一次ID。
使用ID唯一有效的是确定网页或整个站点中的位置。
尽管如此,你应该始终考虑使用class,而不是id,除非只使用一次。
另一个反对使用ID的观点是含有ID选择器权重很高。
一个只包含一个ID选择器权重高于包含1000个class(类)名的选择器,这使得它很奇怪。
2.CSS选择器中避免标签名
当构建选择器时应该使用清晰, 准确和有语义的class(类)名。不要使用标签选择器。 如果你只关心你的class(类)名
,而不是你的代码元素,这样会更容易维护。
从分离的角度考虑,在表现层中不应该分配html标记/语义。
它可能是一个有序列表需要被改成一个无序列表,或者一个div将被转换成article。
如果你只使用具有实际意义的class(类)名,
并且不使用元素选择器,那么你只需要改变你的html标记,而不用改动你的CSS。
/*不推荐*/
div.content > header.content-header > h2.title {
font-size: 2em;
}
/*推荐*/
.content .title {
font-size: 2em;
}
3.尽可能的精确
很多前端开发人员写选择器链的时候不使用 直接子选择器(注:直接子选择器和后代选择器的区别)。
有时,这可能会导致疼痛的设计问题并且有时候可能会很耗性能。
然而,在任何情况下,这是一个非常不好的做法。
如果你不写很通用的,需要匹配到DOM末端的选择器, 你应该总是考虑直接子选择器。
/*不推荐*/
.content .title {
font-size: 2rem;
}
.content > .title {
font-size: 2rem;
}
/*推荐*/
.content > .content-body > .title {
font-size: 1.5rem;
}
.content > .content-body > .teaser > .title {
font-size: 1.2rem;
}
4.缩写属性
CSS提供了各种缩写属性(如 font 字体)应该尽可能使用,即使在只设置一个值的情况下。
使用缩写属性对于代码效率和可读性是有很有用的。
border-top: 0;
font: 100%/1.6 palatino, georgia, serif;
padding: 0 1em 2em;
5. 0 和 单位
省略“0”值后面的单位。不要在0值后面使用单位,除非有值。
/*不推荐*/
padding-bottom: 0px;
margin: 0px;
/*推荐*/
padding-bottom: 0;
margin: 0;
6.声明结束
为了保证一致性和可扩展性,每个声明应该用分号结束,每个声明换行。
/*不推荐*/
.test {
display: block; height: 100px;
}
/*推荐*/
.test {
display: block;
height: 100px;
}
7.属性名结束
属性名的冒号后使用一个空格。出于一致性的原因,
属性和值(但属性和冒号之间没有空格)的之间始终使用一个空格。
/*不推荐*/
h3 {
font-weight:bold;
}
/*推荐*/
h3 {
font-weight:bold;
}
8.选择器和声明分离
每个选择器和属性声明总是使用新的一行。
/*不推荐*/
a:focus, a:active {
position: relative; top: 1px;
}
/*推荐*/
a:focus,
a:active {
position: relative;
top: 1px;
}
9.规则分隔
规则之间始终有一个空行(双换行符)分隔。
html {
background: #fff;
}
body {
margin: auto;
width: 50%;
}
10.CSS引号
属性选择器或属性值用双引号(””),而不是单引号(”)括起来。
URI值(url())不要使用引号。
html {
font-family: "open sans", arial, sans-serif;
}
11.选择器嵌套
嵌套选择器,这可以使代码变得更清洁和可读。嵌套所有的选择器,但尽量避免嵌套没有任何内容的选择器。
如果你需要指定一些子元素的样式属性,而父元素将不什么样式属性,
可以使用常规的CSS选择器链。
这将防止您的脚本看起来过于复杂。
/*不推荐*/
.content {
display: block;
}
.content > .news-article > .title {
font-size: 1.2em;
}
/*不推荐*/
.content {
display: block;
> .news-article {
> .title {
font-size: 1.2em;
}
}
}
/*推荐*/
.content {
display: block;
> .news-article > .title {
font-size: 1.2em;
}
}
12.上下文媒体查询(media)
/*推荐*/
.content-page {
font-size: 1.2rem;
@media screen and (min-width: 641px) {
font-size: 1rem;
}
> .main {
background-color: whitesmoke;
> .latest-news {
padding: 1rem;
> .news-article {
padding: 1rem;
> .title {
font-size: 2rem;
@media screen and (min-width: 641px) {
font-size: 3rem;
}
}
}
}
> .content {
margin-top: 2rem;
padding: 1rem;
}
}
> .page-footer {
margin-top: 2rem;
font-size: 1rem;
@media screen and (min-width: 641px) {
font-size: 0.8rem;
}
}
}
13.嵌套顺序和父级选择器
推荐顺序:
- 当前选择器的样式属性
- 父级选择器的伪类选择器 (:first-letter, :hover, :active etc)
- 伪类元素 (:before and :after)
- 父级选择器的声明样式 (.selected, .active, .enlarged etc.)
- 用Sass的上下文媒体查询
- 子选择器作为最后的部分
.product-teaser {
// 1. Style attributes
display: inline-block;
padding: 1rem;
background-color: whitesmoke;
color: grey;
// 2. Pseudo selectors with parent selector
&:hover {
color: black;
}
// 3. Pseudo elements with parent selector
&:before {
content: "";
display: block;
border-top: 1px solid grey;
}
&:after {
content: "";
display: block;
border-top: 1px solid grey;
}
// 4. State classes with parent selector
&.active {
background-color: pink;
color: red;
// 4.2. Pseuso selector in state class selector
&:hover {
color: darkred;
}
}
// 5. Contextual media queries
@media screen and (max-width: 640px) {
display: block;
font-size: 2em;
}
// 6. Sub selectors
> .content > .title {
font-size: 1.2em;
// 6.5. Contextual media queries in sub selector
@media screen and (max-width: 640px) {
letter-spacing: 0.2em;
text-transform: uppercase;
}
}
}