1. CSS 选择器的优先级是如何计算的?

浏览器通过优先级规则,判断元素展示哪些样式。优先级通过 4 个维度指标确定,我们假定以a、b、c、d命名,分别代表以下含义:
a表示是否使用内联样式(inline style)。如果使用,a为 1,否则为 0。
b表示 ID 选择器的数量。
c表示类选择器、属性选择器和伪类选择器数量之和。
d表示标签(类型)选择器和伪元素选择器之和。
优先级的结果并非通过以上四个值生成一个得分,而是每个值分开比较。a、b、c、d权重从左到右,依次减小。判断优先级时,从左到右,一一比较,直到比较出最大值,即可停止。所以,如果b的值不同,那么c和d不管多大,都不会对结果产生影响。比如0,1,0,0的优先级高于0,0,10,10。
当出现优先级相等的情况时,最晚出现的样式规则会被采纳。如果你在样式表里写了相同的规则(无论是在该文件内部还是其它样式文件中),那么最后出现的(在文件底部的)样式优先级更高,因此会被采纳。
在写样式时,我会使用较低的优先级,这样这些样式可以轻易地覆盖掉。尤其对写 UI 组件的时候更为重要,这样使用者就不需要通过非常复杂的优先级规则或使用!important的方式,去覆盖组件的样式了。

2.实现动画效果方法与requestAnimationFrame

Javascript 中可以通过定时器 setTimeout 来实现,css3 可以使用 transition 和 animation 来实现。html5 还提供一个专门用于请求动画的API,那就是 requestAnimationFrame,顾名思义就是请求动画帧

  • setTimeout:通过设定间隔时间来不断改变图像位置,达到动画效果。但是容易出现卡顿、抖动的现象;原因是:1、settimeout任务被放入异步队列,只有当主线程任务执行完后才会执行队列中的任务,因此实际执行时间总是比设定时间要晚;2、settimeout的固定时间间隔不一定与屏幕刷新时间相同,会引起丢帧。
  • requestAnimationFrame:优势:由系统决定回调函数的执行时机。60Hz的刷新频率,那么每次刷新的间隔中会执行一次回调函数,不会引起丢帧,不会卡顿

参考
requestAnimationFrame

关于BFC详解


BFC(Block formatting context)直译为”块级格式化上下文”。它是一个独立的渲染区域。
我们一般利用这个去处理一个BFC的外部浮动,或者内部浮动,以及margin重叠等问题。最关键的原则就是体现BFC布局规则第五条:
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。

当BFC外部存在浮动时,它不应该影响BFC内部Box的布局,BFC会通过变窄,而不与浮动有重叠。 同样的,当BFC内部有浮动时,为了不影响外部元素的布局,BFC计算高度时会包括浮动的高度。 避免margin重叠也是这样的一个道理。
清除浮动的几个例子

  1. .floatfix{
  2. *zoom:1;
  3. }
  4. .floatfix:after{
  5. content:"";
  6. display:table;
  7. clear:both;
  8. }

清除内部浮动

  1. <style>
  2. .par {
  3. border: 5px solid #fcc;
  4. width: 300px;
  5. overflow: hidden; // 生成了一个BFC, 清除内部浮动
  6. }
  7. .child {
  8. border: 5px solid #f66;
  9. width:100px;
  10. height: 100px;
  11. float: left;
  12. }
  13. </style>
  14. <body>
  15. <div class="par">
  16. <div class="child"></div>
  17. <div class="child"></div>
  18. </div>
  19. </body>

CSS相关 - 图1

清除外部浮动(自适应两栏布局)
  1. <style>
  2. body {
  3. width: 300px;
  4. position: relative;
  5. }
  6. .aside {
  7. width: 100px;
  8. height: 150px;
  9. float: left;
  10. background: #f66;
  11. }
  12. .main {
  13. height: 200px;
  14. background: #fcc;
  15. }
  16. </style>
  17. <body>
  18. <div class="aside"></div>
  19. <div class="main"></div>
  20. </body>

CSS相关 - 图2

参考:
BFC原理剖析
清除浮动和BFC

盒模型


  1. W3C 标准盒模型:
    属性width,height只包含内容content,不包含border和padding。
  2. IE 盒模型:
    属性width,height包含border和padding,指的是content+padding+border。

标准盒模型盒子的宽度为: margin+border+padding+content
怪异盒模型盒子的宽度为: css设置的width值,相当于动态计算content的宽度
可通过CSS的box-size属性设置为content-box(标准盒模型)或border-box(IE盒模型或怪异盒模型)

回流与重绘


  1. 浏览器会把HTML解析成DOM,把CSS解析成CSSOM,DOM和CSSOM合并就产生了Render Tree
  2. 有了RenderTree,我们就知道了所有节点的样式,然后计算他们在页面上的大小和位置,最后把节点绘制到页面上
  3. 由于浏览器使用流式布局,对Render Tree的计算通常只需要遍历一次就可以完成,但table及其内部元素除外,他们可能需要多次计算,通常要花3倍于同等元素的时间,这也是为什么要避免使用table布局的原因之一

重点: 回流必将引起重绘,重绘不一定会引起回流

回流 (Reflow)

当Render Tree中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。

重绘 (Repaint)

当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘

性能影响

回流比重绘的代价要更高。
有时即使仅仅回流一个单一的元素,它的父元素以及任何跟随它的元素也会产生回流

优化

  • css层面
    • 避免使用table布局。
    • 尽可能在DOM树的最末端改变class。
    • 避免设置多层内联样式。
    • 将动画效果应用到position属性为absolute或fixed的元素上。
    • 避免使用CSS表达式(例如:calc())。
  • javascript层面
    • 避免频繁操作样式,最好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性。
    • 避免频繁操作DOM,创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中。
    • 也可以先为元素设置display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘。
    • 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
    • 对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。

参考
浏览器的回流与重绘 (Reflow & Repaint)