如何进行命名是一件看上去微不足道但其实对代码整洁度破坏很大的事情,《代码整洁之道》建议的第一篇就是如何进行好的命名
css杂项(命名,书写顺序,调试)
BEM
BEM
是模块(Block)、元素(Element)、修饰符(Modifier)的简写。BEM
是一种组件架构的命名方法,它的基本思想是将Html
元素划分成独立的组件,然后用简单的规则链接起来,开发时不用担心不会取名字了,同时后期维护和多人协作上好处大大的。其命名规则如下:
1
2
3Block - 模块,名字的单词之间用 `-` 符号连接
Element - 元素,模块中的子元素,用 `__` 符号连接
Modifier - 修饰符,表示父元素或子元素的其他形态,用 `--` 符号连接优势
在没用 BEM 之前,我们可能会这样组织 CSS 类名:
1
2
3
4
5
6
7
8<!-- Common命名的 Search Bar 模块 -->
<div class="search-bar">
<input class="input">
<!-- / input 输入框 -->
<button class="btn">
<!-- / button 搜索按钮 -->
</div>
<!-- E Search Bar 模块 -->用 BEM 命名重写之后:
1
2
3
4
5
6
7
8<!-- BEM命名的 Search Bar 模块 -->
<div class="search-bar">
<input class="search-form__input"/>
<!-- / input 输入框子元素 -->
<button class="search-form__button"></button>
<!-- / button 搜索按钮子元素 -->
</div>
<!-- E Search Bar 模块 -->有对比高下立判~ 通常面试问的语义化(作用与实践),这样就达到了,最终目的是减少代码阅读成本。
缺陷
优点也是缺点,当
HTML
元素层级繁多时,会使得命名越来越长,那样的话,文件会变得臃肿不堪,反而违背了我们的初心。乱七八糟的HTML
谁会愿意看?
我们并不需要把每个元素的全部名称带上来表明主次关系。就像这份族谱一样,他的孩子只需要保留「贾」姓就可以了,名字是可以随便取的。
关联上 BEM 命名方法,姓氏命名法中的 Block 就是「姓」,Element 就是「名字」,而 Modifier 就表示这个人的某种状态,例如:「范 - - 冰冰 - - 很美」。这样就达到了取其精华,去其糟粕的作用。
1
2
3
4
5
6
7
8
9
10
11
<!-- am = app_market -->
<div class="am_answer">
<div class="am_secheader"></div>
<div class="am_answer_list">
<div class="am_answer_item">
<div class="am_answer_itop"></div>
<div class="am_answer_imid"></div>
<a href="javascript:;" class="am_answer_ibtn">去围观</a>
</div>
</div>
</div>
将 app_market 可以看成是「复姓」,将两个单词的首字母结合在一起形成一个新的「单姓」,如 am ;将item中的子项类名直接简写为「ixx」,如:itop。追求便利的副作用之一是牺牲了一点代码的可读性。但多半项目上的文档可以注明命名方法和其他书写规范,如果团队有约束,那一定是极佳的实践。
小结
ClassName 的命名应该尽量精短、明确,以英文单词命名,且全部字母为小写,避免意义不明的缩写
单词之间统一使用下划线
_
或-
连接定义样式模块,提高代码的可复用性
CSS推荐书写
推荐书写顺序
- 位置属性(position, top, right, z-index, display, float等)
- 大小(width, height, padding, margin)
- 文字系列(font, line-height, letter-spacing, color- text-align等)
- 背景(background, border等)
- 其他(animation, transition等)
why this ?
主要从浏览器的渲染机制方面来考虑,减少重绘与重排,提高性能。
良好的习惯会使得你编写
css
代码时也更加清晰
拿到文件后浏览器的渲染流程为:
(1)浏览器解析html构建dom树,解析css构建cssom树即css rule tree:将html和css都解析成树形的数据结构; dom树的构建过程是一个深度遍历过程:当前节点的所有子节点都构建好后才会去构建当前节点的下一个兄弟节点。
(2)构建render树:DOM树和cssom树合并之后形成render树。为了构建渲染树,浏览器大体完成了下列工作:从DOM树的根节点开始遍历每个可见节点。对于每个可见节点,为其找到适配的CSSOM规则并应用它们。发射可见节点,连同其内容和计算的样式。渲染树中包含了屏幕上所有可见内容及其样式信息。
(3)布局render树:有了render树,浏览器已经知道网页中有哪些节点,各个节点的css定义以及它们的从属关系,接着就开始布局,计算出每个节点在屏幕中的位置和大小。(html采用了一种流式布局的布局模型,从上到下,从左到右顺序布局,布局的起点是从render树的根节点开始的,对应dom树的document节点,其初始位置为(0,0),详细的布局过程为:每个renderer的宽度由父节点的renderer确定。父节点遍历子节点,确定子节点的位置(x,y),调用子节点的layout方法确定其高度,父节点根据子节点的height, margin, padding确定自身的高度)。
(4)渲染render树:浏览器已经知道啦哪些节点要显示,每个节点的css属性是什么,每个节点在屏幕中的位置是哪里。就进入啦最后一步,按照计算出来的规则,通过显卡把内容画在屏幕上。
DOM 的变化影响了元素的几何属性(宽和高)- 比如改变边框宽度或给段落增加文字,导致行数增加 – 浏览器需要重新计算元素的几何属性,同样其他元素的几何属性和位置也会因此受到影响。浏览器会使渲染树中受到影响的部分失效,并重新构建渲染树。这个过程称为 “重排(reflow)”。完成重排后,浏览器会重新绘制受影响的部分到屏幕中,该过程称为 “重绘(repaint)”
好了好了,照本宣科的东西终于没了,当然渲染过程没这么简单,这里也是借鉴一下啦。
1 | width: 100px; |
当浏览器解析到position的时候突然发现该元素是绝对定位元素需要脱离文档流,而之前却是按照普通元素进行解析的,所以不得不重新渲染,解除该元素在文档中所占位置,然而由于该元素的占位发生变化,其他元素也可能会受到回流的影响而重新排位,最终导致(3)步骤花费时间太久而影响 。
CSS便捷调试法
控制台输入神秘代码
1
2
3
4
5
6
7
8// 1
javascript: var _q = !_q;document.querySelectorAll('*').forEach(q => q.style.outline = _q ? '1px solid red' : '')
// 2
$$('*').forEach(a=>{a.style.outline='1px solid red'})
// 3
xxxxxxxxx插件: Keylines ( 一键+彩色线条 )
优雅的
xss
- 打开书签管理页
- 右上角三个点「添加新书签」
- 名称随意,粘贴以下代码到网址中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17javascript: (function() {
var elements = document.body.getElementsByTagName('*');
var items = [];
for (var i = 0; i < elements.length; i++) {
if (elements[i].innerHTML.indexOf('html * { outline: 1px solid red }') != -1) {
items.push(elements[i]);
}
}
if (items.length > 0) {
for (var i = 0; i < items.length; i++) {
items[i].innerHTML = '';
}
} else {
document.body.innerHTML +=
'<style>html * { outline: 1px solid red }</style>';
}
})();然后我们就可以在任意网站上点击刚才创建的书签,内部会判断是否存在调试的
style
。存在的话就删除,不存在的话就添加,通过这种方式我们就能很方便的通过这个技巧查看任意网页的布局了。
效果如下:
reference:
浏览器渲染过程与性能优化: https://juejin.im/post/59d489156fb9a00a571d6509 ,
CSS书写顺序 :https://www.cnblogs.com/xuepei/p/8961809.html ,
auto实验室 https://aotu.io/