以下是浮动在 CSS 中的工作方式 您还想了解有关浮动的什么信息?

2025-06-10

CSS 中浮动的工作原理如下

您还想了解有关花车的哪些信息?

封面照片由 JANUPRASAD 通过 Unsplash 拍摄。

还有人记得以前用浮动布局的年代吗?以前我们得赤脚在雪地里爬坡写 CSS,真是上天入地。现在的年轻人都用弹性盒子和网格了……

无论如何,浮动对于非大规模布局仍然很有用。即使你最终不想在新应用中使用它们,你最终也可能会维护一个对浮动使用繁琐方法的旧版应用。了解浮动的基本工作原理在各种情况下都会派上用场。

另外,浮动是 CSS 的一大痛点。很多人遇到过这种情况:应用浮动后,页面上的所有内容突然移动(而且不知道为什么)。今天就让我们一起克服这个难题吧。

那么,让我们立即开始探究花车的奥秘吧。

基础知识

浮动最擅长的就是让文本围绕其他元素流动。在这方面,浮动绝对是模拟打印布局的最佳方式。

发生的事情很简单:

  1. 浮动元素被放置在原本的位置
  2. 它被从正常的文档流中移除,并被推到尽​​可能靠左或靠右的位置
  3. 在其之后的元素将围绕浮动元素排列

我可以浮动中心吗?

不行。我知道这很酷,但根本没用。

我猜你会如何实现这个文字加猫图的版本。你会如何巧妙地将文字拆分?目前没有什么好办法。这可能就是它从未实现的原因。

浮动元素不属于正常的文档流?所以它就像“position: absolute”一样?

position: absolute不完全是。具有(或类似属性)的元素会完全从文档流中移除。绝对定位的元素通常会位于其他邻近元素的上方或下方,因为它们会相互忽略。

当一个元素浮动时,它并不完全处于正常的文档流,但它确实与其他元素相互作用;它们遵循特殊的定位规则,主要是它们会围绕它进行排列。

浮标不想太大

未明确设置大小的浮动元素会“缩小以适应”position: absolute其内容——也就是说,它只会占用所需的宽度。如果浮动元素中的内容不多,它就不会太大;如果内容很多,它就会变大。您可能之前在和position: fixed元素中见过类似的行为。

预测花车的去向

当您在玩 Jabberwocky 示例时,您是否碰巧发现了类似的东西?

漂浮物以一种相当令人困惑和痛苦的方式漂浮着。

人们倾向于避免使用浮动的原因之一是它们看起来难以预测。如果一系列高度不同的浮动溢出了行,会发生什么?

让我们看一下浮动元素如何定位的规范:

[...] 当一个元素浮动时,它会脱离文档的正常流(尽管它仍然是文档的一部分)。它会向左或向右移动,直到接触到其包含框或另一个浮动元素的边缘。

所以,当某个元素适合我们的宽度时,一切正常。当它不适合时,它会向下浮动一段时间,直到碰到它想要停止的边缘——它的父容器的边缘,或者另一个浮动元素。

以 GIF 形式解释上述令人苦恼的浮动排序。

为什么最后一个没有向上移动来填补那个可怕的空白?

浮动元素永远不会将自己定位在 HTML 顺序中位于其前面的元素之上。

然而,它会牢记这一限制,尝试尽可能高地“漂浮”。

边距、盒子模型和 HTML 顺序

在基本示例中,您是否对此感到困扰?

上述钢笔的截图,突出显示了左侧的硬边缘。

这里我们需要一个margin。如果你随机选择一个元素,大概有三分之一的概率能猜出该将 margin 应用于哪个元素。虽然感觉随机猜测是 CSS 的精髓,但还是让我们试着理解一下浮动在这里的作用。

纸上绘制的为所有三个元素添加边距的效果。

#1 - 如果你给外层容器添加 margin-left 属性,就会出现这种情况#container——它只会把所有内容往右推。这并不能真正解决浮动框导致文本边缘过硬的问题。大概没人试过用这种方法修复浮动,除非是在凌晨 3 点,绝望地哭泣。(谁经历过这种事?)

#2 - 你可能真的尝试过——将 应用于margin-left文本本身。然而,文本的边距是基于文本的“盒子”——如果没有浮动元素,文本就会位于那里。(你可以想象在浮动元素“下方”有一个边距。)

文本本身仍然像之前一样围绕浮动元素流动,但相对于其父元素,它保留了一定的外边距。margin 属性无法为文本添加“之字形”外边距,并且文本必须与其父元素保持一定的距离,而外边距代表了文本与浮动元素之间的距离,因此,仅与浮动元素保持距离是不行的。

#3 - 外边距会添加到实际的浮动元素上,从而扩展其浮动框。文本将围绕整个浮动框流动,包括外边距。因此,添加margin-right到左侧浮动的猫形框和margin-left右侧浮动的猫形框会给文本留出一些空间。

总结一下 -在浮动元素上放置边距会导致其他东西流动到组合浮动框的周围,包括任何边距。

我们在这里要表达的想法是 - 页面上的其他内容围绕浮动内容移动,而不是浮动内容围绕页面上的其他内容移动。

我们还可以将浮动元素堆叠在一起!浮动元素会很好地挨着其他浮动元素,并且文本会围绕它们流动。

需要注意的是,浮动元素在 HTML 中的放置顺序非常重要。如有疑问,请优先考虑浮动元素。假设您是浏览器,并且正在按“顺序”读取 HTML 内容——您肯定想知道浮动元素首先位于何处,这样就不必重新绘制之后必须围绕浮动元素流动的所有元素。

清除浮动

具有该属性的元素clear描述了该元素如何与附近的浮动元素交互。您可以为浮动元素非浮动元素添加 clear 属性。

clear 属性意味着:我不希望在这个方向上靠近我的任何浮动!

由于在页面上推动其他元素是不礼貌的,因此,如果附近有冲突的浮动元素,则具有清除属性的元素会向下移动。可以认为清除元素在社交上是尴尬的,并且会避免冲突。

浮动不会像你想象的那样占用空间

如果你以前使用过浮点数,你可能会发现自己处于这种情况:

#container包含所有浮动元素(且仅包含浮动元素)的折叠。这是因为浮动元素会将其从正常文档流中移除,并且其周围的容器不会创建新的块格式化上下文

还记得我上面说过吗:

它被从正常的文档流中移除,并被推到尽​​可能靠左或靠右的位置

“从文档流中删除”在这里具有含义和技术后果!

根据 CSS 的规则,容器的高度由其“在正常文档流内”的所有内容决定。然而,我们也可以将容器设置为“块格式化上下文”——有点像页面内的迷你布局——这样容器就需要将自己视为一个迷你文档,它会拉伸以适应其所有内容,即使是超出文档流的内容。

我们需要做一些令人信服的事情来让容器伸展以适应我们的浮子,但要知道我们有选择。

一些可能的解决方案:

1. 创建一个位于浮动元素之后的元素

这是clearfix-type-one上面提到的解决方案。这也是“老派”的 Clearfix。

我们现在知道,容器会拉伸以适应其流内的所有元素,而浮动元素不在其流内。因此,我们需要一个非浮动元素,放置在浮动元素之后。我们可以使用以下属性clear来实现:

<div id="container">
  <img class="floaty-left" src="https://placekitten.com/100/200">
  <img class="floaty-left" src="https://placekitten.com/100/100">
  <img class="floaty-left" src="https://placekitten.com/160/200">
  <img class="floaty-left" src="https://placekitten.com/100/120">
  <div style="clear: both;"> </div>
</div>
Enter fullscreen mode Exit fullscreen mode

这将导致容器向下延伸至我们清除的 div。

但是,该元素会有一些自身的高度(因为它应该包含一些文本),所以我们可以添加类似的代码,height: 0以确保它在继续应用清除固定效果的同时不会影响容器的高度。多年来,我见过其他实现此目的的方法,例如使用max-height,甚至font-size: 0。¯\_(ツ)_/¯

由于这仅用于显示并且不具有语义,我们也可以将其移动到应用于容器的::after 伪元素。

这就是我们最终得到如下结果的方式:

  // the "basic" clearfix with after
  &.clearfix-type-one {
    background-color: #644;
    &::after {
      content: " ";
      display: block;
      height: 0;
      clear: both;
      visibility: hidden;
    }
  }
Enter fullscreen mode Exit fullscreen mode

这还可以进一步完善;网上有很多类似的解决方案。例如,Nicholas Gallagher 于 2011 年提出的 micro clearfix。这类 Clearfix 解决方案往往具有出色的跨浏览器支持,因为它们已经存在了近十年。

2. 使用overflow: hidden创建新的块格式化上下文

(从技术上讲,您可以使用任何不可见的溢出值,但隐藏值往往是效果最好的值。请给我一点时间来解释一下……)

这是clearfix-type-two上面提到的解决方案。摘自MDN 文档

块格式化上下文包含创建它的元素内的所有内容。

因此,强制父容器形成一个新的块格式化上下文会强制其扩展,因为它必须完全包含其所有子容器。而且这只需要一个属性就能完成,那么为什么这不是最佳解决方案呢?为什么它只是列表中三个方案中的第二个呢?

嗯……你用的是overflow: hidden。这并非没有后果;你得处理一个除了自身之外什么都不显示的容器。如果我们还想给某些元素添加彩虹阴影,而这些元素会被裁剪掉,或者在容器外放置绝对定位的闪光效果,那该怎么办?如果只是为了清除浮动元素而去掉这些元素,那就太疯狂了。

你能想象这是多么可笑的事情。

还记得我之前说过,你可以使用任何不可见的溢出值吗?好吧,想象一下,如果overflow: scroll在侧面创建滚动条,那看起来会有多糟糕。真是让人头疼。

3. 使用display: flow-root创建新的块格式化上下文

这就是clearfix-type-three上面笔中的解决方案。

与上述解决方案不同,此方案旨在在固有层面上发挥作用,而非“黑客攻击”。规范如下:

该元素生成一个块容器框,并使用流式布局来布局其内容。它始终会为其内容建立一个新的块格式化上下文。

所以这基本上和 做了同样的事情overflow: hidden,但没有副作用。✨

这听起来正是我们想要的!它未被使用的原因是跨浏览器支持——目前几乎 30% 的设备不支持它,Safari 和 IE/Edge 一如既往地是问题所在。

您还想了解有关花车的哪些信息?

一系列热气球
页脚照片由 Cristina Gottardi 在 Unsplash 上拍摄。

鏂囩珷鏉ユ簮锛�https://dev.to/tchaflich/here-s-how-floats-work-in-css-13eg
PREV
成为 Tech Lead 之前你需要知道的五件事总结
NEXT
4 月份有 10 场会议您可以在家参加🏡