CSS布局——BFC

上网游荡,意外间发现寒冬大神的关于CSS布局博客http://www.cnblogs.com/winter-cn/archive/2013/05/11/3072929.html和面试博客感觉有点意思,所以花点时间来梳理梳理。

大牛的问题是——position的哪些取值和行为
答案:normal flow、containing block、bfc、margin collapse,base line,writing mode,bidi。。。

了解基本概念:

  • viewport:
    展现网页的媒体,比如窗口或者某个区域,它的大小是有限制的,为了不被平台术语所束缚,我们给他起名viewport,中文意思就是视口。
  • canvas:
    而我们在渲染网页的时候通常并不知道我们需要多大的空间,而且这些空间通常尺寸会超过viewport的大小,于是实际上我们需要设想一个无限大的画布来绘制我们的元素,我们把它称为canvas。
  • box:
    element(元素)和node(节点)是大家很熟悉的概念,当我们做布局计算的时候,通常会把节点变成box,一个节点可能产生多个box,伪元素也会产生box。
  • render tree: 对应于dom树,我们把box的包含关系构成的属性结构成为渲染树render tree

首先来看BFC,BFC(Block Formatting Context)块级格式化上下文

Formatting Context:指页面中的一个渲染区域,并且拥有一套渲染规则,他决定了其子元素如何定位,以及与其他元素的相互关系和作用。

BFC:块级格式化上下文,它是指一个独立的块级渲染区域,只有Block-level BOX参与,该区域拥有一套渲染规则来约束块级盒子的布局,且与区域外部无关。

简单示例:

<html>
  <head><title></title></head>
  <body>
    <div style="width:300px;height:50px;"></div>
    <div style="width:300px;height:20px;"></div>
    <div style="height:50px;"></div>
    <div style="width:300px;height:50px;"></div>
  </body>
</html>

简单地说,BFC就是像例子里面一样顺次竖着排块级盒的一种上下文。

BFC的产生

既然上文提到BFC是一块渲染区域,那这块渲染区域到底在哪,它又是有多大,这些由生成BFC的元素决定,CSS2.1中规定满足下列CSS声明之一的元素便会生成BFC。

  • 根元素
  • float的值不为none
  • overflow的值不为visible
  • display的值为inline-block、table-cell、table-caption
  • position的值为absolute或fixed

      看到有道友文章中把display:table也认为可以生成BFC,其实这里的主要原因在于Table会默认生成一个匿名的table-cell,正是这个匿名的table-ccell生成了BFC。
      canvas会设立一个BFC,这也是最外层的formatting context了,问题的复杂性在于有些块级盒内部也可以产生BFC(至少它必须也能包含块级盒),于是说BFC是可以嵌套滴
      

<html>
  <head><title></title></head>
  <body>
    <div style="width:300px;height:100px;">
      <div style="width:300px;height:20px;"></div>
      <div style="height:50px;"></div>
    </div>
    <div style="height:50px;"></div>
  </body>
</html>
  

不是所有块级盒内部都可以产生BFC,比如说要是这盒里面连块级盒都没有,都是行内盒那就产生IFC。

<html>
  <head><title></title></head>
  <body>
    <div style="width:300px;height:100px;overflow:visible;">
      <span></span><span>囧囧</span>
    </div>
    <div style="height:50px;"></div>
  </body>
</html>

上例中,第一个div中overflow:visible不产生BFC,它的子元素直接搞进自己外层的BFC;但是第二个div产生的是BFC,所以只要它的子节点里面有一个块级盒,它就产生BFC,那些行内元素,会自动套一个匿名的块级行盒。

overflow:visible这个限制只对所谓的块盒(既包含块级盒、自己又是块级盒)存在,有些盒内部也能包含块级元素,但是它本身又不是块级元素(比如display为table-cell、inline-block、或者盒本身是flex item等),因为外面不是BFC,所以它们不论如何一定会给包含的块级盒创建一个新的BFC出来。

总结:
BFC的约束规则
浏览器对于BFC这块区域的约束规则如下:

  • 生成BFC元素的子元素会一个接一个的放置。垂直方向上他们的起点是一个包含块的顶部,两个相邻子元素之间的垂直距离取决于元素的margin特性。在BFC中相邻的块级元素外边距会折叠。
  • 生成BFC元素的子元素中,每一个子元素做外边距与包含块的左边界相接触,(对于从右到左的格式化,右外边距接触右边界),即使浮动元素也是如此(尽管子元素的内容区域会由于浮动而压缩),除非这个子元素也创建了一个新的BFC(如它自身也是一个浮动元素)。

      有道友对它做了分解,我们直接拿来:

    1. 内部的Box会在垂直方向上一个接一个的放置
      垂直方向上的距离由margin决定。(属于同一个BFC的两个相邻Box在流方向上margin会发生重叠)
    2. 每个元素的左外边距与包含块的左边界相接触(从左向右),即使浮动元素也是如此。(这说明BFC中子元素不会超出他的包含块,而position为absolute的元素可以超出他的包含块边界)
    3. BFC的区域不会与float的元素区域重叠 计算BFC的高度时,浮动子元素也参与计算
    4. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然

        看到以上的几条约束,让我想起学习css时的几条规则
        
      IFC
      IFC里面可能有文字、行内元素混合排布:

<html>
  <head><title></title></head>
  <body>
    <div style="">
      <span></span>囧囧囧<span>囧囧</span>
    </div>
  </body>
</html>

对于一个正常的”行盒”来说,文字总是垂直居中排布的。

在纵向,文本排布主要受line-height属性影响,在有行内盒参与的情况下就复杂了,
一个行内盒的vertical-align可以有这样几种取值:

baseline
sub
super
top
text-top
middle
bottom
text-bottom
它也可以是某一指定高度。根据行内盒的对齐方式,它有可能把这行盒向上或者向下”撑大”,造成超过行高的情况。

所以行盒在BFC中占据的实际高度,很可能大于line-height。

文字的baseline很好理解,而行内元素则比较复杂,特别是当行内元素自身又是容器的时候:

猜你喜欢

转载自blog.csdn.net/ty13438189519/article/details/51997039