学习 CSS 时遇到的障碍之一(以及 “啊哈”时刻)就是关于清除浮动的问题。如果您不知道我在说什么,请查看经典的 浮动详解。
我特别想谈谈“塌陷”的问题,即包含浮动元素的元素在计算其高度时不考虑这些浮动元素。例如,仅包含浮动元素的父元素将具有零高度。这对 CSS 新手来说令人惊讶和困惑,并且似乎违反直觉。
解决它通常很简单。在父元素上使用任何 overflow 值的 hidden 或 auto 都会“修复”它。 clearfix 也很受欢迎。
但是,这些“修复”导致人们认为这种行为从一开始就是“错误的”1。令人困惑?当然。应该有更好的控制选项吗?绝对的。错误的?不完全是。如果所有容器都扩展以包含其浮动后代,我们会抱怨得更厉害,并且这个问题可能更难解决。
经典示例
我们将使用 Eric Meyer 七年前提供的这个示例。
<p>
...text...
<img src="sunset.jpg" class="callout" />
...text...
</p>
<p>
...text...
</p>
该调用类,例如,会将图像浮动到左侧并应用一些边距。这就是我们现在得到的结果
这正是我们想要的,正确的文本重排。为了实现这一点,上一段需要“塌陷”,并让浮动图像从其底部突出。
如果上一段自动扩展以包含浮动,我们将得到以下结果
正如 Eric 所说
这是设计师永远不会接受的。
我同意。假设找不到任何花哨的解决方法来解决它,这可能是一个更糟糕的问题。
是否应该有更好的解决方案?
是的,可能吧。我见过有人建议
overflow: contain;
这可能有效,但如果您想隐藏水平溢出怎么办?我们已经有了 overflow: hidden,它已经包含了浮动,可以工作,但这在语义上有点令人困惑。可以有一个全新的属性,例如
contain: floats | collapse | inherit;
但我不确定,他们不能一直添加新属性,所以这需要认真审查。
1 我还想在这里补充一点,我经常听到人们说“浮动将元素从文档流中移除”,这不是真的。浮动元素仍然会影响内联元素(这有点关键),以及其他浮动块级元素。如果浮动元素被“从文档流中移除”,它们将不会影响任何内容(如绝对定位元素)。
我们是否只是滥用 float 属性来做它本意之外的事情?也许应该有一个 layout-flow 属性,它可以自动清除自身。clearfix 类很有用,但不是最优雅的解决方案。
似乎有很多 HTML 和 CSS 以非预期的方式被我们滥用,因为这是我们完成所需工作的唯一好方法。
是的,这正是我所认为的。浮动似乎最初并非用于布局,因为随之而来许多问题——清除、等高、向下偏移等,因此做了很多“修复”。在许多情况下,表格似乎更容易,但它们也不适合布局(出于充分的理由)。
看起来有一些建议将更多基于布局的 CSS 集成进来: http://www.w3.org/TR/2009/WD-css3-layout-20090402/。它看起来并不完美,但可能比我们现在拥有的更好。但谁知道这何时会成为标准……
不,我们没有滥用 float。不可能滥用表示层来描述表示。
今天听到的最佳想法!
不妨将此想法提交给 w3。
“解决它通常很简单。在父元素上使用任何 overflow 值的 hidden 或 scroll 都会“修复”它。”
Overflow:auto 是这里正确的解决方案。
是的,我本来想在那里说“auto”。但实际上,在使用此功能的情况下,我使用“hidden”的频率高于使用 auto。这取决于上下文,但我发现 hidden 在 IE6 时代更可靠,当您未设置固定高度时,它只是防止内容水平突出并破坏布局。
很好的想法!我一直希望有一个快速 HTML 非终止标签来执行清除。例如 “clear” 标签,然后 “rtclear” 和 “ltclear”……等等。但是,如上所述,将其放在样式表中可能是一个更灵活的解决方案。
我使用了一种从 Ed Elliot 获取的方法,它对我的情况总是有效。
只需将 container 类添加到您想要包含其所有内容的任何 div 中,它就能正常工作……这意味着需要在 HTML 中添加一个类,但对我来说,这比添加清除 <br /> 或其他内容更具语义。
但是,与仅使用 overflow: auto; 相比,这要不那么具有语义性;
这通常是我喜欢使用的方法,但 :after 伪类在大多数旧版浏览器中不起作用。
这不是 “clearfix” 技术的第一部分吗?
是的,这只是 clearfix
在这些“面向新手的 CSS”类型的博文(如今有很多)中,我经常这么说——
1. 对于那些在实际技巧发明者/创新者首次撰写这些内容时没有学习这些内容的“年轻一代”网页设计师来说,人们撰写这些主题的文章真是太棒了。
2. 也就是说,让我们公平地给予应有的荣誉……所谓的“clearfix”方法首先由 Position is Everything 的优秀团队广泛记录和推广——http://www.positioniseverything.net/easyclearing.html
继续学习——这些都是很棒的东西。
在 CSS 修复方面,我会更进一步。我经常遇到的一个问题是侧栏中的一个项目侵入到充满文本的中心栏中,并且设计师期望文本环绕该项目。(想象一下上面的示例,但图像向左突出。)我从习惯于进行打印的设计师那里经常听到这一点。(我也从桌面出版开始。)
在页面布局程序中,您可以获取一个元素(例如图像)并对其应用文本环绕。这意味着无论您将元素放在页面上的哪个位置,如果它与任何文本框相交,文本都会避开它并环绕它。设计师期望 HTML 页面具有这种行为,我必须解释它并非如此。
要使文本环绕 HTML 中的元素,该元素必须位于文本内部。对于上面的示例,图像标签实际上位于“egestas semper”这两个词之间。为了使图像左对齐在文本左侧的列中,它必须具有负左外边距才能将其拉过来。这意味着它有风险与左侧列中的内容重叠。
我认为也许需要一个 float:all 或 text-wrap:left 来处理这种情况。
哇,Chris,
您在不经意间提到了它,但在父元素上仅使用 overflow:hidden(或 auto)作为浮动的单行工作解决方案真是太棒了。
甚至“简单”的浮动(clearfix/after + zoom:1 IE)也比这差。
我(现在)无法相信这在所有“可接受的”浏览器(IE6+、Mozilla FF2+、WebKit)中都能正常工作。
谢谢!
它看起来不错,但问题是 overflow: hidden 和 overflow: auto 除了修复浮动问题之外,还有非常具体的其他功能。假设你在一个浮动 div 内部有一个图像,并且你**有意**地希望它超出 div 的宽度(通常不是一个好主意,但请继续)。overflow: auto 会触发一个水平滚动条。overflow: hidden 会将其裁剪掉。所以,这两个选项都不行。但你仍然需要清除浮动,所以你只能添加一个额外的清除元素或 clearfix。还有其他情况……总的来说,overflow 的方法并不是理想的。
也可以将父元素也设置为浮动来达到相同的效果,但不会导致滚动条或裁剪图像。谷歌搜索:“css shrink wrapping”
当然,这种方法也不总是理想的。
那么,一切都取决于遇到的具体情况。
当我的内容超出包含 div 时,我使用额外的清除元素。或者,更好的方法是,当包含 div 是主要 960px 宽的居中容器,并且我需要在窗口大小调整时显示水平滚动条时。如果使用 overflow: hidden,则滚动条不会显示。
否则,我使用 overflow: hidden。
但绝不使用 overflow: auto,因为它可能导致添加额外内容时出现不需要的垂直滚动条。
“我经常听到人们说“浮动元素会脱离文档流”,这并不正确。”
我也经常听到这句话,并且一直接受这个说法直到现在。现在我不确定该怎么想了。即使浮动元素不会脱离文档流……它们仍然会影响文档的流向。也许与其说浮动元素会脱离文档流,不如说它们会将其从自然位置偏移并影响其后面元素的位置??”
我认为混淆源于名称相似的“文档流”和“文本流”之间的差异。请参阅规范的此部分以获取更多信息
http://www.w3.org/TR/CSS2/visuren.html#comparison
终于!一个非常好的解释!
如果你需要文本“折叠”,为什么不直接清除呢?
例如:img { float: left; clear: right; }
向 CSS 添加新规则或添加新元素的问题显然是不可接受的。如果我们这样做,所有当前的浏览器都将变得过时,我们必须添加当前的修复以及“新”的修复,直到 2018 年没有人再使用 IE9 为止。如果 W3C 在 2010 年内应用这些规则,这可能不会发生。我认为我们不会等待支持一个新规则和一个旧的 hack,直到我们中有一半的人要退休成为开发者。
“但是如果想要隐藏水平溢出怎么办?”
overflow-x 和 overflow-y 是完美的用例。
如果这个问题偏离主题,我表示歉意。
我有一个关于浮动元素与列表元素(ul 或 ol)的问题。
如果列表的 list-style-position 为“outside”,则项目符号不会受浮动元素的影响,并且会被放置在其后面。是否有任何解决方法?因为使用“inside”位置不如“outside”整洁。
好文章,这可能对我的许多朋友有所帮助,因为他们总是犯清除浮动的错误……
我想知道为什么这些帖子留下了不需要的间隙。很好的解决方案。
我认为 w3c 与你的观点不一致。
http://www.w3.org/TR/CSS2/visuren.html#floats
指出
“由于浮动元素不在流中,因此在浮动框前后创建的非定位块级框会垂直流动,就好像浮动元素不存在一样。但是,紧邻浮动元素创建的行框会被缩短,以便为浮动元素的边距框腾出空间。”
所以你在这里展示的是伪 CSS 吗?
我认为 Chris 并没有错,但我认为需要进一步解释。正如其他人指出的那样,所指的“流”不是“文档流”(即使我本人有时也错误地这样说过),而是指块级元素的流向。内联元素会环绕浮动元素流动。甚至SitePoint 的参考也没有真正说明他们是否指的是“文档流”,只使用了“流”这个词。
所以,你可以说浮动元素被移出了“相对”流,虽然这个说法不是很好。
我真的认为这里被说得比实际情况复杂了。浮动就是浮动,框/元素等等。浮动应该很少使用。
有人给出了在创建模板中使用浮动的简单易用的想法,并且很快就被推广开来。我真的找不到浮动的正常用途。我认为这只是某些人的习惯和一种趋势,很快就会消失。display 和 position 就足够了。只需要正确应用即可。
如果你从不使用浮动,并且只使用定位,除非你是一位 CSS 超级专家,否则你将创建不可维护的网站布局。我怀疑即使你是超级专家,你仍然难以创建可维护的布局。
如何使用“块流”和“内联流”来区分呢?
所以浮动,定位中的一个例外,是你的 CSS 布局的基础?我相信你只是用它的邪恶孪生兄弟替换了一种糟糕的样式(基于表格的样式) :)
这就是表格支持者用来反对 CSS div 布局的论点。
浮动优于表格布局的一个重要原因是,表格布局没有语义,并且会混淆搜索引擎和文本阅读器浏览器等。使用浮动,你的 HTML 代码可以被正确地构建。任何试图争辩说浮动是表格的邪恶孪生兄弟的人都不理解语义和编码标准,我猜他们可能只是一个业余的设计师/开发者。
@ 挪威的 Richard:你是一个业余爱好者的两个主要原因
– 你正在使用 XHTML,而这对于 IE(最常用的浏览器,无论你是否喜欢)来说是一团乱麻
– 你的http://www.richardharris.no/页面 HTML 使用浮动并没有更具语义:在开始放置任何语义内容之前,你使用了一个容器 div,一个包装器 div。
我看到你的主页 CSS 中有表格样式代码,但它不再使用了,所以我相信你只是从表格样式切换了过来。在发表声明之前,你应该明确学习更多 CSS :)
Ulyses:标签汤显然不是你认为的意思。这是过去两年中最流行的转移话题,所以是可以理解的,但它仍然是一个转移话题。
好吧,看起来你在这里把我塑造成一个坏人。所以让我们一步一步来。我认为说出这篇文章的真相并不好。
标题,是一个错误。我在这里看到有人需要回到基础,并了解即使是一个内联框也可以是一个容器,而对于内联框的自动清除是……愚蠢的吗?
然后,作者 Chris Coyier 说
“我特别想讨论“折叠”的问题,也就是包含浮动项目的元素如何在计算其高度时不考虑这些浮动项目。”
然后
“我还想在这里补充一点,我经常听到人们说“浮动元素会脱离文档流”,这并不正确。”
这完全是相互矛盾的。如果元素没有脱离流,那就不会发生这种情况。
这里说的另一个半真半假的是下一个
“例如,仅包含浮动项目的父元素将具有零高度。”
如果父元素也浮动,则**不正确**。
然后,他继续说
“解决它通常很简单。在父元素上使用任何 overflow 值(hidden 或 auto)都会“修复”它。clearfix 也很流行。”
他没有给予发现它们的人以应有的赞誉,正如这篇文章中更好地指出的那样……2005 年:http://www.sitepoint.com/blogs/2005/02/26/simple-clearing-of-floats。
此外,他没有提到一个非常好的解决方法(不是 hack)来清除浮动,那就是“几乎所有都浮动”(FnE)。
最后,关于你所谓的转移话题,标签汤正是我的想法,但为了让你学习。需要更多细节,我会提供给你真相。即使 IE 的用户代理在您编写 XHTML 时对您有所帮助,您看到的也不是 XHTML,而是一个被友好地视为 HTML 的标签汤,仅仅因为 IE 不支持作为 application/xhtml+xml 提供的服务文档。我也通过http://www.sitepoint.com/forums/showthread.php?t=393445(艰难的途径)了解了这一点。
@Luis:除非它在浮动,否则它不可维护?这不是一个好概念。
Ulyses,你能向我展示一种实现可维护 CSS 布局的文档化方法,该方法不使用浮动吗?我说的不是那些演示布局*无需*浮动*可能性*的一次性教程。我要求你在实践中向我展示,这种概念在哪里取得了成功。
我并不是说布局应该充斥着浮动。我的意思是,一些浮动加上良好的定位组合,以及仔细注意其他跨浏览器原则,将是最可行的解决方案。如果你能提供一些现实世界的证据证明布局*不需要*任何浮动,那就尽管去做吧,但我怀疑你能做到。
给我一个项目,我会在没有浮动的情况下完成它。而且付费项目会更好:)
我开发了许多模板,用于打印或屏幕,这些模板不涉及使用浮动。我不明白你为什么这么需要它们。当您定义列时,您不需要浮动:)
仅仅因为 w3cschools 教你使用浮动来定义布局中的列,这并不意味着它是法律。
@挪威的理查德:你说什么?当您插入包装器 div 用于浮动时,这会使您的 HTML 语义化吗?您应该再检查一下:)
即使您帮助了您的 HTML,您的 CSS 也根本不是应该的样子。一个优秀的开发者会努力做出好的 HTML 和好的 CSS。也许你不是其中之一。
Ulyses,我说的不是什么可能。事实上,我认为创建没有浮动的布局会更容易。这不是这里的问题。
问题在于,在现实世界的情况下,无浮动布局是否实用且可维护。
好吧,我尽量不使用浮动,最重要的是不要用于主要布局。这是一个观点,在实践中它是可靠的。
到目前为止对我来说是这样。哪天不行了,你会看到我在这里发布完整细节。
当你不得不从浮动切换时(就像那些需要从表格切换的人一样),你才是那个陷入困境的人。
浮动只是模拟了一种布局,可以通过其他更自然、更“CSS 语义”的方式实现的布局。
这只是基本的 CSS,用正确的习惯替换你的浮动习惯。IMO :)
这个人只是一个喷子。别再理他了。
请您能解释一下喷子吗?:)
我感觉自己疯了,但我真的希望浮动对象能够扩展其父容器的尺寸。我想我考虑得“过于现实”。就像把盒子放在垃圾袋里。你永远不会期望袋子穿过垃圾袋壁的物理物质。如果有一个 CSS 属性可以分配给父元素以打开/关闭任何浮动子元素是否扩展它,那就很酷了。
问题不在于“float”属性本身。
在您的示例上下文中——调用图像,就像在打印设计中一样——它工作得很好。事实上,这是它的预期用途。
当您在超出此使用上下文中使用“float”时,您就会开始遇到问题。例如,当您开始使用“float”创建列时。
这只是违反直觉,因为“float”对于除了在段落或浏览器引擎知道如何“环绕”元素的其他内容流中间浮动内容之外的任何其他内容,都是一个失效的概念模型。
更不用说浮动清除行为在浏览器之间完全不一致,而且你不能责怪它们。每个浏览器都会实现不同的行为,其中规范没有处理当不同的浮动元素交互时应该发生什么。找到“正确的方法”是不可能的,因为,同样,概念模型是失效的。
这就是它成为 CSS 中主要障碍的原因。
优秀的帖子。我同意你对浮动的看法。我相信 WC3 设想了一种用 css 替代方案替换图像中的 align=”right|left” 的方法。我认为他们没有充分考虑,但由于我不是讨论的一部分,我无法想象它有多困难,我也不会评判他们。我只是期待着这些问题终将过去的一天。 :)
我同意。Float 是一个错误的工具来……定位。这就是为什么有像 display 和 position 这样的 css 属性。
解释得很好。这是很多新手在一段时间内无法理解的一些基本内容。
我认为这里唯一的问题是清除方法被标记为“修复”,就像你说的那样,这表明某些东西坏了。
没有东西坏了,不需要修复,只需要清除。
在抛弃太多“table”之后过度使用“float”也是 CSS 的一大罪过。
浮动滥用不是良好的 CSS 实践。
IMO。
这就像语义 HTML 的斗争。语义 CSS 怎么样?
我同意,这很不直观!
不错的文章,Chris,
我发现使容器扩展到其浮动内容高度的最佳方法是也使容器浮动。
这就是我的等高列方法的工作原理。
对于那些反对使用浮动进行布局的人,您会推荐什么替代方案?display 和 position 只能让你走那么远。如果你……
实际上,我越努力思考浮动是唯一解决方案的情况(并对选项进行一些快速研究,以免显得像个傻瓜),我越意识到不使用浮动但保持灵活性是一些值得真正深入研究的东西。这是一个真正的思考点。
另外,那个 CSS 布局模块看起来非常棒。
完美!我们今天在课堂上刚刚讲过这个,这将非常有助于我完成我的作业。感谢您,Chris!这里有一位忠实的粉丝。
是的,我将在这一点上与 cyborg_572 站在一起。
或者你可以尝试像blueprint或
960
嗯……也许我生活在一个不同的 CSS 世界,但我对浮动项目未清除的经典解决方案是使用 clear:both;
IE:这是浮动的!清除两者会创建您可能期望的分隔
糟糕。
这是浮动的!
清除两者会创建您可能期望的分隔
当需要这样做时,我发现自己会使用浮动……拥有某种像云一样的内容,只是坐在那里并让周围的事情发生。没有高度元素是有道理的(除非另有说明),因为您告诉该部分它本质上是无形的,允许周围发生事情。
我发现使用绝对/相对定位的混合以及使用浮动填充边缘是我自己的“正确”做事方式,而不是基于纯浮动或纯定位的布局。两者都不能真正正确,因为 CSS 仍在网站的设计/布局世界中找到自己的位置。我认为在当前状态下,采用代码的整体视图是最佳选择。
也就是说,能够在不需要指定像“float”这样模棱两可的东西或像完全定位元素那样过多的情况下创建列和侧边栏会很好。进入:CSS3。我越深入研究它,我就越希望大多数用户升级他们的浏览器,因为它解决了困扰 CSS 的许多布局问题。
我想说的是,CSS 显然没有“坏掉”。根据本文,当你真正观察它时,它正按照预期的方式工作。然而,它只是发展最快的行业中的一项新(er)技术,并且其中许多所谓的“问题”都将随着新属性的出现和(最重要的是)支持而得到解决,这些属性有助于我们迈向纯语义代码的世界。 :)
我记不清在哪里读到这个了(可能是 Sitepoint 的一本书),但有人建议使用表格布局 CSS 属性来解决使用浮动进行复杂布局的问题。
你获得了表格的结构和行为——承认吧,有时布局中确实需要表格——但没有实际表格那种糟糕的标记。
至于使用溢出清除浮动,对我来说,这是绝对不行的。就在上周,我不得不重新处理几个刚刚开始的模板的浮动清除,因为使用了溢出,但当我开始向页面添加其余元素时,它完全崩溃了。
:after 规则,虽然某种包含规则会很好。
是的,真是个好主意。
我一直很好奇这个问题,现在我找到了答案。感谢您的信息,我下次使用 CSS 时一定会牢记这份指南!
我在关闭标签之前应用一个 `
` 来拉伸我的非浮动容器,其中 .clear { clear: both; }。为什么有人会用浮动来定位,我无法理解。浮动是为了让元素浮动。如果你不希望下一个元素成为“流”的一部分——清除它。
我一直使用浮动来定位固定 div 内部的 div,并且通常总是使用 overflow:hidden height:auto。我知道你提到了如果想要让图像从 div 的侧面伸出来,它会被“隐藏”的事实,但谢天谢地,我还没有需要这样做,而且如果他们正确地布局他们的网站,我认为这不是人们常遇到的问题。
我也总是在下一个固定 div 上设置 clear:both 以确保它下降到下方。我的网站在每个浏览器上看起来都一样,并且从未遇到过使用这些方法的问题。
我认为浮动对于布局来说完全可以接受。
Overflow: hidden – 大错特错。
@Damian Smith:你的网站可以使用多种不同的技术看起来一样。一种涉及表格。一种是浮动。还有其他方法。浮动是为了在特殊情况下帮助你。你将它们用作标准,并试图强加于它们非标准的行为,只是为了满足你的目的。也许你应该先学习如何更好地使用 CSS 样式,然后再学习如何更好地使用 CSS 技巧。
感谢您回到基础,我使用了 overflow:hidden,并且一直想知道是否有替代方案可以让父元素对浮动做出良好的响应,我想这篇文章给了我额外的方法来处理布局中的混乱。
我非常喜欢你的论点,它对我有用。
很棒的文章和解释。
对于你的“普通”页面,解决方案是否如下 CSS…
div { overflow:auto; }
然后使用更具体的选择器覆盖它。这当然可以消除对大量 `
` 的需求。这样做的优缺点是什么?
@Richard
我认为不是。根据你对布局的谨慎程度(不谨慎),意外的滚动条可能会在用户体验中的某个时间点突然出现。
另一方面,overflow: hidden 也不是一个好的解决方案,需要额外的未来修复。
记住,你追求的是技巧,而不是技巧 :)
在很多情况下,我使用了 overflow:auto,并且滚动条在 IE6 中随机出现,或者它们在 Safari 中出现,但其他浏览器没有,或者只在 Opera 和 Firefox 中出现,而不是 Safari 或 IE6/7。
这就是为什么我坚持使用 overflow hidden。_firefox_ 的主要问题是,通常与 overflow hidden 有关的一些内容会导致在尝试打印网页时无法打印网页的第一页。根据我的经验,其他浏览器没有这个问题。
还有一件事,对我来说非常清楚
如果你需要清除,这意味着你不需要浮动
对于主布局而言。
你可以像这样强制 IE7 和 IE6 中的容器清除。这些是技巧,应该谨慎使用。最好的建议是创建一个 IE 条件样式表。因此,结合 :after 和这些,我不知道是否有必要在你的标记中添加任何 clearfix。
*:first-child html .container{min-height:1px; /* IE7 */}
* html .container{ height:1%; /*IE6*/}
当您需要快速解决方案时,clearfix 非常有用。它为我节省了许多调试工作。
试试这个
.clearfix {
height:1%;
min-height:0;
overflow:hidden;
}
我使用了这种方法,到目前为止效果很好…
为什么要用两段?
为什么不使用一段和一个换行符?
“为了让这种情况发生,上面的段落需要‘折叠’,让浮动图像从它的底部伸出来。”
嗯……我没有看到 img 标签必须位于段落内的任何充分理由。如果 img 标签位于两个段落之间(或者放在两个段落之前,这通常是我做的方法),无论浮动是否折叠,它都能正常工作。
此外,文章正文中的照片是否会倾向于作为补充或图例向前发展。更有理由让它们不在 P 标签内。
因为图像为内联元素,而内联元素完全可以放在块级元素内部。
“但是如果你想隐藏水平溢出怎么办?”
overflow-x: hidden;
overfloy-y: contain;
不用管理论上的差异,我想真诚地感谢 Chris Coiyer 先生。
他非常慷慨地为我们付费/工作,让我们表达任何意见,并托管它,即使我们攻击他的观点。
谢谢。
display:inline-block 是 float:left/right 的逻辑继承者,尽管它仍然存在一些问题(格式化代码中元素之间的空白)。