Learn web development

浮动元素(Floats)

float 属性最初只是用于浮动图像内的文本块,但是现在它已成为在网页上创建多列布局的最常用工具之一。本文将阐述它的有关知识。

要求: HTML基础知识(学习入门 HTML),和CSS的工作理念(学习 入门 CSS)。
摘要: 学习如何创建浮动特性,比如删除帽、浮动图像,和多个列在网页布局。

背景知识

最初,引入 float 属性是为了能让 web 开发人员实现简单的布局,包括在一列文本中浮动的图像,文字环绕在它的左边或右边。你可能在报纸版面上看到的东西。

但 Web 开发人员很快意识到,它可以浮动任何东西,而不仅仅是图像,所以浮动的使用范围扩大了。之前的 fancy paragraph example 的课程展示了如何使用float创建一个有趣的drop-cap效果。

现在,浮动通常用来创建整个网站布局,其中包括浮动的多列信息,因此它们彼此并排放置(默认行为是列彼此之间的排列顺序与它们在源中显示的顺序相同)。虽然有更新的更好的布局技术可用,但我们将在本模块的后面探讨,浮动仍然是最受喜欢的老物,因为它们可以支持到 Internet Explorer 4。

简单的例子

让我们来探讨如何使用浮动。我们将从一个非常简单的例子开始,包括在图像周围浮动一个文本块。你可以跟随在你的电脑上创建新的index.html文件,以填充它 simple HTML template, 以下代码插入它在适当的地方。底部的部分你可以看到一个生活最后的代码应该是什么样子的例子。

首先,我们写一些简单的HTML——添加以下到HTML的<body>内,删除之前<body>里面的东西:

<h1>Simple float example</h1>
<img src="butterfly.jpg" alt="A pretty butterfly with red, white, and brown coloring, sitting on a large leaf">
<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. 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> 到一个单独的 separate .css 文件 — 你来选择):

body {
  width: 90%;
  max-width: 900px;
  margin: 0 auto;
}
p {
  line-height: 2;
  word-spacing: 0.1rem;
}

如果你现在保存并刷新,你会看到和你预期的效果差不多——图片坐落在文本的上方,使得目前看起来有点丑陋。我们可以让图片在它的容器内居中,但是这里,我们将使用float来让图片周围的文本浮起来。将以下规则添加到你之前的规则下面:

img {
  float: left;
  margin: 0 30px 0 0;
}

现在,如果您保存和刷新,你会看到类似下面的东西:

因此,让我们考虑一下float是如何工作的 - 浮动元素 (这个例子中的<img> 元素)会脱离正常的文档布局流,并粘贴到其父容器的左侧 (这个例子中的<body>元素)。在正常布局中位于该浮动元素之下的内容,此时会围绕着浮动元素,填满其右侧的空间。

注意,浮动内容仍然遵循盒子模型诸如边缘和边界。我们设置一下图片右侧的外边距就能使得右侧的文字不会紧贴着图片。

向右浮动的内容是一样的效果,区别就是元素会浮动到右侧去,而其他内容将从左侧环绕它。尝试将上一个例子中的浮动值改为 right,再把margin-left 换成 margin-right,看看结果是什么。

再看下拉列表例子

如上所述,我们的 fancy paragraph example 从早先的课程精选了一个漂亮的cap. 在这个例子中,我们有一个简单的段落:

<p>This is my very important paragraph.
 I am a distinguished gentleman of such renown that my paragraph
 needs to be styled in a manner befitting my majesty. Bow before
my splendour, dear students, and go forth and learn CSS!</p>

我们的CSS看起来像这样:

p {
  width: 400px;
  margin: 0 auto;
}
p::first-line {
  text-transform: uppercase;
}
p::first-letter {
  font-size: 3em;
  border: 1px solid black;
  background: red;
  float: left;
  padding: 2px;
  margin-right: 4px;
}

结果如下:

这里的效果与我们在图像的第一个例子中所做的没有很大的不同,但是这一次,我们在信中的第一个字母后面的其余部分是浮动的,在使这封信看起来显得又大又大胆又有趣之后。

你可以漂浮任何的东西,只要有两个项目的空间,以配合在一起。这使我们很好地谈论多列布局。

多列浮动布局

Floats通常用于创建多个列布局,并且由于其广泛的浏览器支持已经有相当一段时间。这是尽管事实上,他们不是真的打算这个工作,并有一些奇怪的副作用,必须处理,你会在后面的文章中看到。

两列布局

让我们先从最简单的例子,一个两列布局。您可以通过创建一个新的索引。html文件在您的计算机上,填充它simple HTML template, 并在适当的地方插入下面的代码。在该部分的底部,您可以看到一个活生生的例子,什么样的最终代码应该看起来像。

首先,我们需要一些内容放入我们的列。使用以下内容替换正文中的任何内容:

<h1>2 column layout example</h1>
<div>
  <h2>First column</h2>
  <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. 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>
</div>
<div>
  <h2>Second column</h2>
  <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>
</div>

每个列都需要一个外部元素来包含其内容,并让我们一次操作它的所有内容。在这个例子中,我们选择了<div>但,你可以选择更多语义合适的东西<article>s, <section>s, 和<aside>,诸如此类。

现在为CSS将以下内容应用到HTML以提供一些基本设置:

body {
  width: 90%;
  max-width: 900px;
  margin: 0 auto;
}

body的90%的视口宽,直到它的宽度900px,在这种情况下,它将保持固定在这个宽度和中心本身在视口。 默认情况下,它的孩子 (这个<h1> 和两个 <div>s)span将跨越body的100% 宽度。如果我们想要两个<div>以便彼此并排浮动, 我们需要将它们的宽度设置为其父元素的宽度100%或更小,以便它们可以彼此并排。将以下内容添加到CSS的底部:

div:nth-of-type(1) {
  width: 48%;
}
div:nth-of-type(2) {
  width: 48%;
}

在这里我们设置了他们的父亲的宽度的48% - 这总计96%,留下我们4%自由作为两列之间的沟槽,给内容一些空间呼吸。现在我们只需要浮动列,像这样:

div:nth-of-type(1) {
  width: 48%;
  float: left;
}
div:nth-of-type(2) {
  width: 48%;
  float: right;
}

把这些结合在一起应该跟我们结果一样:

你会注意到,我们使用所有宽度的百分比 - 这是一个很好的策略,因为它创建一个liquid layout, 一种调整为不同的屏幕尺寸,并在较小的屏幕尺寸下保持相同的列宽度比例。请尝试调整浏览器窗口的宽度,以便自己查看。这是响应式网页设计的一个有价值的工具,我们将在以后的模块中讨论。

注意:你可以看到这个例子运行在 0_two-column-layout.html (参见 the source code).

你需要注意的是,列可以开始看起来可怕的时候变得很窄。一般意义切换回单个列布局窄屏幕(如手机),可以通过使用媒体查询。再一次,您将了解这些在未来响应网页设计模块。

另一种选择是将宽度设置为一个固定的单位如雷姆或像素——你可以看到一个例子two-column-layout-fixed.html (see source code), 或将通过消除max-width声明自己的例子,和改变宽度900 px,分别为430 px和430 px。这叫做固定宽度的布局——如果你调整你的浏览器大小现在,你会发现不再布局调整以适应窗口宽度,和你需要滚动在较小的尺寸。

现在我们将用流体布局。

三列布局

你已经有了一个两列布局工作,添加一个第三列(或更多)并不是太难。你只需要添加另一个列在同一个父元素。开始通过添加以下 <div>就在另外两个(或我们(or use 0_two-column-layout.html as a starting point):

<div>
  <h2>Third column</h2>
  <p>Nam consequat scelerisque mattis. Duis pulvinar dapibus magna, eget congue purus mollis sit amet. Sed euismod lacus sit amet ex tempus, a semper felis ultrices. Maecenas a efficitur metus. Nullam tempus pharetra pharetra. Morbi in leo mauris. Nullam gravida ligula eros, lacinia sagittis lorem fermentum ut. Praesent dapibus eros vel mi pretium, nec convallis nibh blandit. Sed scelerisque justo ac ligula mollis laoreet. In mattis, risus et porta scelerisque, augue neque hendrerit orci, sit amet imperdiet risus neque vitae lectus. In tempus lectus a quam posuere vestibulum. Duis quis finibus mi. Nullam commodo mi in enim maximus fermentum. Mauris finibus at lorem vel sollicitudin.</p>
</div>

现在更新你的CSS如下:

body {
  width: 90%;
  max-width: 900px;
  margin: 0 auto;
}
div:nth-of-type(1) {
  width: 36%;
  float: left;
}
div:nth-of-type(2) {
  width: 30%;
  float: left;
  margin-left: 4%;
}
div:nth-of-type(3) {
  width: 26%;
  float: right;
}

这将给我们以下结果:

这里有很少我们没有见过;唯一的真正的区别是,我们有这个额外的列来应对 - 让它坐在正确的地方,我们已经漂浮它离开;我们也给了它 margin-left of 4%, 创建一个排水沟之间的第一和第二列。我们设置列宽,这样他们都健康— 36% + 30% + 4% + 26% = 96%, 这让一个 4% 剩余部分在第二和第三列之间形成一个沟槽(该自然沟槽将总是出现在左浮动列和右浮动列之间的点,无论哪里。)

这里需要注意的一点是,你必须仔细考虑你的列的源顺序,以及它们如何浮动,以得到期望的结果。你的内容应该有道理当读源阶(认为有视觉障碍的人使用屏幕阅读器来听你的内容-你如何布局你的内容没有区别他们),但是你也需要考虑,在内容源的订单将出现在命令之前浮动元素太所以进一步的左左浮动的情况下,再到右下右飘。为了说明我们的意思,试着改变 float 第二列向右 (或者看看 three-column-layout-wrong-order.html (source code)). 现在你会看到,如下:

div1  div3  div2

这是因为第二个<div>在source order上比第三个<div>等级要高 (DOM上第二个<div>先出现并声明了float right) ,所以在float order 上也会比第三个<div>等级要高。又因为两者同时像右浮动,第二个<div>就会更加地靠右。

注:完成了这一点您可以找到的例子1_three-column-layout.html (see source code).

清除浮动

现在你已经知道了关于 float 属性的一些有趣事实,不过你很快就能够碰到一个问题——所有内容在漂浮,如果不是处理看起来可怕。为了我们所说低于的第三个环绕浮动元素,尝试添加以下HTML <div>元素 (并检查 2_float-disaster.html (source code)):

<footer>
  <p>&copy;2016 your imagination. This isn't really copyright, this is a mockery of the very concept. Use as you wish.</p>
</footer>

你会发现旁边的页脚是包装在空间最长的列,看起来可怕的——我们真正想要的页脚留在底部,下面的所有列。好吧,幸运的是有一个简单的方法来解决这个问题的 clear 属性。当你将它应用到一个元素,它基本上说“停止浮动在这里” - 这个元素和它之后的源将不会浮动,除非你应用一个新的 float 声明到另一个元素。

所以,要解决我们的问题,添加以下规则到您的CSS:

footer {
  clear: both;
}

这将给你一个页脚的行为本身和坐在您的列,喜欢它应该做的是:

clear can take three values:

  • Left:停止左侧浮动
  • right:停止右侧浮动
  • both: 停止左右浮动

你通常只需要设置清除:两者在元素上你想要的浮动停止;在某些情况下,您只需要取消左或右引号。

注:你可以在这个阶段找到例子 2a_fixed-by-clear.html (see source code).

浮动问题

以上部分提供了使用浮动创建简单布局的基础,但是还有一些问题需要解决。 让我们谈谈这些问题。

整个宽度可能难以计算

到目前为止,我们的例子是没有应用样式的浮动框——这很容易。当你开始给这些框加上样式时,比如 borders, padding 等等,问题就来了。为了更好了解这个问题,可以将下面的 CSS 加入到你的代码里 (你也可以看这个例子 3_broken-layout.html (source code)):

div, footer {
  padding: 1%;
  border: 2px solid black;
  background-color: red;
}

此时,您将看到您的布局已损坏 - 由于填充和边框引入的额外宽度,三列不再适合一行,因此第三列下降到另外两列。

我们有很多方法可以解决上面的问题,但最好的方法是给你的html加上下面的css。

* {
  box-sizing: border-box;
}

box-sizing 将我们box的width的计算方式变为了content + padding + border,而不是之前的content的width,所以当我们增加padding或border的width时,我们不会增加我们box的width。相反我们的content的width会缩小padding或border增加的宽度。

我们有另一个问题 — 页脚正压在最长列上, 在这一点并不理想—让我们尝试修复沿着这个 margin-top 它清理给页脚部分:

footer {
  clear: both;
  margin-top: 4%;
} 

然而,这不起作用 — floated元素在某些方面表现相当奇怪,它存在于正常的文档布局流程之外:

  • 首先,他们在父元素的有效高度为0 — 尝试在浏览器中加载 1_three-column-layout.html 并检查 <body> 的高度,查看 developer tools, 你将会看到并明白我们的意思 — body报告的高度只有 <h1> 的高度 。这个可以通过很多方式解决,但在我们上述中我们依靠在父容器的底部清除浮动来解决这一问题,如我们在我们的当前示例所做的那样。 如果在当前示例中检查正文的高度,您应该会看到它的高度本身。
  • 其次,你不能在非浮动元素上使用边距去创建它们之间的浮动空间— 这是我们在这里眼前的问题,我们将在下面实施修复。
  • 文章概述了所有关于Floats使用以及修复一些奇怪的元素。

所以,让我们解决这个! 首先,在HTML的页添加,新的<div> 元素,在上方页脚:

<div class="clearfix"></div>

如果你没有一个元素可以清除,你可以添加一个不可见的 "clearfix div" 元素,在你想要清除的浮动后是非常有用的 (就像页脚), 但在这里也有用。接下来我们要做的是清除:both; 声明了对页脚进行样式化的规则,并将其放在clearfix div上:

.clearfix {
  clear: both;
}

我们现在有一个很好的顶部边缘,但也有另一个问题— 列和页脚。cleardiv div 被赋予相同背景填充边框!为了解决这个问题,让我们先给每个列div一个类的列:

<div class="column">
  ...
</div>

 现在将框样式改变规则,让我们应用到div和footer,这样只有div列样式:

.column, footer {
  padding: 1%;
  border: 2px solid black;
  background-color: red;
}

这只是为了现在解决它。

注: 查看在这个阶段最后一个固定的例子4_fixed-layout-border-box.html (source code).

另一点要注意的是,box-sizing Internet Explorer 8不支持 — 如果你明确需要支持旧浏览器,你可能需要手动调整列宽度以允许填充和边框宽度。考虑到你不能使用百分比调整大小边框,你需要留出足够空间,同时尽可能多填充父级宽度,但这不是一个非常精确的技术 — 你可以在操作中看到这样的修复 fixed-layout-adjusted-percentages.html (见源代码)。

浮动项目的背景高度

到目前为止,我们建好的示例是有效的,但另一个问题是列高度是不同的 - 如果列都是相同的高度,它看起来会更好。

我们可以通过给所有的列固定来解决这个问题height (see 5_fixed-height-columns.html (源代码):

.column {
  height: 550px;
}

然而在许多情况下这并不理想—它使设计呆板。如果你能保证列中总是有相同数量的内容,这是可以的,但这并不总是如此— 在很多类型的网站上,内容也会定期更改。

Flexbox是一种新的布局设计,flexbox可自动伸展列,只要解决技术上它们伸展的长柱问题。

你也可以考虑:

  1. 将列的背景颜色设置为与其父背景相同的颜色,但不能高度不同。这是目前最好的选择。
  2. 将它们部分溢出设置为固定宽度并使内容滚动使用overflow (参见我们的示例。)
  3. 在柱的父元素上绘制假背景 - 这种技术叫伪列,该元素看起来像列的背景。这涉及到从实际列中移除背景(与边框)不幸的是,这将无法处理列边框。 详见对于伪列伪列流体布局的教程。

清除浮动会变复杂

我们在文章中建立的简单例子很容易理解,但是当布局变得更加复杂清理也会变得更加复杂。如果你没有一个方便的容器在必要的地方使用clearfix divs将被清理。你需要确保任何浮动的内容尽快清除,以避免降低麻烦。

总结

在接下来的文章中,我们将采取更进一步的定位创造添置相当复杂的网格布局。在这一点上,你会掌握一些强大的工具。

文档标签和贡献者