浮动的原始意义

在绝大多数Web开发者的语境中,“布局”这个术语和“排版”是有差异的。“布局”偏向于指宏观的GUI区域划分,比如双栏布局或三栏布局等。从这一点出发,float其实本不是一项用于“布局”的属性。float对应的其实是传统印刷排版中图文混排中的环绕

在 CSS 中,用 float 和 position 的区别是什么?

浮动的特性

float与block

常见元素inline,inline-block,table-cell等等设置float属性,都被视为块级元素,相当于display设置为block

Specified value Computed value
inline-table table
inline, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, table-caption, inline-block block
其它 与指定值相同

float与包裹性

如果margin-left或者margin-right的计算值为auto,它们的应用值为0

对于非替换元素,如果width的计算值为auto,应用值为“自适应(shrink-to-fit)”宽度

自适应宽度的计算与用自动表格布局算法去算一个表格单元的宽度类似。粗略地讲:通过格式化不含除显式换行外的换行来计算首选宽度(preferred width),然后计算首选最小宽度(preferred minimum width),例如,通过尝试所有可能的换行。CSS 2.1没有定义准确的算法。第三步,算出可用宽度(available width):这种情况下,就是包含块的宽度减去margin-leftborder-left-widthpadding-leftpadding-rightborder-right-widthmargin-right和所有相关滚动条的宽度的应用值

那么自适应宽度就是:min(max(首选最小宽度, 可用宽度), 首选宽度)

对于替换元素,width的应用值由行内的可替换元素决定

我们说的包裹性,主要就是指自适应宽度,通常情况下也就是首选宽度

特定情况下(例如,见上面的10.6.4节和10.6.6节),一个建立了块格式化上下文的元素的高度按照如下规则计算:

如果它只含有行内级子级,高度就是最高的行盒的top与最低的行盒的bottom之间的距离

如果它只含有块级子级,高度由就是最高的块级子级盒的top margin-edge到最低的块级子级盒的bottom margin-edge之间的距离

此外,如果该元素含有任意bottom margin边位于元素的content边下方的的浮动后代,那么高度增加至能够包含这些边。只考虑参与此块级格式化上下文的浮动,例如,不考虑绝对定位的后代中的浮动或者其它浮动

float包裹性展示

float与兄弟元素

浮动 在浮动模型中,一个盒先根据常规流布局,然后从流中取出来尽可能地左移或右移。其它内容可能会沿着浮动(盒)的一侧排列(Content may flow along the side of a float)

一个浮动盒会向左或向右移动,直到其外边(outer edge)挨到包含块边或者另一个浮动盒的外边。如果存在行盒,浮动盒的外top(边)会与当前行盒的top(边)对齐

因为浮动(盒)不在流内,在浮动盒之前或者之后创建的未定位的(non-positioned)块盒会竖直排列,就像浮动不存在一样。然而,接着(next to)浮动(盒)创建的当前及后续行盒会进行必要的缩短,为了给浮动(盒)的margin box让出空间

浮动(盒)的内容会堆叠起来,就像浮动(盒)生成了新的层叠上下文(stacking contexts)一样,除了所有定位的元素和实际创建了新的层叠上下文并参与了浮动(盒)的父级堆叠上下文的元素。一个浮动(盒)可以与常规流中的其它盒重叠(例如,当一个常规流盒接着一个有负margin的浮动(盒)时),出现这种情况时,浮动(盒)会被渲染在未定位的(non-positioned)流内块之前,流内行内(盒)之后

float虽然使元素脱离了文档流,但是它仍然占据着位置,这也是影响外部元素宽度计算的原因之一

float盒的兄弟块盒会竖直排列,当作float盒不存在,而兄弟行内盒会缩进,给float让出空间

对于float盒,如果它与常规流中的其它盒重叠,那么它会覆盖流内块,并且被流内行内盒覆盖

float与图文混排

一个浮动的盒与任何其它盒之间的margin不会合并(甚至一个浮动盒与它的流内子级之间也不会)

  1. 一个左浮动盒的left外边(outer edge)不能位于其包含块的left边的左边。向右浮动的元素也有类似的规则
    float与左右边界

  2. 如果当前盒是向左浮动的,并且在这之前源文档中还有元素生成了左浮动盒,那么对于每一个之前的盒,要么 当前盒的left外边在之前的盒的right外边的右边,要么它的top要比之前的盒的bottom低。右浮动盒也有类似的规则
    float与兄弟float排列

  3. 一个左浮动盒的right外边不能位于接着它的任意右浮动盒的left外边的右边。右浮动盒也有类似的规则
    float与兄弟float不能重叠

  4. 一个浮动盒的外top(outer top)不能高于其包含块的top。当浮动(盒)出现在两个合并的margin之间时,浮动(盒)的定位就像它有一个空的匿名块父级存在于(当前)流一样。这个父级的位置通过margin合并章节中的规则来定义
    float与margin

  5. 一个浮动盒的外top不能高于源文档中任何在此之前的元素生成的块盒或者浮动盒的外top
    float与块盒,浮动盒

  6. 一个元素的浮动盒的外top不能高于任何含有源文档中在此之前的元素生成的盒的行盒的top
    float与行盒

  7. 左边存在另一个左浮动盒的左浮动盒的right外边不能位于其包含块的right边的右边(不严谨的:一个左浮动盒不能超出right边,除非它已经尽量向左(紧挨着包含块的left边)了)。右浮动元素也有类似的规则
    多个float与包含块边界

  8. 浮动盒必须尽量高往高放(A floating box must be placed as high as possible)

  9. 左浮动盒必须尽量往左放,右浮动盒尽量往右放。更高的位置要比更左/右的位置优先
    float与高度

所以,float自身的主要原则是:浮动元素之间不重叠;尽可能向边缘漂浮,但不越界。

float与父元素

overflow计算值为visible时常规流中的块级不可替换元素

只考虑常规流中的子级(即,浮动盒和绝对定位的盒会被忽略,并且相对定位的盒不考虑其偏移)。注意子级盒可以是一个匿名块盒

这就是float元素的父元素塌陷的原因

float与父元素塌陷

那么,float在父元素的兄弟元素上会不会起作用呢

float与父元素的非浮动,浮动兄弟元素

这些规则里涉及的其它元素仅仅是指与浮动(盒)处于同一个块格式化上下文的其它元素

由于父元素跟它的兄弟元素同出于一个BFC中,所以行为规则与同处于同一个父元素之中的元素的规则相同:块级元素重叠;行内元素环绕;浮动元素跟随。

clear与闭合浮动

该属性说明了一个元素的盒的哪一边不能与之前的浮动盒相邻。'clear'属性不考虑元素自身的或者其它块格式化上下文中的浮动

为了解决上面的父元素高度塌陷以及父元素的兄弟元素受到子元素float影响的问题,我们需要闭合浮动

.clearfix:before,
.clearfix:after
{
  display: table;
  content: " ";
}
.clearfix:after
{
  clear: both;
}
.clearfix{*zoom:1;} //ie 6 7

before是因为table类型能生成独立的bfc,防止上边距塌陷,

after负责清除浮动,防止父级高度塌陷;配合使用,代码少,效率高。

想要具体了解,请看一丝大大的那些年我们一起清除过的浮动,这里就不详细写了

回归CSS标准之Float


人丑就要多读书_
197 声望17 粉丝