3

引子

在维护一些项目的时候,发现不少地方用 float 来进行布局,知道这个属性的作用效果,也知道怎么解决相关的问题,但就是不能进一步说出一个所以然来,就整理一下了。

约定

这里是为了理解 float 相关的问题和解决方法,不去比较它们的优劣和兼容性,要相信未来是越来越美好的。基本的 html 结构如下:

<div class="float-parent">
  <div class="float-ele fl"></div>
</div>

以下所讲示例页面:CSS浮动float相关初解示例

手机端浏览

9-qrcode

浮动的用途

浮动设计的初衷,是为了实现文本环绕效果。在一些教程里面,关于浮动的介绍没有强调这个,而是讲如何利用这个属性的作用,去实现一些所谓“有趣”的效果。虽然拓展了思路,但感觉并没有用的合适。

浮动的介绍

W3C 文档里面说的很简洁:这个属性指定一个盒子浮动到左边、右边还是不浮动。下面是摘取过来的基本特性。

Value: left | right | none | inherit
Initial: none
Applies to: all,but see 9.7
Inherited: no

下面就是相关说明和一些注意项。

重要的认知

浮动使元素从正常的文档流中移除,脱离了正常的文档流。然后向左或者向右平移,一直移动直到碰到了所处的容器的边界,或者碰到另外一个浮动的元素。

值的作用

  • left :元素会产生一个块级盒子向左浮动,正常的文档流会从这个盒子的右边和顶部开始。
  • right :跟 left 属性值类似,只是元素产生的块级盒子向右浮动,正常的文档流会从这个盒子的左边和顶部开始。
  • none :这个盒子不浮动。

display, position 和 float 之间的关系

多次看到有人把这些属性写在一起,感觉是在用试错的心理写 CSS 。以下情况示例页面:display、position 和 float 之间的关系示例 。精力有限,规则应用下只试了部分取值情况。

这三个属性影响盒子产生和布局,它们相互影响有以下的顺序规则判断:

  1. 如果 display 的属性值为 none ,那么 positionfloat 属性不会应用。这种情况不会产生盒子。
  2. 否则,如果 position 的指定值为 absolutefixed ,这个盒子会是绝对定位,float 的计算值会取 nonedisplay 的取值规则按照下面的表格所示。这个盒子的位置取决于 toprightbottomleft 属性和这个盒子的包含块。
  3. 否则,如果 float 指定了 none 之外的值,这个盒子就会浮动,并且 display 取值规则按照下面的表格所示。
  4. 否则,如果这个元素是根元素,display 取值规则按照下面的表格所示。但在CSS2.2 有一种情况例外,指定为 list-item 的值变成计算值为 blocklist-item 时,它的值未定义。
  5. 否则,剩下的 display 属性值按照指定的值应用。
指定的值计算值
inline-tabletable
inline, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, table-caption, inline-blockblock
otherssame as specified

由以上的规则可知,将这些属性写一起,有些时候并不会起作用。对于不熟悉的人反而会造成不必要的困惑。

浮动的约束规则

约束的规则有不少,但实际中碰到的情况,并没有那么多,觉得要关注了解的点有 3 个:

  1. 浮动元素的包含块,是其最近的块级父元素;
  2. 包含块对于浮动元素的边界是指内容区的边界;
  3. 多个浮动元素之间的相互影响。

相关详细介绍见这里。如果之后实际中碰到相关情况,需在此进行补充。

浮动的问题

这个就是众所周知的父元素高度坍塌问题,由于脱离了文档流,这个是可以想象到的。为了解决这个问题,出现了 2 种说法:清除浮动闭合浮动。看了这篇文章,觉得说的很有道理,我们是为了解决高度坍塌的问题,清除浮动只是其中的一种方法,叫闭合浮动更为合适严谨。

闭合浮动的方法

方法1:利用属性 clear

样式属性 clear

结构变成如下

<div class="float-parent">
  <div class="float-ele fl"></div>
  <div class="clear-fix"></div>
</div>

新增的样式为:

.clear-fix {
  clear: both;
}

这个就是使用了 CSS 属性 clear 的特性,这个属性指出元素盒子的那边不会跟更早浮动盒子相邻,值为 both 的含义是:

在源文档里面,如果有比该元素比较早的浮动元素,需要让该元素的顶部 border 边界在,任何右浮动或左浮动元素底部外(margin)边界之下。

标签属性 clear

<div class="float-parent">
  <div class="float-ele fl"></div>
  <br clear="all" />
</div>

这个作用跟 CSS 形式一样,标签上的属性 clear 在 html5 中已经被废弃了,建议使用 CSS 属性 clear

方法2:利用伪元素

/* 添加到父元素上 */
.close-float-method2:after {
  content: ".";
  display: block;
  height: 0;
  clear: both;
  visibility: hidden;
}

这个就是用伪元素的方式替代额外的标签,主要属性还是用到了 clear 。这个方法据说在跨浏览器时有问题,里面提到的是 ie7 ,就没有去尝试,具体见这里

方法3:利用属性 overflow

/* 添加到父元素上 */
.close-float-method3 {
  overflow: hidden;
}

这个就要提到一个概念 Block formatting contexts(块级格式化上下文)

浮动、绝对定位元素和块级包含块(比如 inline-blockstable-cellstable-captions)都不是块级盒子,overflow 属性值取 visible 之外值的块级盒子为它们的内容建立新的块级格式化上下文。

在一个块级格式化上下文中,垂直方向上,盒子的放置是一个接一个,从一个包含块的顶部开始。垂直方向上两个相邻盒子的距离由 margin 属性决定。垂直边距在同一个块级格式化上下文中会产生重叠。

在一个块级格式化上下文中,每个盒子的左外边界跟包含块的左边界相接触。这个对于浮动的展示同样是适用的,除非这个盒子建立了一个新的块级格式化上下文。

这里使用了 overflow 后建立了块级格式化上下文,包含了浮动元素,所以就闭合了浮动。

以上所讲相关示例页面:CSS浮动float相关初解示例

参考资料


XXHolic
363 声望1.1k 粉丝

[链接]