Chrome 调试对象非及时跟新问题

问题

今天调试代码准备追踪下对象的变化,但是突然发现在chrom调试中对象没有随方法的调用而发生变化
如下:
对象显示细节.png

但是可以明显发现 对象显示的概括和点击显示的详情不符,概括应该是正常的。然后我又试了下每个对象显示出来的就点开详情,可以发现这次对象都正常显示。因此我们可以猜想应该是chrome调试在点击对象的详情的时候才调用的遍历显示对象,因此之前对象显示了但是我又点击详情,因此在后面点击的时候才调用循环显示这个对象的属性。
即这个时候的对象是现在的情况,不是当时显示的时候的对象。

下面我们可以新建一个简单对象来验证下:
对象细节.png

然后我们可以看看其实chrome有标记的:
对象细节1.png

明确标识了显示的是点击的时候对象,出”bug”除了自己尝试,还可以关注官方的文档/工具的细节,稳住不急。

BFC简述总结

定义

BFC(block formatting context),中文“块级格式化上下文”,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。如果一个元素具有BFC,内部元素无法影响到外部元素;外部元素也无法影响内部。类似一块具有结界的元素或则一个单独的文档流。

在块格式化上下文中,盒子一个接一个地垂直排列,从包含块的顶部开始。两个同胞框之间的垂直距离由“margin”属性决定。块格式上下文中相邻块级框之间的垂直边距折叠。

在块格式设置上下文中,每个框的左外边缘与包含块的左边缘相接触(对于从右到左的格式设置,右边缘相接触)。即使在浮动存在的情况下也是如此(尽管一个盒子的行盒可能会因为浮动而收缩),除非盒子建立一个新的块格式上下文(在这种情况下,盒子本身可能会因为浮动而变窄)。

注意:BFC属于正常文档流,floats、绝对定位元素、不是块状盒子的块状容器(例如:inline-block、table-cell、table-caption),以及其他情况,会为其内容创建新的的BFC。

所以之前常见元素之间能相互影响的情况:

  • margin重叠—影响外部元素
  • 浮动—直接影响父元素的高度,间接影响其他元素的布局

都可以借助新建BFC进行处理

触发条件

  • <html>根元素
  • 浮动元素—float 的值不是none
  • overflow—值不为 visible 的块元素
  • display 的值不是table-cell\table-caption和inline-block中的任何一个
  • 绝对定位元素—元素的 position 为 absolute 或 fixed
  • 弹性元素—display为 flex 或 inline-flex元素的直接子元素
  • 网格元素—display为 grid 或 inline-grid 元素的直接子元素
  • 多列容器—元素的 column-count 或 column-width 不为 auto,包括 column-count 为 1
  • column-span 为 all 的元素始终会创建一个新的BFC,即使该元素没有包裹在一个多列容器中

BFC应用

margin 重叠

1
2
3
4
<body>
<div style="width: 200px;height: 200px;background-color: red;margin: 20px;"></div>
<div style="width: 200px;height: 200px;background-color: green;margin: 20px;"></div>
</body>

重叠示例:
margin重叠.gif

两个块状元素上下margin出现重叠,如果要避免重叠根据上面BFC的介绍,我们可以新建一个BFC区域。

1
2
3
4
<body>
<div style="width: 200px;height: 200px;background-color: red;margin: 20px;over"></div>
<div style="width: 200px;height: 200px;background-color: green;margin: 20px;"></div>
</body>

创建新的BFC消除影响,原理:BFC不会被其他元素的margin影响

1
2
3
4
5
6
7
8
<body>
<div style="overflow: hidden;">
<div style="width: 200px;height: 200px;background-color: red;margin: 20px;"></div>
</div>
<div>
<div style="width: 200px;height: 200px;background-color: green;margin: 20px;"></div>
</div>
</body>

消除marin重叠.png

清除浮动(阻止元素被浮动元素覆盖)

1
2
3
4
<body>
<div style="width: 200px;height: 200px;float: left;background-color: blueviolet;"></div>
<div style="width: 200px;height: 200px;background-color: brown;"></div>
</body>

紫色下面还有一个大小完全一致的深红色的盒子被浮动的盒子完全覆盖

浮动元素覆盖.png

1
2
3
4
5
6
7
8
<body>
<!-- <div style="overflow: hidden;"> -->
<div style="width: 200px;height: 200px;float: left;background-color: blueviolet;"></div>
<!-- </div> -->
<div style="overflow: hidden;">
<div style="width: 200px;height: 200px;background-color: brown;"></div>
</div>
</body>

将被覆盖元素用新建的BFC包裹,原理:浮动元素是一个BFC和新建的BFC按普通文档流依次排列

防止被浮动元素覆盖.png

清除浮动(BFC包含浮动元素)

1
2
3
4
<body>
<div style="width: 200px;height: 200px;float: right;background-color: blueviolet;"></div>
<div style="width: 200px;height: 200px;background-color: brown;"></div>
</body>

浮动

影响外部div元素位置上移

1
2
3
4
5
6
<body>
<div style="overflow: hidden;">
<div style="width: 200px;height: 200px;float: right;background-color: blueviolet;"></div>
</div>
<div style="width: 200px;height: 200px;background-color: brown;"></div>
</body>

将浮动元素用一个新建的BFC包裹,但是不是使用浮动建立的。新BFC回归文档流,float元素在新BFC中浮动,无法出来。

清除浮动

自适应布局

  • BFC 与 float

    相对纯流体布局,自适应内容自动填满浮动以外区域。无需考虑浮动元素的宽度;无需考虑margin和padding撑开间距。

可以考虑抽象几个通用的布局类名:

  • .left { float:left; }
  • .right { float:right; }
  • .bfc { overflow:hidden; }

由于创建BFC的元素都比较特殊,有其自己的属性,一般建议使用

  • overflow:heidden
  • 融合display:table-cell 和 display:inline-block
    1
    2
    3
    4
    5
    6
    .lbf-content{
    display:tabel-cell;width:9999px;
    // 兼容IE7
    display:inlinte-block;
    width:auto;
    }

总结

BFC 类似于在一个文档流中又创建了一个文档流;日常中元素会相互影响,但是文档流不会;因此可以利用新建文档流包裹元素来避免影响。

参考:css2.2

css世界--流

本书主要基于css2进行讲解,本书除了对于一些属性的讲解,最重要的部分就是对于css流的介绍。在一开始学习了解css的时候我们就知道css的基础就是“流”,但是当时对于流的理解是css自身的一种属性。但是通过本书可以了解到流也是由来和作用。

流体布局

所谓“流体布局”,指的是利用元素“流”的特性实现的各类布局效果,因为“流”本身具有自适应性,所以“流体布局”往往都是具有自适应性的。但是,“流体布局”并不等于“自适应布局”

无宽度

对于块状元素,如果width:auto,则元素会如流水一样充满整个容器,而一旦设定了width具体数值,则元素的流动性会消失。如果宽度作用在content box上,内外流动性皆无。

CSS流体布局下的宽度分离原则

所谓“宽度分离原则”,就是css中width属性不与影响宽度的padding/border(有时候包括margin)属性共存。
如下:

  • 不要出现这种写法
    1
    .box { width:100px; border: 1px solid; padding:20px;}
  • 鼓励这种写法(分离 width 独立占用一层标签,padding\border\margin利用流动性在内部自适应)
    1
    2
    3
    4
    5
    6
    7
    .father {
    width:142px;
    }
    .son {
    padding:20px;
    border:1px solid;
    }
    思想:
    便于维护,盒子尺寸中4个属性都能影响到宽度,因此改动需要非常小心精确算好对于宽度的影响。宽度分离后,宽度在外层单独固定。内部调整padding\margin\border相互自适应调整(流体)依旧充满整个父元素空间。如果不考虑替换元素,所有页面基本只需要一个width设定就可以了,内部元素根据流体填充。

*{box-sizing:border-box} vs 宽度分离

border-box 无法解决所有问题。box-sizing 不支持margin-box,只有元素没有水平margin的时候,box-sizing才能和我们预想中一样,宽度分离可以使用所有情况。
而且 box-sizing 的初衷是解决替换元素的宽度自适应问题。

无宽度业务运用

通用:

  1. 如必须使用 width 属性数值使用比例数值

左右两栏布局

  1. position:absolute + padding-left
  2. float:left + padding-left

多栏布局

  1. column-width + 百分比

总结:宽度分离—充分利用流动性用内部元素充满父元素,不要用具体数值限制非直接内容元素的宽度,让他们被具体内容填充。具体的排版使用padding\margin\float\positon 等属性进行调整。充分利用子元素填充支撑父元素。

奇怪的行高

问题点

我们先想想这段代码的浏览器渲染效果是什么样?

1
2
3
4
5
6
7
<!-- 页面骨架 -->
<div class="test">
<span class="size-style">sphinx</span>
</div>
<div class="test1">
<span class="size-style1">sphinx</span>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* 页面样式 */
.test {
font-family: simsun;
line-height: 40px;
background-color: yellow;
display: inline-block;
}
.size-style {
font-size: 31px;
background-color: white;
}

.test1 {
font-family: simsun; //宋体,字体显示区域大小与字体大小一致
line-height: 40px;
font-size: 31px;
background-color: yellow;
display: inline-block;
}
.size-style1 {
background-color: white;
}

粗看这段代码是两个一模一样的行内块级元素并排,因为 CSS font-size 属性的继承性,内部只有一个子元素,属性值写在子或父元素全部一致。理论渲染的效果也应该是一样。

理论效果.png

  • test 与 test1 的高度为 40px (行高)

但是实际浏览器渲染的结果如下图所示

实际效果.png

  • test1 元素高度 44px
  • test 元素高度 40px (行高)

这多出来来的4px高度是撒?

看渲染效果 test 和 test1 大体相似上半行距和字体显示局域是一样的,区别在于下半行距,test 多出的 4px就在这个区域。我们可以猜测是 test 内的 span 下方多出一个块级元素或换行的行内元素还有同行的行内元素(无宽度)。

  1. 我们先试试改变行高这个 4px 差的差距会跟随变化吗。(有变化=>但是从数值看不会是元素下方的)
  2. 删除 test 上的 line-height 属性。(发现 line-height 的默认值不会产生这个 4px 的误差)
  3. 查询 line-height 的默认值,是相对量。尝试使用其他相对量。(发现相对量不会产生 4px 误差;只有绝对量才会产生)。
  4. 尝试改变 font-size 的值(发现 4px 大小发生变化;额外元素能响应 font-size,但是想不出那个元素符合)。
  5. 好难看不出这是个撒,google了下发现每个 line-box 的起始位置都有一个宽度为 0 的字符(CSS 文档将其称为 strut),并将其纳入 line-box 的高度的计算中。

下面我们来验证下这个看不见的字符

前提:

  • 行内元素默认对齐是根据字符的基线
  • font-size的大小不等于实际看见的字符大小(content area)
  • 同一个 size 不同字体看见的字符大小也不一样,具体跟字体自己的规定相关(注:simsun 宋体 字符大小和font-size一致)
1
2
3
4
5
6
<div class="test">
<span class="size-style2">x</span>
</div>
<div class="test">
<span class="size-style">sphinx</span>
</div>
1
2
3
.size-style2 {
background-color: white; //其他属性继承自父元素,模拟幽灵元素
}

snipaste_20200229_172517.png

可以发现x字符由于字体和字号的不一样,字符占据的空间 + 字间距对比会有下沉。如果用一个元素包裹 x 和 test1 元素就会渲染出 test1 的样式。test1 中幽灵元素没造成影响是因为幽灵元素继承了父元素的字体字号与中属性一致​。​

问题解决

可以发现只要控制幽灵元素和其上下间距的范围不超出想实现效果的范围即可

方案:

  • 减小幽灵元素的字体大小(推荐,比较彻底直接设置0)
  • 减小幽灵元素的行高大小

参考:

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×