CSS命名一般是用 BEM 规则命名的。它背后的想法是将用户界面划分为独立的块。
BEM
的意思就是B模块(block)
、E元素(element)
、M修饰符(modifier)
,
即:[block]__[element]--[modifier]
。
模块和子元素之间用两个下划线分隔(如:order__security),子元素和修饰符之间用两个中划线分隔,(如:content__person–selected)。
● 块 Block:组件的最外层父元素定义为块。
● 元素 Elemnt:组件内部可以是一个或多个称为元素的子元素。
● 修饰符 Modifier:块或元素可能具有由修饰符表示的变体。
关于子元素E,有两种写法:
第一种:按照层级嵌套来写,如 block__ele1-son-inner,但是这样写会导致命名过长;
第二种:扁平化,一个模块下的所有子元素,无论相互层级如何,都直接连接这个模块,如
block__inner,但是这样就无法表示层级关系,命名时也可能会出现冲突。
命名注意:
一般来说,要先定义好布局,即先写位置、再写大小边距,再写文字样式、背景色,最后写其他属性。
如:
.wrapper{
display: block;
position: relative;
width: 100px;
height: 100px;
margin: 0 10px;
padding: 20px 0;
font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;
color: #333;
background: rgba(0,0,0,.5);
border-radius: 10px;
}
目的:减少浏览器回流(reflow),提升浏览器渲染dom的性能
浏览器的渲染流程:
① 解析html构建 DOM 树,解析css构建 CSSOM 树:将html解析成树形的数据结构,将css解析成树形的数据结构。
② 构建 Render 树:DOM树和CSS树合并之后形成的render树。
③ 布局(Layout):有了render树,浏览器已经知道那些网页中有哪些节点,各个节点的css定义和以及它们的从属关系,从而计算出每个节点在屏幕中的位置和大小
。
④ 绘制(Painting):根据css样式规则将计算好的盒模型呈现出来。
布局阶段的主要任务是生成盒子,计算它们的位置和大小;绘制阶段则是根据css样式规则将计算好的盒模型呈现出来。
所以说,如果元素的 位置 和 大小 出现变动,就需要浏览器再次回到布局阶段重新计算,计算后再绘制,这就是 回流
;而如果元素的颜色等样式属性出现变动,则无需计算,只需再次绘制,这就是 重绘
。
css样式解析到显示至浏览器屏幕上就发生在 ②③④ 步骤,浏览器并不是一获取到css样式就立马开始解析,而是根据css样式的书写顺序,将之按照 dom 树的结构完成构建,然后开始遍历每个树结点的 css 样式进行解析,此时 css 样式的遍历顺序完全是按照之前的书写顺序。
在解析过程中,一旦浏览器发现某个元素的定位变化影响布局,则需要倒回去重新渲染。正如按照这样的书写顺序:
.test{
width: 100px;
height: 100px;
background-color: red ;
position: absolute;
}
当浏览器解析到 position
的时候突然发现该元素是绝对定位元素需要脱离文档流,而之前却是按照普通元素进行解析的,所以不得不重新渲染,解除该元素在文档中所占位置,然而由于该元素的占位发生变化,其他元素也可能会受到它回流的影响而重新排位。最终导致③步骤(布局)花费的时间太久而影响到④步骤的显示,影响了用户体验。
另:一些可以缩写的属性建议缩写,如padding,在值不同的情况下,还是不要拆开的好。代码看起来会简略很多。
建议:
.test{
padding: 8px 6px 4px 2px;
margin:8px 6px;
}
不建议:
.test{
padding-top: 8px;
padding-right:6px;
padding-bottom:4px;
padding-left:2px;
}
我们维护的项目代码来自不同的开发者,风格比较多样化。尽量养成良好的代码习惯!