数年前,当开发者首次开始不使用table
来布局网页时,CSS中的一个property
突然间显得格外重要,该属性就是float
。float
属性变得如此常用的原因在于:默认情况下,在一个以列布局的方式中 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
元素 相对于其它的元素 脱离文档流。这使得 自然流动的内容 会包裹浮起来的元素。这个概念类似于:你每天在印刷媒体上所看到的内容(图片或其它图像元素 对齐于左边或者右边,其它的内容 通常是一些文本 会环绕在 左对齐或右对齐的 图片元素 周围)。如下图所示:
上图展示了:3个图片 在它们各自的列中 都是左对齐的,并且都被文字环绕着。这是CSS布局中 float
属性的基本观念,并且展示了float
在table-less design
中的 一个使用方式。
语法
CSS的float
属性 可以接收4个值:left
, right
, none
, inherit
。float
的使用方式如下:
#sidebar {
float: left;
}
最常用的值是:left
和right
。none
是所有元素的默认值(或者说是初始值)。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
属性最常用的用途之一是:使图片浮动起来,并且使文本环绕包裹 浮动图片。如下图所示:
上图中用于图片的CSS代码如下:
img {
float: left;
margin: 0 15px 5px 0;
border: solid 1px #bbb;
}
为了达到上图效果 所需要的唯一的属性 是:float
。上面代码中出现的其它的属性(margin, border) 是出于审美的原因。上图中的其它元素(含有文本的p元素) 不需要任何样式作用于它们。
像上文中提到的那样,浮起来的元素 相对于其它块元素 是脱离文档流的,并且其它块元素仍然在文档流中,其它块元素的行为 看起来 好像浮动元素并不在那儿一样。这可以用下图展示:
在上面例子中,p元素是块元素,所以p元素会 忽略 浮动元素,跨越整个父容器的宽度(减去padding)。所有没有浮起来的块元素都有类似的行为。
p元素内的文本是inline
元素,所以文本会围绕浮动元素。浮动元素之所以有外边距,是想让它偏离p元素:使得p元素忽略浮动元素
在视觉上更清晰。
清除浮动 - Clearing Floats
使用浮动所带来的布局问题 可以通过 使用CSS的clear
属性 来解决,这可以让你清除某个元素 左侧的或者右侧的 浮动元素。
让我们来看一个经常会出现的例子 - footer
围绕在 一个2列布局 的右侧:
如果你在IE6 IE7中查看的话:左侧列和右侧列都在对的位置,footer
也被塞到下方。但是如果在Firefox,Opera,Safari,Chrome中,你会看到footer
会跳到左侧列的旁边。之所以会这样,是因为左侧列的浮动。这是正确的行为,即使左侧列的浮动会造成困扰。为了解决这个问题,我们使用上述的clear
属性,并应用于 footer
:
#footer {
clear: both;
}
结果如下所示:
clear
属性会清除浮起来的元素,所以应用clear: both
到2列 不会让footer
下移,因为footer
不是浮起来的元素。
所以对非浮动元素 使用clear
,去强制浮动元素占据它们本来的空间。
解决父元素的坍塌 - Fixing the Collapsed Parent
过度使用float
的布局 最常见的症状之一 是:父元素坍塌。如下所示:
注意:浮起来的图片的底部出现在了它的父元素的外边。父元素没有扩展到完全包含浮动图片。之所以会这样是由于:浮起来的元素 相对于其它块元素 脱离了文档流,所以所有的块元素在被渲染时,是假设浮动元素不在它原本的位置上的。这不是CSS的bug;这是和CSS说明一致的。所有的浏览器在这个示例中的渲染结果都是一样的。应该指出的是:在这个例子中,对父容器添加一个宽度 会阻止 IE浏览器发生父元素坍塌;所以这是在Firefox,Opera,Safari,Chrome中你不得不解决的问题。
解决方案1:使父元素浮起来 - SOLUTION 1: FLOAT THE CONTAINER
解决这个问题的最简便的方法是:使 包含它的父元素 浮起来:
现在父容器扩展到 包含所有的子元素。但是不幸的是,这个方法只会在有限的几个环境下起作用,因为浮动父元素可能对你的布局产生难以预料的效果。
解决方案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
方法的唯一缺点是:父元素会有滚动条 或者 隐藏的内容。如果父元素中的任意的子元素 使用了负的外边距 或者 绝对定位,并且它们超过了父元素的边框,它们会被遮挡。所以,这个方法应该被谨慎使用。应该指出的是:如果父元素不得不设置一个具体的height
或min-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
3列,等高布局
pixy.cz 展示了兼容多浏览器的3列布局,同样使用的是float
:
没有
table
,没有绝对定位
(没有任何定位),没有hacks
,所有列都保持同样的高度。左侧栏和右侧栏有个固定宽度(150px),中间栏自适应宽度。
3-Column Layout with CSS
带标题的浮动图片
类似于 我们之前在'Float in Practice'章节 所讨论的内容,Max Design 描述了怎样使 带标题的图片浮起来,并允许图片周围的文本自然地围绕着它。
Floating an Image and Caption
使用无序列表创建水平导航
float
属性 在编码基于sprite图的水平导航条时 是一个关键因素。Line25描述了 怎样创建一个很棒的menu,这里的li元素包含了导航按钮,并且li元素是左浮动的:
How to Create a CSS Menu Using Image Sprites
为了展示在这个例子中
float
属性的重要性,这儿有一个 在使用firebug移除
float: left
后 的截屏:
基于栅格的图片陈列室
对float
属性的一个简单使用 是:左浮动 包含在无序列表中一系列图片,这会得到 和‘基于table
的布局’相同的 布局。
上图中的这些图片 是以无序列表的形式被展示的,该无序列表的所有li元素的float
属性都被设置为float: left
。比起基于table
的栅格布局,这种方式的布局更好,因为陈列室中的图片数量改变时,布局不会受到影响。
上图中的 iStockphoto’s search results page 是个类似结构的图片栅格,但是这次的所有图片都被包含在左浮动的
把 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/
转载请注明出处