css 浮动[译]

原文链接

什么是 Float

Float 是 CSS 用于定位的属性。为了彻底明白它意图和来源,可以参考印刷设计。在印刷布局中,通常图片会有被包裹在文本里的需求。这通常称之为“图文混排(字体环绕)”,如下图:

在页面布局程序设定中,页面的框子可以控制文本是否遵循字体环绕。忽略字体环绕将使得单词在图片上方流过,就像它甚至不存在一样。这是图片是否是流动于页面一部分的区别。网页设计非常相似。

在网页设计中,页面元素依托 css 的 float 属性,使得图片被排版在文字里。浮动的元素依旧是网页流式的一部分。和绝对定位是有区别的。绝对定位的元素脱离页面流式布局,如同排版布局中告诉程序页面去忽略文字。绝对定位的元素不会影响其他元素,无论是否紧挨着接触。

浮动代码示例:

1
2
3
#sidebar {
float: right;
}

通常 float 有四个合法值,left、right 更别是元素方向定位。none(默认值)定义元素不适用 float,inherit 跟随父元素的浮动值。

Float 使用场景?

除了之前说的字体环绕图片,float 通常用于 web 页面的布局。

float 在小范围的布局也非常使用。拿页面一个小区域举例:如果我们需要浮动图像,当图片尺寸改变时该区域盒子内的文字将重新渲染自适应。

当然同样的效果 relative 定位和 absolute 定位也可以实现,但是该区域内的文本不会重新渲染并自适应。

清除浮动

float 的类似元素是 clear。设置了 clear 的元素不会随意移动到浮动元素周边,而是会排在浮动元素之下,图例将更好的说明:

上例,侧边栏定义 right float 并且比内容局域短。页脚则会移动到浮动元素后的空缺位置。为了修复这个问题,定义 clear 使得页脚待到内容和侧边栏之下这个位置。

1
2
3
#footer {
clear: both;
}

clear 也有四个值。both 是最为常用,可以清除任意方向的浮动。left,right 用于清除指定方向的浮动。none 默认值,无清除效果。inherit 在 IE 中支持不友好。

高度塌陷

使用 float 最容易疑惑的问题是怎么让包裹浮动元素的父元素有效。如果父元素不含其它元素但只有浮动元素,其高度将一定塌陷。如果没有明显的背景色等参照很难发现这个问题。

塌陷现象有点反人类,如下例子可能更为糟糕:

block 元素如果已经自适应 float 元素,我们将遇到两个段落之间不自然的空隙,没有什么好方法修复。遇到这样的问题,我们的设计师将崩溃。

塌陷现象在浏览器布局问题中是极其常见的,需要在容器中的浮动元素之后和容器闭合之前来解决处理此类问题。

清除浮动的技巧

如果你处理这类问题当提前知道随后元素是什么,你可以使用 clear:both 来解决问题。这样不需要特殊修改和额外的标签处理。当然万事不会那样顺利,我们需要更多的清除浮动的工具类。

使用空的 Div 清空元素

一个空的 div:

1
<div style="clear: both;"></div>

当然你可以使用其他标签如
,但是 div 是最为常见的,浏览器也没有针对它有特殊样式,指定功能,同时我们也不会对其做全局 css 处理。这个方法会被语义“信徒”认为是可笑的,在页面中无任何含义。虽然不能说他们错,但是我们这样做没有对页面造成影响。

使用 Overflow

在父元素上定义 overflow 溢出属性。如果将其设置为 auto、hidden,包含浮动的父元素将立竿见影地清除浮动。堪称优雅的方式,不需要添加额外标签。而然如果你发现如果在原有页面基础上又添加一个 div 来运用此方法,将等同于非语义的 div 方式,并且效果不会很好。记住 overflow 不是专门用来清除浮动的,当心不要隐藏内容或者触发非预期的滚动条

伪类

添加一个 css 伪元素(pseudo selector),如::after。相比添加 overflow 在父元素上,你可以添加“.clearfix”来使用这个方法。

1
2
3
4
5
6
7
.clearfix:after {
content: '.';
visibility: hidden;
display: block;
height: 0;
clear: both;
}

这将用一个很小的真实存在的内容区域放在需要解决浮动问题的父元素中。当然这不是全部代码,如果你想兼容一些其他版本的浏览器。

场景分析

不同场景需要不同的清除浮动的方法,如下(处理不同类型的网格块):

为了更好的展示相同的块,我们想要每个颜色相同则重启一行。对于这个需求,当颜色改变时,我们可以使用 overflow、伪类方式。或者在每个颜色相同的组下使用 div 方式,当然不管添加三个充当父类的 div 或者额外添加的三个 div,你自己决定那个更好?

float 问题(浏览器兼容)

float 总是会因为没考虑周全而显得解决地很鸡肋。这种脆弱性通常来自 ie6 和浮动相关的 bug。全世界都在放弃 ie6 的支持,可能你不关心,但对于关心的人来说会出现很多问题。

顶掉其他元素

发生在当一个元素在一个比他更窄的浮动元素内部(图片居多)。绝大多数浏览器将渲染这个图片到浮动元素外,但不会差得很多。ie 将扩展浮动元素包裹其中的图片,这就会影响布局。会把其他元素往下挤掉

解决这个问题:你可以使用overflow:hidden来解除多余的部分。

边距扩大

使用 ie6 另一件事是,如果在 float 同一方向上使用 margin,将使得双倍的 margin。
解决这个问题:设置display:inline在浮动元素上,它依旧保持 block 元素特性。

3px 坑

当文字旁是浮动元素,其间的 3px 将被神奇的抹去。
解决这个问题:浮动元素上额外设置长宽。

底部 margin bug

ie7 上,父浮动元素内包含子浮动元素,子元素的 bottom margin 将失效。
解决这个问题:更为换 padding。

更多

如果想实现图文混排,float 外没有第二选择。当然你可以查看rather clever technique,将文本包裹在非规则的形状内。对于页面局部当然还有其他方案,可查看Faux Absolute Positioning,关于 css3 实现更好的布局方式
Template Layout Module

作者的视频截图

【长按关注】看看↓↓↓?
Eminoda wechat
【前端雨爸】分享前端技术实践,持续输出前端技术文章
欢迎留言,评论交流,一起讨论前端问题
📢 因为是开源博客,为避免 Gitalk授权 带来的 安全风险,也可访问