YAOHAIXIAO.COM

HTML(5),CSS(3),JavaScript,DOM,Ajax,JSON,Front-end technologies & Yaohaixiao

热门标签:JavaScript Performance 前端开发 前端性能优化 原创

Rss

Home » Frontend » CSS » CSS学习经验总结 – float 浮动元素

CSS学习经验总结 – float 浮动元素

CSS 中的 float

要做到前面 HACK 篇提到的优化前端性能,我们就必须要有扎实的 CSS 的技术基础。需要对各个 CSS 属性和选择器等基础知识有着深刻了解才能做到优化代码性能。由于篇幅有限,我不能一一介绍各个 CSS 属性,具体内容还需要大家自己产看《CSS 权威指南》、阅读 W3CCSS 标准文档。我这里想介绍是 CSS 里一个十分重要的属性 float

为了讲解 float,我想还是从最常见的一个 IE 显示 bug —— float 元素的双倍边距问题讲起。在前面 haslayout.net 的《Double Margin Bug》中介绍了这个 bug 的解决办法:添加 display:inline;。 不过为什么使用 display:inline; 就可以解决了呢?

‘display’ 和 ‘float’ 之间的关系

在说明为什么前,我推荐大家一定看看 MaxDesign 的 《Float Tutorial》以及 W3C 的《Floats》来学习关于 float 的相关知识。

原来在 W3C 的《Relationships between ‘display’, ‘position’, and ‘float’》这一章节介绍了 display 和 float 的关系。我这里把 W3C 的原文引用贴出来:

The three properties that affect box generation and layout — ‘display’, ‘position’, and ‘float’ — interact as follows:

  1. If ‘display’ has the value ‘none’, then ‘position’ and ‘float’ do not apply. In this case, the element generates no box.
  2. Otherwise, if ‘position’ has the value ‘absolute’ or ‘fixed’, the box is absolutely positioned, the computed value of ‘float’ is ‘none’, and display is set according to the table below. The position of the box will be determined by the ‘top’, ‘right’, ‘bottom’ and ‘left’ properties and the box’s containing block.
  3. Otherwise, if ‘float’ has a value other than ‘none’, the box is floated and ‘display’ is set according to the table below.
  4. Otherwise, if the element is the root element, ‘display’ is set according to the table below, except that it is undefined in CSS 2.1 whether a specified value of ‘list-item’ becomes a computed value of ‘block’ or ‘list-item’.
  5. Otherwise, the remaining ‘display’ property values apply as specified.
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
others same as specified

从文档中 W3C 文档中我们可以看到,当给一个元素设置了 float 属性,而 float 的值不等于 none 时(inline, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, table-caption, inline-block ),元素的 Computed value 都是 block。所以在支持 W3C 标准浏览器里面,设置了 display:inline; 和设置其余的一些值,最终的显示效果都等于是设置了 display:block;,不会因为设置 display:inline 而发生显示上的任何改变。而 IE6 不知就怎么的会因为 display:inline; 而能够正确计算出 margin 的正确边距,而不再是双倍的边距了。

不知道你以前花时间看过 W3C 的 CSS 标准文档没有,原来我们前端工程师是利用了 W3C 提到的 float 和 display 之间的这种显示关系来解决双倍边距的问题的。

Float 定位(显示)的精确规则

要运用好 float 属性,就必须要了解设置了 float 元素的显示规则。还是来看看 W3C 是怎么说的吧;

left:
The element generates a block box that is floated to the left. Content flows on the right side of the box, starting at the top (subject to the ‘clear’ property).
right:
Similar to ‘left’, except the box is floated to the right, and content flows on the left side of the box, starting at the top.
none
The box is not floated.

User agents may treat float as ‘none’ on the root element.

上文分别介绍了设置给一个(HTML)元素设置了 left、right 和 none 后元素和 float 周围元素的显示规则。我这里以left为例介绍:

  • 1. 一个元素设置了 float:left,那么这个元素将生(变)成一个块级元素。这意味着如果给 span 或者 a 标签这样的行内元素设置了 float:left 后,你可以给它设置高和宽。而普通的行内元素设置宽和高是不起作用的。
  • 2. 这个元素接下来的(行内元素)的内容将在这个元素的右上方还是接着显示。这就意味着如果你给一段文字中的一个图片 img 标签设置了 float:left,那么这段文字会从图片的右上方开始,包围这个图片。

设置了 float:right 和 float:left 类似,只是接下来的内容会从左上方开始包围这个元素。而设置了 float:none 则和元素默认的显示方式一样,默认的浏览器会把跟元素(body)设置为 float:none 。

W3C 接下来就介绍了 float:left 和 float:right 这样两个浮动元素之间如何显示排列:

Here are the precise rules that govern the behavior of floats:

  1. The left outer edge of a left-floating box may not be to the left of the left edge of its containing block. An analogous rule holds for right-floating elements.
  2. If the current box is left-floating, and there are any left-floating boxes generated by elements earlier in the source document, then for each such earlier box, either the left outer edge of the current box must be to the right of the right outer edge of the earlier box, or its top must be lower than the bottom of the earlier box. Analogous rules hold for right-floating boxes.
  3. The right outer edge of a left-floating box may not be to the right of the left outer edge of any right-floating box that is next to it. Analogous rules hold for right-floating elements.
  4. A floating box’s outer top may not be higher than the top of its containing block. When the float occurs between two collapsing margins, the float is positioned as if it had an otherwise empty anonymous block parent taking part in the flow. The position of such a parent is defined by the rules in the section on margin collapsing.
  5. The outer top of a floating box may not be higher than the outer top of any block or floated box generated by an element earlier in the source document.
  6. The outer top of an element’s floating box may not be higher than the top of any line-box containing a box generated by an element earlier in the source document.
  7. A left-floating box that has another left-floating box to its left may not have its right outer edge to the right of its containing block’s right edge. (Loosely: a left float may not stick out at the right edge, unless it is already as far to the left as possible.) An analogous rule holds for right-floating elements.
  8. A floating box must be placed as high as possible.
  9. A left-floating box must be put as far to the left as possible, a right-floating box as far to the right as possible. A higher position is preferred over one that is further to the left/right.

英文水平有限,而且感觉怎么翻译都不太通顺,大家还是自己体会原文的意思。这9条显示规则是我们平时使用 float 的基础指导,只有完全理解了 float 元素的显示规则,我们才能根据自己的需要灵活的使用 float 属性来布局。这里我想提醒一下,规则中提到 A floating box must be placed as high as possible. – 浮动元素的高度应该尽量的高。其实 W3C 另外还提示过,浮动元素最好应该设置宽度。在IE中尤其应该按照 W3C 的推荐写法来写 CSS。而浮动元素显示的各种组合,在《Float Tutorial》中都一一举例说明,一定去看看啊!

如何清除浮动

在了解了浮动元素的特点,浮动元素的定位规则以及浮动元素和 display 的关系后,最后要了解的 float 相关的知识就是如何清除浮动了。其实在前面的章节有介绍过如何清除浮动的代码:

select:after {
    content:”.”;
    display:block;
    height:0;
    clear:both;
    visibility:hidden;
}

前文介绍过了这段代码的基本原理,使用 :after 伪类的方法我也不打算过不多介绍,大家可以看看《The New Clearfix Method》。实际的开发中我基本上不用这个方法,(纯属个人偏好)我觉得清除浮动的最好用的方法就是设置 overflow:hidden。我推荐大家看看《A Problem With Using “overflow: hidden” to Clear Floats》这篇文章。

其实清除浮动,无论使用 :after 伪类的方法还是使用 overflow:hidden; (其实 overflow:auto; 也是可以的),大家看看我的示例:Clear Float 就会发现,其效果都是让浮动元素的父元素获得高度(或者说 haslayout)来实现清除浮动。这里随便插一句话,你如果在IE6中查看,你才会看到真正我们期望的效果。每个 DEMO 之前的 h2 与 DEOM 的边距是一致的。虽然是我们理想状态下想要的,不过根据 W3C 的规范来说的话,却又是不符合盒模型规范的。你不要看到 IE6 中显示正常了就绝对过了,因为你还要 hack 符合 W3C 规范的浏览器啊。

在我的 DEOMO 中也演示了两个连续的区块如果都没有清除浮动的状态,前面一个 h2 我没有设置 clear:both; 显得就十分乱了,而后面一个我给 h2 添加了 clear:both; 效果就好些了。其实这个也是我们以前一阵子使用的一个清除浮动的方法。就是在需要清楚浮动的位置,添加一个内联的如 span,br 或者一个高度宽度为1px的 HTML 标签给它添加 clear:both; 来清除浮动。当然这种方法是不推荐的,因为添加了多余的无意义的HTML标签。

不过我实际开发的经验是,除了使用 :after 伪类或者 overflow:hidden; 让浮动元素的父元素获得高度外,最好还是在需要换行显示的元素(如示例中的 h2)添加 clear:both;,来显式的清除浮动。因为我发现在 chrome 浏览器的一些版本中,有时会出现原本应该换行的块级元素会跟随前面的浮动元素后面显示,而不管上一行浮动元素所在的空间是否够宽。

最后总结一下,关于 CSS 中的浮动,我们需要掌握的重点是:float 元素的定位规则float 和 display 的关系以及如何清除浮动。至于在学习 float 之前要了解的一些基础 CSS 知识,如:Block-level elements and block boxes、Inline-level elements and inline boxes 、Normal flow 、Out of normal flow 等,在 MaxDesign 的《Some definitions》中已经讲解的很清楚了,这个就需要大家自己阅读学习了。

声明:本文采用BY-NC-SA协议进行授权。转载请注明转自:CSS学习经验总结 – float 浮动元素

« »

1 条评论

  • CSS Float 的具体技巧,我这篇文章并没有介绍,主要是让初学的朋友了解CSS Float 应该了解的知识点。具体的技巧我稍后会用一片实例教程介绍从切图到写HTML到写CSS样式,以及做前端优化的全过程。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(Spamcheck Enabled)