内容


CSS 真的可以浮动么?

关于 CSS 浮动属性的行为、使用和支持的概览

Comments

从人类开始书写文字的早期,我们就看到了文绕图的实践。

Web 的先驱们很早就认识到了文字绕图编排的美学价值及这样做所能节省出来的空间,于是在 Netscape 1.0 和 HTML 2.0 中都包括进了一种 “浮动” (float)功能。浮动功能亦成为了 HTML 标准和级联样式表(Cascading Style Sheet,CSS)规范的基本属性。

虽然 “浮动” 属性的定义十分直观,但该属性的实现和使用却让很多 Web 页面设计者为了能让页面按理想的那样显示而煞费苦心并投入了大量的时间。

在本文中,我将介绍 “浮动” 属性的如下方面:

  • 定义和概念模型
  • 常见用例
  • 开发工具的问题
  • 浏览器问题

何为 “浮动” 属性?

在 CSS2 规范中,可以找到浮动属性的权威性定义和行为原则。在本文后续的章节中,我将对 CSS2 规范中的 9.5 节 “Visual Formatting Model” 中描述的内容展开讨论(相关链接,请参看 参考资料)。

定义

浮动属性指定了某个框应该向左侧还是向右侧浮动。此属性可应用于任何能生成位置不绝对固定的框(box)的元素。

此属性可有如下的值:

  • inherit - 该元素继承封装元素的浮动属性。此值为默认值。
  • left - 该元素生成一个浮动到左侧的块状框。内容排列到该框的右侧,并从顶部开始。这种排列取决于元素的 “clear” 属性。除非该值为 “none”,否则都会忽略 “display” 属性。
  • right - 这种排列取决于元素的 “clear” 属性。除非该值为 “none”,否则都会忽略 “display” 属性。
  • none - 该框不浮动。

行为

浮动属性受限于如下规则。本文中,我只对左浮动行为进行详细描述。要获得右浮动行为的相应信息,只需互换方向即可(即,将左换成右)。

此规范依据框的边框定义行为。CSS 框模型中的四种不同的边框描述如下:

  • content edgeinner edge 围绕所呈现的元素内容。这是最接近内容的边缘。
  • padding edge 包括了应用到某元素的留白。padding edge 定义了此包含块的边缘。
  • border edge 包括了应用到某元素的边界。
  • margin edgeouter edge 包括了应用到某元素的边框。

包含块的水平限制:左浮动框的 margin edge 不能在包含块的左 padding edge 框的左边。

包含块的垂直限制:左浮动框的上 margin edge 不能高于包含块的上 padding edge。

之前浮动限制:如果当前框是左浮动框而且之前的框也是左浮动框,那么当前框的左 margin edge 必须在之前框的右 margin edge 的右边,或者当前框的上 margin edge 必须要低于之前框的下 margin edge。

无交叠限制:左浮动框的右 margin edge 不能在任何共享相同水平空间的右浮动框的左 margin edge 之右。

之前元素的垂直限制:左浮动框的上 margin edge 不能高于任何块或在由源文档中前一元素生成的被浮动框的上 margin edge。

Line-box 垂直限制:左浮动框的上 margin edge 不能高于任何包含由源文档中前一元素生成的框的 line-box 的上 padding edge。line-box 是一个假想的矩形框,包含在此块级包含元素内连成一线的所有 inline box。其高度(上 padding edge)取最高的那个 line-box 的高度。

对立水平边框限制:如果一个左浮动框的左边还有另一个左浮动框,那么这个左浮动框的右 margin edge 不能在此包含块的右 padding edge 之右。即,左浮动框不能超出此包含块的右边缘,除非它已经被定位在向左足够远的地方。

最佳垂直限制:浮动框必须被置于此包含块内尽量高的地方。

最佳水平限制:浮动框必须被置于此包含块内向左尽量远的地方。

位置优先原则:在判断浮动框位置时,最佳垂直限制优于最佳水平限制。即,要先向上移动浮动框,然后再向一侧移动。

图 1 展示了这些行为原则是如何定位一个边框与文本块相关的图像的。

图 1. 左浮动框的定位示例
fig1.gif
fig1.gif

其他考虑

让 Web 设计新手感到疑惑的一个问题是应该将被浮动元素置于源文档的什么位置。要解决这个问题,可以采用如下这些经验指导。

定位:浏览器决定了被浮动元素相对于该元素在文档的 “正常排列” 中的位置的垂直位置。正常排列是指如果浏览器忽略定位属性的话文档将如何显示。被浮动元素会从这种编排被拿出并会被在其包含块内向左(或右)移动尽量远的位置。

内联成为块:为了页面格式化,被浮动元素成为了块状框。这等价于指定 display: block 属性。

所需宽度:被浮动元素应该有指定的宽度。CSS2 规范要求元素必须要么具有使用 “宽度” 属性指定的显式宽度,要么具有从所包含的子元素(比如图像)计算得出的隐式宽度。图像的隐式宽度是图像属性的一部分。如果不指定宽度,那么结果将不可预知。

何为 “clear” 属性?

被浮动元素的后续元素均会围绕该被浮动元素。总的来说,对于文本,这是一种所希望出现的效果。但是,如果是为了布局而使用浮动,那么就需要停止围绕行为。要停止此行为,后续元素需要指定 “clear” 属性。

CSS2 规范提供了有关 clear 属性的权威性定义和行为原则。在本文的后续章节,我将就 CSS2 规范 9.5 节 “ Visual Formatting Model” 展开讨论(参见 参考资料)。

定义

clear 属性表明了一个元素的框的哪一侧或哪些侧不必与之前的浮动框相邻。如果元素本身具有浮动后代,那么 clear 属性对这些后代没有任何影响。

clear 属性只能应用于块级元素。这包括借助浮动属性被转变成块级元素的那些元素。

此属性可以有以下这些值:

  • inherit - 此元素承继封装元素的 clear 属性,为默认值。
  • left - 增加所生成框的上边框,以便上 border edge 处于由之前的源元素所生成的任一左浮动框的底 margin edge 之下。
  • right - 增加所生成框的上边框,以便上 border edge 处于由之前的源元素所生成的任一右浮动框的底 margin edge 之下。
  • both - 将所生成框移动到由之前的源文档所生成的所有浮动框之下。
  • none - 不对框的位置应用任何与之前的被浮动元素相关的限制。

行为

clear 属性的行为基本上就是对定位被浮动元素的规则的修改。在此规范中,行为亦被视为一种额外的限制。

Clear 限制:浮动框的上 margin edge 必须要处在所有先前的左浮动框(“clear:left” 的情况)、或所有先前的右浮动框(“clear:right” 的情况)、或二者(“clear:both” 的情况)的底 margin edge 之下。

图 2 给出了一个 clear 属性的使用示例。两个段落均具有属性 “clear:left”。这对第一个段落或在第一个段落内定义的浮动框没有任何影响。clear 属性只会让第二个段落定位于浮动之下。请注意第二个段落的上边框是如何垂直扩展以便与前一段落的底边框相接的。

图 2. Clear 定位示例
fig2.gif
fig2.gif

其他考虑

与 clear 属性相关的一个常见困难是其使用常常需要在文档内的后续元素上添加额外的标记。

清单 1 显示了添加一个空白的 division 导致向 HTML 文档增加了非内容标记。

清单 1. 处理 clear 需要额外标记
<div class="myFloatClass">
    <p>myFloatClass has float:left specified</p>
</div>
<div class="myClearClass" />
    <!--myClearClass has clear:left specified-->

先后有几名作者提出了各种技术来消除对 HTML 文档添加额外标记的需要。这些技术包括:

  • 向容器元素添加 “float”。
  • 向容器元素添加 “overflow:hidden”。
  • 在容器元素上添加一个 CSS2 “:after” 伪类。

浮动容器技术(Float Container Technique):该技巧常常见于页面布局和水平导航菜单 — 在浮动容器内放上一个浮动元素。浮动容器会被扩大以包含所有内部的浮动元素。这种方式需要准确设置容器的宽度属性,100% 是常见的一种设置。

这种技术有几个缺点。第一个缺点是很难设置宽度,使用 100% 可能会与留白冲突。第二,Internet Explorer V6 可能还会添加额外的底边框。最后,浮动框的深度嵌套常常会导致在浏览器中产生某些不可预知的行为。

清单 2 显示了这种浮动容器技术所使用的 CSS 代码。

清单 2. 浮动容器技术
.myFloatClass {
    float: left;
    width: 100%;
}

隐藏溢出容器技术(Hidden Overflow Container Technique):这种方式很少使用。它涉及了对 “overflow” 属性和默认的 “clip” 属性的利用 — 一个溢出 元素会被扩至所有所含子元素(包含被浮动元素)的大小。

这种技术也有几个缺点。首先,使用溢出可能会影响容器的 fluid height。其次,溢出需要触发 Internet Explorer V6 的 “hasLayout” 属性。

清单 3 显示了隐藏溢出容器技术所使用的 CSS 代码:

清单 3. 隐藏溢出容器技术
.myFloatClass {
    overflow: hidden;
    height: 1%;
    /* Or zoom:1 to trigger IE's hasLayout */
}

:after 伪类技术:这种方式极少使用。它所涉及的是使用 CSS 伪类在容器后生成内容。使用 :after 伪类技术向结果 HTML 文档追加已指定 clear 属性的新元素。

这种技术最不推崇,提供支持的浏览器也少。Internet Explorer V7 或更早的版本不支持 :after 伪类技术。但最为重要的是,这种技术会将无意义的内容插入到结果 HTML 文档。

清单 4 显示了 :after 伪类技术所使用的 CSS 代码。

清单 4. :after 伪类技术
.myFloatClass {
    height: 1%;
    /* Or zoom:1 to trigger IE's hasLayout */
}
.myFloatClass:after {
    content: ".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
}

有无开发工具的考虑?

每个开发人员都知道,并不是所有的 HTML/CSS WYSIWYG 编辑器都是一样的。每个编辑器都有其自身的特点、对 Web 标准的遵从程度和对页面呈现引擎的选择。

我对流行的 WYSIWYG 编辑器(比如 IBM® Rational® Software Architect V7、Adobe Dreamweaver CS3 和 Genuitec MyEclipse V6)的使用经验是它们往往对页面的初始准备很有帮助,但若要进行页面调整和优化,您通常都会不得不进行源代码级别的工作。在目标浏览器中进行页面测试至关重要。很多编辑器都包括了对各种浏览器的插件支持,这样一来,就可以从编辑器中启动浏览器来对页面进行测试。

如果需要对某个 WYSIWYG 编辑器进行评估,我建议用 Acid2 Browser Test 对此编辑器(参见 参考资料)进行测试。Acid2 Browser Test 由 Web Standards Project 开发,用来测试各种浏览器对 Web 标准兼容性。不过,您也可以使用 Acid2 Browser Test 源来测试您备选的 HTML/CSS WYSIWYG 编辑器对 Web 标准兼容性。

有无浏览器方面的考虑?

Web 设计人员业已发现了流行的 Web 浏览器中的很多非标准的行为。

各种浏览器都以不同的方式实现了嵌套浮动元素。其结果是,为了定位的目的,常常需要避免使用被浮动元素的深层嵌套。 在这些情况下,更好的方法是使用相对和绝对定位属性。

Internet ExplorerPosition Is Everything 站点维护 Internet Explorer bug 以及修复手段的目录。请参看 Explorer Exposed 页

Firefox:我在 Firefox 中发现的一个与定位相关的 bug 是 Top Gap Bug。这个 bug 通常都会出现于多栏布局,其中栏是浮动的,而 header section 却不是。如果其中某个栏中的某个元素具有上边框,那么此边框会被推至 header 之上,导致窗口顶部和 header 顶部之间出现间隙。修复的手段是在被浮动栏上放一些东西。一种方式是向具有 clear:both 属性的头的底部添加一个元素。另一种方式是让 header 也浮动。

OperaPosition Is Everything 站点存有 Opera bug 以及修复手段的目录。请参看 Opera Omnibus 页

结束语

自 Web 浏览器技术出现的早期,在页面上浮动元素的功能就已经存在。现代的 Web 设计开始越来越多地使用浮动属性来获得之前使用表实现的页面布局。尽管浮动属性的定义和行为都很简单,但浏览器的不一致性却让使用此属性变得有些困难。本文只对浮动属性作了十分浅显的介绍。更多信息,请参看 参考资料 部分,当然,也要勇于亲自实践。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Web development
ArticleID=301529
ArticleTitle=CSS 真的可以浮动么?
publish-date=04222008