花车

float 属性最初用于文本块内的浮动图片,后来成为在网页上创建多列布局的最常用工具之一。随着 Flexbox 和网格的出现,它现在又回到了最初的目的,正如本文所解释的那样。

¥Originally for floating images inside blocks of text, the float property became one of the most commonly used tools for creating multiple column layouts on webpages. With the advent of flexbox and grid it's now returned to its original purpose, as this article explains.

先决条件: HTML 基础知识(研究 HTML 简介),以及 CSS 如何工作的想法(研究 CSS 简介)。
目标: 了解如何在网页上创建浮动功能并使用 clear 属性以及其他清除浮动的方法。

花车背景

¥The background of floats

引入 float 属性是为了允许 Web 开发者实现涉及浮动在文本列内的图片的布局,并且文本环绕在其左侧或右侧。你可能会在报纸版面中看到这种东西。

¥The float property was introduced to allow web developers to implement layouts involving an image floating inside a column of text, with the text wrapping around the left or right of it. The kind of thing you might get in a newspaper layout.

但 Web 开发者很快意识到你可以浮动任何东西,而不仅仅是图片,因此浮动的使用范围扩大了,例如,扩展到有趣的布局效果,例如 drop-caps

¥But web developers quickly realized that you can float anything, not just images, so the use of float broadened, for example, to fun layout effects such as drop-caps.

浮动通常用于创建整个网站布局,其中包含多个浮动信息列,因此它们彼此并排(默认行为是各列按照它们在源中出现的顺序依次位于另一列下方)。有更新、更好的布局技术可用。这样使用浮点数应该算是 遗留技术 了。

¥Floats have commonly been used to create entire website layouts featuring multiple columns of information floated so they sit alongside one another (the default behavior would be for the columns to sit below one another in the same order as they appear in the source). There are newer, better layout techniques available. Using floats in this way should be regarded as a legacy technique.

在这篇文章中,我们将集中讨论浮动的正确使用。

¥In this article we'll just concentrate on the proper uses of floats.

浮动示例

¥A float example

让我们探讨一下浮动的用法。我们将从一个涉及在元素周围浮动文本块的示例开始。你可以在计算机上创建一个新的 index.html 文件,用 HTML 模板 填充该文件,然后在适当的位置插入以下代码。在本节的底部,你可以看到最终代码应该是什么样子的实时示例。

¥Let's explore the use of floats. We'll start with an example involving floating a block of text around an element. You can follow along by creating a new index.html file on your computer, filling it with an HTML template, and inserting the below code into it at the appropriate places. At the bottom of the section, you can see a live example of what the final code should look like.

首先,我们将从一些 HTML 开始。将以下内容添加到你的 HTML 正文中,删除其中之前的所有内容:

¥First, we'll start off with some HTML. Add the following to your HTML body, removing anything that was inside there before:

html
<h1>Float example</h1>

<div class="box">Float</div>

<p>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam
  dolor, eu lacinia lorem placerat vulputate. Duis felis orci, pulvinar id metus
  ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies tellus
  laoreet sit amet.
</p>

<p>
  Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet
  orci vel, viverra egestas ligula. Curabitur vehicula tellus neque, ac ornare
  ex malesuada et. In vitae convallis lacus. Aliquam erat volutpat. Suspendisse
  ac imperdiet turpis. Aenean finibus sollicitudin eros pharetra congue. Duis
  ornare egestas augue ut luctus. Proin blandit quam nec lacus varius commodo et
  a urna. Ut id ornare felis, eget fermentum sapien.
</p>

<p>
  Nam vulputate diam nec tempor bibendum. Donec luctus augue eget malesuada
  ultrices. Phasellus turpis est, posuere sit amet dapibus ut, facilisis sed
  est. Nam id risus quis ante semper consectetur eget aliquam lorem. Vivamus
  tristique elit dolor, sed pretium metus suscipit vel. Mauris ultricies lectus
  sed lobortis finibus. Vivamus eu urna eget velit cursus viverra quis
  vestibulum sem. Aliquam tincidunt eget purus in interdum. Cum sociis natoque
  penatibus et magnis dis parturient montes, nascetur ridiculus mus.
</p>

现在将以下 CSS 应用到你的 HTML(使用 <style> 元素或 <link> 到单独的 .css 文件 - 你的选择):

¥Now apply the following CSS to your HTML (using a <style> element or a <link> to a separate .css file — your choice):

css
body {
  width: 90%;
  max-width: 900px;
  margin: 0 auto;
  font:
    0.9em/1.2 Arial,
    Helvetica,
    sans-serif;
}

.box {
  width: 150px;
  height: 100px;
  border-radius: 5px;
  background-color: rgb(207 232 220);
  padding: 1em;
}

如果保存并刷新,你会看到与你期望的非常相似的内容:在正常流程中,该框位于文本上方。

¥If you save and refresh, you'll see something much like what you'd expect: the box is sitting above the text, in normal flow.

漂浮的盒子

¥Floating the box

要浮动框,请将 floatmargin-right 属性添加到 .box 规则中:

¥To float the box, add the float and margin-right properties to the .box rule:

html
<h1>Float example</h1>

<div class="box">Float</div>

<p>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam
  dolor, eu lacinia lorem placerat vulputate. Duis felis orci, pulvinar id metus
  ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies tellus
  laoreet sit amet.
</p>

<p>
  Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet
  orci vel, viverra egestas ligula. Curabitur vehicula tellus neque, ac ornare
  ex malesuada et. In vitae convallis lacus. Aliquam erat volutpat. Suspendisse
  ac imperdiet turpis. Aenean finibus sollicitudin eros pharetra congue. Duis
  ornare egestas augue ut luctus. Proin blandit quam nec lacus varius commodo et
  a urna. Ut id ornare felis, eget fermentum sapien.
</p>

<p>
  Nam vulputate diam nec tempor bibendum. Donec luctus augue eget malesuada
  ultrices. Phasellus turpis est, posuere sit amet dapibus ut, facilisis sed
  est. Nam id risus quis ante semper consectetur eget aliquam lorem. Vivamus
  tristique elit dolor, sed pretium metus suscipit vel. Mauris ultricies lectus
  sed lobortis finibus. Vivamus eu urna eget velit cursus viverra quis
  vestibulum sem. Aliquam tincidunt eget purus in interdum. Cum sociis natoque
  penatibus et magnis dis parturient montes, nascetur ridiculus mus.
</p>
css
.box {
  float: left;
  margin-right: 15px;
  width: 150px;
  height: 100px;
  border-radius: 5px;
  background-color: rgb(207 232 220);
  padding: 1em;
}

现在,如果你保存并刷新,你将看到类似以下内容的内容:

¥Now if you save and refresh you'll see something like the following:

让我们考虑一下浮动是如何工作的。设置了浮动的元素(在本例中为 <div> 元素)将从文档的正常布局流中取出,并粘贴到其父容器(在本例中为 <body>)的左侧。在正常布局流程中位于浮动元素下方的任何内容现在都将环绕它,填充其右侧的空间,直到浮动元素的顶部。在那里,它将停止。

¥Let's think about how the float works. The element with the float set on it (the <div> element in this case) is taken out of the normal layout flow of the document and stuck to the left-hand side of its parent container (<body>, in this case). Any content that would come below the floated element in the normal layout flow will now wrap around it instead, filling up the space to the right-hand side of it as far up as the top of the floated element. There, it will stop.

将内容向右浮动具有完全相同的效果,但效果相反:浮动元素将粘在右侧,内容将围绕其向左环绕。尝试将最后一个规则集中的浮点值更改为 right,并将 margin-right 替换为 margin-left,看看结果是什么。

¥Floating the content to the right has exactly the same effect, but in reverse: the floated element will stick to the right, and the content will wrap around it to the left. Try changing the float value to right and replace margin-right with margin-left in the last ruleset to see what the result is.

可视化浮动

¥Visualizing the float

虽然我们可以向浮动添加边距以将文本推开,但我们无法向文本添加边距以将其移离浮动。这是因为浮动元素被从正常流中取出,并且后续项目的框实际上在浮动元素后面运行。你可以通过对示例进行一些更改来看到这一点。

¥While we can add a margin to the float to push the text away, we can't add a margin to the text to move it away from the float. This is because a floated element is taken out of normal flow and the boxes of the following items actually run behind the float. You can see this by making some changes to your example.

special 类添加到文本的第一段(紧跟浮动框的那段),然后在 CSS 中添加以下规则。这些将为我们的下一段提供背景颜色。

¥Add a class of special to the first paragraph of text, the one immediately following the floated box, then in your CSS add the following rules. These will give our following paragraph a background color.

css
.special {
  background-color: rgb(148 255 172);
  padding: 10px;
  color: purple;
}

为了使效果更容易看到,请将浮标上的 margin-right 更改为 margin,以便在浮标周围获得空间。你将能够看到浮动框正下方运行的段落的背景,如下例所示。

¥To make the effect easier to see, change the margin-right on your float to margin so you get space all around the float. You'll be able to see the background on the paragraph running right underneath the floated box, as in the example below.

html
<h1>Float example</h1>

<div class="box">Float</div>

<p class="special">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam
  dolor, eu lacinia lorem placerat vulputate. Duis felis orci, pulvinar id metus
  ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies tellus
  laoreet sit amet.
</p>

<p>
  Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet
  orci vel, viverra egestas ligula. Curabitur vehicula tellus neque, ac ornare
  ex malesuada et. In vitae convallis lacus. Aliquam erat volutpat. Suspendisse
  ac imperdiet turpis. Aenean finibus sollicitudin eros pharetra congue. Duis
  ornare egestas augue ut luctus. Proin blandit quam nec lacus varius commodo et
  a urna. Ut id ornare felis, eget fermentum sapien.
</p>

<p>
  Nam vulputate diam nec tempor bibendum. Donec luctus augue eget malesuada
  ultrices. Phasellus turpis est, posuere sit amet dapibus ut, facilisis sed
  est. Nam id risus quis ante semper consectetur eget aliquam lorem. Vivamus
  tristique elit dolor, sed pretium metus suscipit vel. Mauris ultricies lectus
  sed lobortis finibus. Vivamus eu urna eget velit cursus viverra quis
  vestibulum sem. Aliquam tincidunt eget purus in interdum. Cum sociis natoque
  penatibus et magnis dis parturient montes, nascetur ridiculus mus.
</p>
css
body {
  width: 90%;
  max-width: 900px;
  margin: 0 auto;
  font:
    0.9em/1.2 Arial,
    Helvetica,
    sans-serif;
}

.box {
  float: left;
  margin: 15px;
  width: 150px;
  height: 150px;
  border-radius: 5px;
  background-color: rgb(207 232 220);
  padding: 1em;
}

我们的以下元素的 线盒 已被缩短,因此文本围绕浮动,但由于浮动已从正常流中删除,段落周围的框仍然保持全宽。

¥The line boxes of our following element have been shortened so the text runs around the float, but due to the float being removed from normal flow the box around the paragraph still remains full width.

清除浮动

¥Clearing floats

我们已经看到,浮动元素已从正常流程中删除,其他元素将显示在其旁边。如果我们想阻止后面的元素向上移动,我们需要清除它;这是通过 clear 属性实现的。

¥We've seen that a float is removed from normal flow and that other elements will display beside it. If we want to stop the following element from moving up, we need to clear it; this is achieved with the clear property.

在上一示例的 HTML 中,将 cleared 类添加到浮动项下方的第二段。然后将以下内容添加到你的 CSS 中:

¥In your HTML from the previous example, add a class of cleared to the second paragraph below the floated item. Then add the following to your CSS:

css
.cleared {
  clear: left;
}
html
<h1>Float example</h1>

<div class="box">Float</div>

<p class="special">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam
  dolor, eu lacinia lorem placerat vulputate. Duis felis orci, pulvinar id metus
  ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies tellus
  laoreet sit amet.
</p>

<p class="cleared">
  Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet
  orci vel, viverra egestas ligula. Curabitur vehicula tellus neque, ac ornare
  ex malesuada et. In vitae convallis lacus. Aliquam erat volutpat. Suspendisse
  ac imperdiet turpis. Aenean finibus sollicitudin eros pharetra congue. Duis
  ornare egestas augue ut luctus. Proin blandit quam nec lacus varius commodo et
  a urna. Ut id ornare felis, eget fermentum sapien.
</p>

<p>
  Nam vulputate diam nec tempor bibendum. Donec luctus augue eget malesuada
  ultrices. Phasellus turpis est, posuere sit amet dapibus ut, facilisis sed
  est. Nam id risus quis ante semper consectetur eget aliquam lorem. Vivamus
  tristique elit dolor, sed pretium metus suscipit vel. Mauris ultricies lectus
  sed lobortis finibus. Vivamus eu urna eget velit cursus viverra quis
  vestibulum sem. Aliquam tincidunt eget purus in interdum. Cum sociis natoque
  penatibus et magnis dis parturient montes, nascetur ridiculus mus.
</p>
css
body {
  width: 90%;
  max-width: 900px;
  margin: 0 auto;
  font:
    0.9em/1.2 Arial,
    Helvetica,
    sans-serif;
}

.box {
  float: left;
  margin: 15px;
  width: 150px;
  height: 150px;
  border-radius: 5px;
  background-color: rgb(207 232 220);
  padding: 1em;
}

.special {
  background-color: rgb(148 255 172);
  padding: 10px;
  color: purple;
}

.cleared {
  clear: left;
}

你应该看到第二段现在清除了浮动元素并且不再出现在它旁边。clear 属性接受以下值:

¥You should see that the second paragraph now clears the floated element and no longer comes up alongside it. The clear property accepts the following values:

  • left:透明的物品飘到左边。
  • right:透明的物品漂浮到右侧。
  • both:清除左侧或右侧的所有浮动项目。

清理缠绕在漂浮物上的盒子

¥Clearing boxes wrapped around a float

你现在知道如何清除浮动元素后面的内容,但让我们看看如果你有一个高浮动元素和一个短段落,并且两个元素都包裹着一个框,会发生什么。

¥You now know how to clear something following a floated element, but let's see what happens if you have a tall float and a short paragraph, with a box wrapped around both elements.

问题

¥The problem

更改文档,使第一段和浮动框用 <div> 联合包裹,该 <div> 的类为 wrapper

¥Change your document so that the first paragraph and the floated box are jointly wrapped with a <div>, which has a class of wrapper.

html
<div class="wrapper">
  <div class="box">Float1</div>

  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus
    aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci,
    pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at
    ultricies tellus laoreet sit amet.
  </p>
</div>

在 CSS 中,为 .wrapper 类添加以下规则,然后重新加载页面:

¥In your CSS, add the following rule for the .wrapper class and then reload the page:

css
.wrapper {
  background-color: rgb(148 255 172);
  padding: 10px;
  color: purple;
}

另外,去掉原来的 .cleared 类:

¥In addition, remove the original .cleared class:

css
.cleared {
  clear: left;
}

你会看到,就像我们在段落上放置背景颜色的示例一样,背景颜色在浮动后面运行。

¥You'll see that, just like in the example where we put a background color on the paragraph, the background color runs behind the float.

html
<p>
  Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet
  orci vel, viverra egestas ligula. Curabitur vehicula tellus neque, ac ornare
  ex malesuada et. In vitae convallis lacus. Aliquam erat volutpat. Suspendisse
  ac imperdiet turpis. Aenean finibus sollicitudin eros pharetra congue. Duis
  ornare egestas augue ut luctus. Proin blandit quam nec lacus varius commodo et
  a urna. Ut id ornare felis, eget fermentum sapien.
</p>

<p>
  Nam vulputate diam nec tempor bibendum. Donec luctus augue eget malesuada
  ultrices. Phasellus turpis est, posuere sit amet dapibus ut, facilisis sed
  est. Nam id risus quis ante semper consectetur eget aliquam lorem. Vivamus
  tristique elit dolor, sed pretium metus suscipit vel. Mauris ultricies lectus
  sed lobortis finibus. Vivamus eu urna eget velit cursus viverra quis
  vestibulum sem. Aliquam tincidunt eget purus in interdum. Cum sociis natoque
  penatibus et magnis dis parturient montes, nascetur ridiculus mus.
</p>
css
body {
  width: 90%;
  max-width: 900px;
  margin: 0 auto;
  font:
    0.9em/1.2 Arial,
    Helvetica,
    sans-serif;
}

.box {
  float: left;
  margin: 15px;
  width: 150px;
  height: 150px;
  border-radius: 5px;
  background-color: rgb(207 232 220);
  padding: 1em;
  color: black;
}

再次,这是因为浮子已脱离正常流动。你可能期望通过将浮动框和包围浮动框的第一段文本封装在一起,后续内容将从框中清除。但事实并非如此,如上所示。为了解决这个问题,标准方法是使用 display 属性创建 块格式化上下文 (BFC)。

¥Once again, this is because the float has been taken out of normal flow. You might expect that by wrapping the floated box and the text of first paragraph that wraps around the float together, the subsequent content will be cleared of the box. But this is not the case, as shown above. To deal with this, the standard method is to create a block formatting context (BFC) using the display property.

展示:flow-root

¥display: flow-root

解决这个问题的方法是使用 display 属性的值 flow-root。其存在只是为了在不使用 hack 的情况下创建 BFC - 使用它时不会产生意想不到的后果。

¥To solve this problem is to use the value flow-root of the display property. This exists only to create a BFC without using hacks — there will be no unintended consequences when you use it.

css
.wrapper {
  background-color: rgb(148 255 172);
  padding: 10px;
  color: purple;
  display: flow-root;
}
html
<h1>Float example</h1>
<div class="wrapper">
  <div class="box">Float</div>

  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus
    aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci,
    pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at
    ultricies tellus laoreet sit amet.
  </p>
</div>
<p class="cleared">
  Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet
  orci vel, viverra egestas ligula. Curabitur vehicula tellus neque, ac ornare
  ex malesuada et. In vitae convallis lacus. Aliquam erat volutpat. Suspendisse
  ac imperdiet turpis. Aenean finibus sollicitudin eros pharetra congue. Duis
  ornare egestas augue ut luctus. Proin blandit quam nec lacus varius commodo et
  a urna. Ut id ornare felis, eget fermentum sapien.
</p>

<p>
  Nam vulputate diam nec tempor bibendum. Donec luctus augue eget malesuada
  ultrices. Phasellus turpis est, posuere sit amet dapibus ut, facilisis sed
  est. Nam id risus quis ante semper consectetur eget aliquam lorem. Vivamus
  tristique elit dolor, sed pretium metus suscipit vel. Mauris ultricies lectus
  sed lobortis finibus. Vivamus eu urna eget velit cursus viverra quis
  vestibulum sem. Aliquam tincidunt eget purus in interdum. Cum sociis natoque
  penatibus et magnis dis parturient montes, nascetur ridiculus mus.
</p>
css
body {
  width: 90%;
  max-width: 900px;
  margin: 0 auto;
  font:
    0.9em/1.2 Arial,
    Helvetica,
    sans-serif;
}

.box {
  float: left;
  margin: 15px;
  width: 150px;
  height: 150px;
  border-radius: 5px;
  background-color: rgb(207 232 220);
  padding: 1em;
  color: black;
}

测试你的技能!

¥Test your skills!

你已读完本文,但你还记得最重要的信息吗?在继续之前,你可以找到一些进一步的测试来验证你是否已保留此信息 - 请参阅 测试你的技能:花车

¥You've reached the end of this article, but can you remember the most important information? You can find some further tests to verify that you've retained this information before you move on — see Test your skills: Floats.

概括

¥Summary

你现在已经了解了现代 Web 开发中有关浮动的所有知识。请参阅有关 遗留布局方法 的文章,了解有关它们过去如何使用的信息,如果你发现自己正在处理较旧的项目,这可能会很有用。

¥You now know all there is to know about floats in modern web development. See the article on legacy layout methods for information on how they used to be used, which may be useful if you find yourself working on older projects.