The Mystery Of The CSS Float Property

数年前,当开发者首次开始不使用table 来布局网页时,CSS中的一个property突然间显得格外重要,该属性就是floatfloat属性变得如此常用的原因在于:默认情况下,在一个以列布局的方式中 block-level元素之间不会对齐。因为column在实际的CSS布局中 是常用且必需的,所以float属性逐渐地被极多地采用(甚至滥用)。

CSS float 属性是什么?

CSS的float 属性允许开发者 在不使用table的前提下 在网页的布局中 融入类似表格的 column。如果不是因为CSS的float属性,不使用绝对和相对定位,CSS的布局是不可能实现的。采用 相对定位和绝对定位 实现的布局 会非常凌乱 并且 这样的布局是不可维护的。

在这篇文章中,我们将会具体讨论:float属性是什么;float属性 在具体的上下文中 是如何影响元素的。我们也会看看float属性在大多数常用的浏览器中 会有哪些差异。最终,我们会展示:CSSfloat属性的一些实际的使用。这将会提供一个对float属性 全面地且透彻地讨论。

定义与语法 - Definition and Syntax

CSSfloat属性的目的 在于:把一个block-level元素推到左边或者右边,使该block-level元素 相对于其它的元素 脱离文档流。这使得 自然流动的内容 会包裹浮起来的元素。这个概念类似于:你每天在印刷媒体上所看到的内容(图片或其它图像元素 对齐于左边或者右边,其它的内容 通常是一些文本 会环绕在 左对齐或右对齐的 图片元素 周围)。如下图所示:

The Mystery Of The CSS Float Property_第1张图片
https://www.smashingmagazine.com/wp-content/uploads/2009/10/print.jpg

上图展示了:3个图片 在它们各自的列中 都是左对齐的,并且都被文字环绕着。这是CSS布局中 float属性的基本观念,并且展示了floattable-less design中的 一个使用方式。

The Mystery Of The CSS Float Property_第2张图片
https://www.smashingmagazine.com/wp-content/uploads/2009/10/stopdesign-float.jpg

语法

CSS的float属性 可以接收4个值:left, right, none, inheritfloat的使用方式如下:

#sidebar { 
  float: left;
}

最常用的值是:leftrightnone是所有元素的默认值(或者说是初始值)。inherit可以用于几乎所有的CSS属性,但是在IE 7及以下 inherit不起作用。
float属性不需要其它任何的属性 共同作用于 同一个元素,就能正常运作;然而,float在特定环境下会更有效地运作。总的来说,一个浮起来的元素 应该又一个明确的宽度(除非该元素是replaced element,比如一个图片)。这保证了:浮动的行为和预料中的一致,有助于 在某些浏览器中 避免问题的出现。

#sidebar {
  float: left; width: 350px;
}
浮动元素的细节 - SPECIFICS ON FLOATED ELEMENTS

下列是浮动元素具体行为的列表:

  • 一个左浮动起来的盒子 会左移到:盒子的外边距的左最外沿(如果没有外边距,就是边框的左边沿) 接触到 包含该盒子的父元素的边沿 或者 另一个浮动元素的边沿。
  • 如果浮动元素的尺寸超过了 可利用的水平空间,浮动元素会移动到下一行。
  • non-positioned non-floated的块元素 默认 浮动元素不占据空间,因为浮动元素 相对于其它块元素 是脱离文档流的。
  • 浮动元素的外边距 不会和相邻元素的外边距 合并。
  • 根元素()不能浮起来。
  • 一个浮动起来的inline元素 会被转化为 块元素。

float的实际使用 - Float in Practice

float属性最常用的用途之一是:使图片浮动起来,并且使文本环绕包裹 浮动图片。如下图所示:

The Mystery Of The CSS Float Property_第3张图片
Screen Shot 2017-07-18 at 5.22.14 PM.png

上图中用于图片的CSS代码如下:

img {
  float: left;
  margin: 0 15px 5px 0;
  border: solid 1px #bbb;
}

为了达到上图效果 所需要的唯一的属性 是:float。上面代码中出现的其它的属性(margin, border) 是出于审美的原因。上图中的其它元素(含有文本的p元素) 不需要任何样式作用于它们。
像上文中提到的那样,浮起来的元素 相对于其它块元素 是脱离文档流的,并且其它块元素仍然在文档流中,其它块元素的行为 看起来 好像浮动元素并不在那儿一样。这可以用下图展示:

The Mystery Of The CSS Float Property_第4张图片
Screen Shot 2017-07-18 at 5.36.24 PM.png

在上面例子中,p元素是块元素,所以p元素会 忽略 浮动元素,跨越整个父容器的宽度(减去padding)。所有没有浮起来的块元素都有类似的行为。
p元素内的文本是inline元素,所以文本会围绕浮动元素。浮动元素之所以有外边距,是想让它偏离p元素:使得p元素忽略浮动元素在视觉上更清晰。

清除浮动 - Clearing Floats

使用浮动所带来的布局问题 可以通过 使用CSS的clear属性 来解决,这可以让你清除某个元素 左侧的或者右侧的 浮动元素。
让我们来看一个经常会出现的例子 - footer围绕在 一个2列布局 的右侧:

The Mystery Of The CSS Float Property_第5张图片
Screen Shot 2017-07-18 at 5.55.47 PM.png

如果你在IE6 IE7中查看的话:左侧列和右侧列都在对的位置,footer也被塞到下方。但是如果在Firefox,Opera,Safari,Chrome中,你会看到footer会跳到左侧列的旁边。之所以会这样,是因为左侧列的浮动。这是正确的行为,即使左侧列的浮动会造成困扰。为了解决这个问题,我们使用上述的clear属性,并应用于 footer:

#footer {
  clear: both;
}

结果如下所示:


The Mystery Of The CSS Float Property_第6张图片
Screen Shot 2017-07-18 at 6.06.59 PM.png

clear属性会清除浮起来的元素,所以应用clear: both到2列 不会让footer下移,因为footer不是浮起来的元素。
所以对非浮动元素 使用clear,去强制浮动元素占据它们本来的空间。

解决父元素的坍塌 - Fixing the Collapsed Parent

过度使用float的布局 最常见的症状之一 是:父元素坍塌。如下所示:

The Mystery Of The CSS Float Property_第7张图片
Screen Shot 2017-07-18 at 6.20.16 PM.png

注意:浮起来的图片的底部出现在了它的父元素的外边。父元素没有扩展到完全包含浮动图片。之所以会这样是由于:浮起来的元素 相对于其它块元素 脱离了文档流,所以所有的块元素在被渲染时,是假设浮动元素不在它原本的位置上的。这不是CSS的bug;这是和CSS说明一致的。所有的浏览器在这个示例中的渲染结果都是一样的。应该指出的是:在这个例子中,对父容器添加一个宽度 会阻止 IE浏览器发生父元素坍塌;所以这是在Firefox,Opera,Safari,Chrome中你不得不解决的问题。

解决方案1:使父元素浮起来 - SOLUTION 1: FLOAT THE CONTAINER

解决这个问题的最简便的方法是:使 包含它的父元素 浮起来:


The Mystery Of The CSS Float Property_第8张图片
Screen Shot 2017-07-18 at 6.37.59 PM.png

现在父容器扩展到 包含所有的子元素。但是不幸的是,这个方法只会在有限的几个环境下起作用,因为浮动父元素可能对你的布局产生难以预料的效果。

解决方案2:添加额外的标记 - SOLUTION 2: ADDING EXTRA MARKUP

这是个过期的方法,但是好在简单。只需要在父容器的下面添加一个额外的元素,并清除它。下面是 使用该方法后 html的样子:

![](http://upload-images.jianshu.io/upload_images/6174636-258e1164a9a2bcc3.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper.

应用于新添加元素的CSS:

.clearfix {
  clear: both;
}

你也可以通过使用
标签达到同样的效果。在任何情况下,这个方法都会让你得到想要的结果:父容器会扩展到 包围它所有的子元素。但是这个方法并不推荐,因为它添加了没有语义的代码 给你的标记语言。

解决方案3:after伪元素 - SOLUTION 3: THE :AFTER PSEUDO-ELEMENT

:after伪元素给HTML页面添加了一个元素。这个方法经常被用来解决清除浮动的问题。CSS代码如下:

.clearfix:after {
    content: ".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
}

如果包含浮动元素的父容器 没有扩展到 包围所有的子元素,这时就可以使用clearfix。但是这个方法不适用于IE7 及以下,所以需要 使用下面规则 来设置 一个额外的IE样式 :

.clearfix {
  display: inline-block;
}

.clearfix {
  zoom: 1;
}

根据你要处理的问题的类型,上述2中解决方式中一个 会解决 IE中的问题。需要指出的是:zoom属性是一个不标准的微软专有的属性,并且会导致你的CSS无效。
因为:after伪元素的解决方式在IE6 IE7中无效,并且需要额外的无效的IE样式,所以在代码方面显得有点臃肿。虽然这个方法不是最佳方法,但是可能是目前最好的方法。

解决方案4:overflow属性 - SOLUTION 4: THE OVERFLOW PROPERTY

截止到现在,最好的最容易的解决父元素坍塌问题的方法是:为父元素 添加overflow: hidden或者overflow: auto。这个方法很简洁,易于维护,在几乎所有的浏览器中都起作用,而且不会添加额外的标记。
你会注意到:我所说的,几乎所有的浏览器。这是因为他不是用于IE6。但是在很多情况下,父容器都会有一个设置好的宽度,这恰好解决了IE6中的问题。如果父容器没有宽度,你可以使用下面代码 添加一个IE6的样式:

// This fix is for IE6 only
.clearfix {
  height: 1%;
  overflow: visible;
}

在IE6中,height会被错误地认为是min-height,所以 这会强制父容器包围它的子元素。overflow接着被设置回visible,确保了内容没有被隐藏或卷起来。
在任何浏览器中 使用overflow方法的唯一缺点是:父元素会有滚动条 或者 隐藏的内容。如果父元素中的任意的子元素 使用了负的外边距 或者 绝对定位,并且它们超过了父元素的边框,它们会被遮挡。所以,这个方法应该被谨慎使用。应该指出的是:如果父元素不得不设置一个具体的heightmin-height,那么你绝对不要使用overflow方法。
所以,实际上没有简单的,兼容所有浏览器的 解决父元素坍塌问题的 方法。但是几乎任何的浮动清除问题 通过上述方法中某一个 都可以被解决。

IE中float相关的bug - Float-Related Bugs in Internet Explorer

这些年来,有许多关于CSSfloat的bugs讨论的文章被发布到网上。所有这些文章 无疑都是 处理IE特定的问题的。下面,你会发现一些文章的链接列表,这些文章深入讨论了float相关的问题:

  • The Internet Explorer Guillotine Bug
  • The IE5/6 Doubled Float-Margin Bug
  • IE7 Bottom Margin Bug
  • The IE Escaping Floats Bug
  • The IE6 Peekaboo Bug
  • The IE6 “Ghost Text” Bug
  • The IE6 Expanding Box Problem
  • The IE6 3-pixel Gap

使用JavaScript更改float属性 - Changing the Float Property with JavaScript

在JavaScript中更改一个CSS值,你需要访问style对象。使用对象时需要做个转换:把想要的CSS属性转换为驼峰的样子。例如,CSS属性magin-left在JavaScript中变为了marginLeft; background-color属性在JS中变为了backgroundColor等等。但是使用float属性时,有点不同,因为float已经是JavaScript中保留的关键字了。所以,接下来的代码是不正确的:

myDiv.style.float = "left";

作为代替,你应该使用下面中的一种:

// For Internet Explorer
myDiv.style.styleFloat = "left";

// For all other browsers
myDiv.style.cssFloat = "left";

float的实际应用 - Practical Uses for Float

float可以被用来解决在CSS布局中的许多设计挑战。一些例子在这儿被讨论了。

2列,固定宽度的布局

这儿 列出了 创建一个简单的,兼容多浏览器的 2列水平居中布局 的8步指导。float属性对于该布局的融洽是必需的。

布局包括了一个header,一个水平导航条,一个主内容列,一个侧边栏,以及一个footer。布局在浏览器窗口中是水平居中的。这是一个相当基本的布局,只要你知道如何处理不可避免的IE bugs,使用CSS创建该布局一点都不困难。

Simple 2 column CSS layout

The Mystery Of The CSS Float Property_第9张图片
https://www.smashingmagazine.com/wp-content/uploads/2009/10/2-column-layout.jpg

3列,等高布局

pixy.cz 展示了兼容多浏览器的3列布局,同样使用的是float:

没有table,没有绝对定位(没有任何定位),没有hacks,所有列都保持同样的高度。左侧栏和右侧栏有个固定宽度(150px),中间栏自适应宽度。

3-Column Layout with CSS

The Mystery Of The CSS Float Property_第10张图片
https://www.smashingmagazine.com/wp-content/uploads/2009/10/3-column-layout.jpg

带标题的浮动图片

类似于 我们之前在'Float in Practice'章节 所讨论的内容,Max Design 描述了怎样使 带标题的图片浮起来,并允许图片周围的文本自然地围绕着它。
Floating an Image and Caption

The Mystery Of The CSS Float Property_第11张图片
https://www.smashingmagazine.com/wp-content/uploads/2009/10/floated-image.jpg

使用无序列表创建水平导航

float属性 在编码基于sprite图的水平导航条时 是一个关键因素。Line25描述了 怎样创建一个很棒的menu,这里的li元素包含了导航按钮,并且li元素是左浮动的:
How to Create a CSS Menu Using Image Sprites

The Mystery Of The CSS Float Property_第12张图片
https://www.smashingmagazine.com/wp-content/uploads/2009/10/menu.jpg

为了展示在这个例子中 float属性的重要性,这儿有一个 在使用firebug移除 float: left后 的截屏:
The Mystery Of The CSS Float Property_第13张图片
https://www.smashingmagazine.com/wp-content/uploads/2009/10/menu-nofloat.jpg

基于栅格的图片陈列室

float属性的一个简单使用 是:左浮动 包含在无序列表中一系列图片,这会得到 和‘基于table的布局’相同的 布局。

The Mystery Of The CSS Float Property_第14张图片
https://www.smashingmagazine.com/wp-content/uploads/2009/10/foremost.jpg

上图中的这些图片 是以无序列表的形式被展示的,该无序列表的所有li元素的float属性都被设置为float: left。比起基于table的栅格布局,这种方式的布局更好,因为陈列室中的图片数量改变时,布局不会受到影响。

The Mystery Of The CSS Float Property_第15张图片
https://www.smashingmagazine.com/wp-content/uploads/2009/10/istockphoto.jpg

上图中的 iStockphoto’s search results page 是个类似结构的图片栅格,但是这次的所有图片都被包含在左浮动的
元素中,而不是li元素中。

field和button对齐

各种浏览器中form元素的默认样式处理起来很头疼。很多时候,在 单field的form中(比如一个搜索form) 把input元素放在提交按钮的旁边是必需的。
在所有的浏览器中,结果都是相同的:提交按钮看起来比input field要高。更改margin和padding不会更改显示结果。最简单的方式是:使input field左浮动,并添加一个微小的右外边距。

总结 - Conclusion

就像在一开始提到的那样,不使用CSS的float属性时,table-less的布局 在最坏的情况下 会变得不可能,在最好的情况下 会变得不可维护。float在CSS布局中仍然是重要的,即使当CSS3开始获得重要位置 - 即便 已经有一些关于‘不使用float进行布局’的讨论。希望这里的讨论已经简化了 一些有关float的奥秘,并对开发者所面临的许多问题 提供了一些实际的解决方法。

本文翻译自: https://www.smashingmagazine.com/2009/10/the-mystery-of-css-float-property/
转载请注明出处

你可能感兴趣的:(The Mystery Of The CSS Float Property)