最初用于在文本块内浮动图像
,float属性成为在网页上创建多列布局最常用的工具之一。随着flexbox和grid的出现,它现在又回到了最初的目的,正如本文所解释的那样。
引入float属性是为了允许web开发人员实现包含图像在文本列内浮动的布局,文本在其左侧或右侧环绕。就像你在报纸版面上看到的那样。
但网页开发者很快意识到,你可以浮动任何东西,而不仅仅是图像,所以浮动的使用范围扩大了,例如,有趣的布局效果,如首字下沉。
浮动通常用于创建整个网站布局,其中包含多个浮动的信息列,因此它们彼此相邻(默认的行为是列以相同的顺序排列在另一个列的下面,因为它们出现在源中)。有更新、更好的布局技术可用。以这种方式使用浮点数应该被视为一种遗留技术。
在本文中,我们只关注浮动的正确使用。
让我们来探索浮点数的使用。我们将从一个示例开始,该示例涉及在元素周围浮动文本块。您可以在计算机上创建一个新的index.html
文件,用HTML模板填充它,并在适当的位置插入下面的代码。在本节的末尾,您可以看到一个演示最终代码的示例。
首先,我们将从一些HTML开始。将下面的代码添加到你的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中(使用元素或
到一个单独的
.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;
}
如果您保存并刷新,您将看到与您所期望的非常相似的东西:该框位于文本上方,以正常的流程。
要浮动盒子,添加float和margin-right属性到.box
规则:
.box {
float: left;
margin-right: 15px;
width: 150px;
height: 100px;
border-radius: 5px;
background-color: rgb(207, 232, 220);
padding: 1em;
}
现在,如果你保存并刷新,你会看到如下内容: 将内容向右浮动具有完全相同的效果,但相反:被浮动的元素将附着在右侧,而内容将围绕它向左缠绕。尝试将 虽然我们可以给浮动添加边距来使文本远离浮动,但我们不能给文本添加边距来使其远离浮动。这是因为浮动元素是从正常流程中取出的,而随后项的方框实际上运行在浮动后面。您可以通过对示例进行一些更改来看到这一点。 在文本的第一段中添加一个 为了使效果更容易看到,将浮动的 我们已经看到浮动从正常流中移除,并且其他元素将在其旁边显示。如果我们想要阻止随后的元素向上移动,我们需要清除它;这是通过clear属性实现的。 在前面示例中的HTML中,向浮动项下面的第二段添加一个 现在您已经知道了如何清除浮动元素后面的内容,但是让我们看看,如果您有一个高浮动和一个短段落,并在两个元素周围都有一个box ,会发生什么。 更改文档,使第一段和浮动盒子用 此外,删除原始的 你会看到,就像我们在段落中添加背景色的例子一样,背景色在浮动后面运行。 要解决这个问题,可以使用 测试你的技能:浮动 定位( 我们希望你在你的本地电脑上做以下练习。如果可能的话,从我们的GitHub repo(源代码在这里)获取0_basic-flow.html的副本,并将其作为起点。 有许多不同类型的定位可以用于HTML元素。为了在元素上激活特定类型的定位,我们使用position属性。 静态定位是每个元素的默认设置。它的意思是“将元素放到文档流中的正常位置——这里没有什么特别的。” 要看到这一点(并为以后的章节设置示例),首先在HTML中的第二个 现在在你的CSS底部添加以下规则: 如果你保存并刷新,除了第二段的背景颜色更新之外,你将看不到任何不同。这很好——正如我们之前所说,静态定位是默认行为! 注意:您现在可以在1_static-positioning.html上看到这个示例(参见源代码)。 相对定位是我们要看的第一个位置类型。这与静态定位非常相似,不同之处在于,一旦被定位的元素在正常流程中占据了位置,您就可以修改其最终位置,包括使其与页面上的其他元素重叠。继续并更新代码中的位置声明: 如果在此阶段保存并刷新,则不会看到结果有任何更改。那么如何修改元素的位置呢?您需要使用top、bottom、left和right属性,我们将在下一节中解释这些属性。 top, bottom, left和right与position一起使用,以指定将定位元素移动到的确切位置。要尝试一下,在CSS中的.定位规则中添加以下声明: 注意:这些属性的值可以采用您合理期望的任何单位:像素、mm、rems、%等。 如果你现在保存并刷新,你会得到类似这样的结果: 注意:您可以在2_relative-positioning.html上看到这个例子(参见源代码)。 绝对定位带来截然不同的结果。 让我们尝试更改代码中的位置声明,如下所示: 如果你现在保存并刷新,你应该看到这样的内容: 其次,注意元素的位置发生了变化。 注意:如果需要,可以使用 top、bottom、left和 right来调整元素的大小。尝试在定位元素上设置 注意:是的,页边距仍然影响已定位的元素。然而,外边距不会塌陷。 注意:您可以在3_absolute-positioning.html上看到这个例子(参见源代码)。 哪个元素是绝对定位元素的“包含元素( 如果没有祖先元素显式定义其position属性,那么默认情况下所有祖先元素都将具有静态位置。这样做的结果是绝对定位的元素将被包含在初始包含块( 定位元素嵌套在HTML源中的 注意:您现在可以在4_positioning-context.html中查看示例(请参阅源代码)。 所有这些绝对定位都很有趣,但我们还没有考虑到另一个功能。当元素开始重叠时,是什么决定了哪些元素出现在其他元素之上,哪些元素出现在其他元素之下?在我们目前看到的例子中,我们在定位上下文中只有一个定位元素,并且它出现在顶部,因为定位元素战胜了非定位元素。如果不止一个呢? 尝试在你的CSS中添加以下内容,使第一段也完全定位: 此时,您将看到第一段被涂成石灰色,移出文档流,并位于比原来位置高一点的位置。它也被堆叠在两个重叠的原始 你能改变堆叠顺序吗?是的,可以,通过使用z-index属性。 网页也有一个z轴:一条假想的线,从屏幕表面到你的脸(或者任何你想在屏幕前看到的东西)。 要更改堆叠顺序,请尝试在 现在你应该看到顶部的石灰段: 注意:您可以在5_z-index.html上看到一个示例(参见源代码) 现在让我们看一下固定定位。这与绝对定位完全相同,有一个关键的区别: 让我们用一个简单的例子来说明我们的意思。首先,从CSS中删除现有的 现在更新 现在我们要给出 如果您保存和刷新,您将看到标题保持固定的有趣的小效果——内容似乎在它下面滚动并消失。但请注意,一些内容最初是在标题下被剪辑的。这是因为定位标题不再出现在文档流中,所以其余的内容移动到顶部。我们可以通过把这些段落移动一点来改进这一点。我们可以通过在第一段设置一些上限来做到这一点。现在加入: 还有另一个可用的位置值,称为 例如,可以使用粘性定位,使导航条随着页面滚动,直到某一点,然后粘在页面的顶部。 CSS可能如下所示。在正常流程中, 粘性元素相对于最近的祖先具有“滚动机制”,这是由其祖先的 position属性决定的。 Test your skills: Positioning 多列布局规范为您提供了一种按列布局内容的方法,就像您在报纸上看到的那样。本文将解释如何使用此功能。 让我们探索一下如何使用多列布局——通常被称为 我们的起始文件包含一些非常简单的HTML:一个带有 带有 您创建的列具有灵活的宽度-浏览器计算出为每个列分配多少空间。 改变你的CSS使用列宽度如下: 浏览器现在会按照你指定的大小给你尽可能多的列;然后在现有列之间共享任何剩余空间。这意味着除非您的容器能被指定的宽度整除,否则您将无法获得指定的宽度。 由multicol创建的列不能单独设置样式。没有办法使一个列比其他列大,也没有办法改变单个列的背景或文本颜色。有两种方法可以更改列的显示方式: 使用上面的示例,通过添加 现在用 可以使元素跨所有列。在这种情况下,内容在引入生成元素的地方中断,然后在元素下面继续,创建一组新的列。若要使元素跨所有列,请为column-span属性指定all的值。 注意:不可能使一个元素只跨一些列。该属性只能具有 多栏布局的内容是分裂的。它本质上的行为方式与页面媒体中的内容行为相同,例如当您打印网页时。当您将内容转换为多列容器时,它会分割成列。为了让内容做到这一点,它必须分裂( 有时,这种分裂会发生在导致糟糕阅读体验的地方。在下面的例子中,我使用 为了控制这种行为,我们可以使用CSS片段规范中的属性。该规范为我们提供了控制multicol和分页媒体中内容分割的属性。例如,通过在 Test your skills: Multicol
让我们考虑一下浮动是如何工作的。设置了float
的元素(在本例中为)的左侧。在正常布局流中,任何位于浮动元素后面的内容现在都将围绕它进行换行,填充其右侧的空间,直至浮动元素的顶部。在那里,它会停止。
float
值更改为right
,并将最后一个规则集中的margin-right
替换为margin-left
,看看结果是什么。6.2.2 让浮动效果可视化
special
类,紧跟浮动框之后,然后在CSS中添加以下规则。这将给我们下面的段落一个背景颜色。.special {
background-color: rgb(148, 255, 172);
padding: 10px;
color: purple;
}
margin-right
更改为margin
,这样浮动周围就有了空间。你可以看到段落的背景在浮动框的正下方运行,如下例所示。
我们下面元素的行框被缩短了,这样文本就可以围绕浮动运行,但是由于浮动从正常流中移除,段落周围的框仍然保持全宽。6.3 清除浮动
cleared
类。然后在CSS中添加以下内容:.cleared {
clear: left;
}
你应该看到,第二段现在清除浮动元素,不再出现在它旁边。clear
属性接受以下值:
left
:清除浮动到左边的项目。right
:清除向右浮动的项目。both
:清除左边或右边的浮动项。6.4 清除浮动元素周围的盒子
6.4.1 问题
wrapper
类。
<div class="wrapper">
<div class="box">Float1div>
<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>
.cleared
类:.cleared {
clear: left;
}
再一次,这是因为浮动已经从正常流动中取出。您可能期望通过将浮动框和围绕浮动的第一段的文本包装在一起,随后的内容将从框中清除。但如上所示,事实并非如此。为了解决这个问题,标准的方法是使用display
属性创建一个块格式化上下文(BFC)。6.4.2 display: flow-root
display
属性的值flow-root
。它的存在只是为了在不使用hack的情况下创建BFC——当你使用它时,不会有意想不到的后果。.wrapper {
background-color: rgb(148, 255, 172);
padding: 10px;
color: purple;
display: flow-root;
}
6.5 测试
7、定位
Positioning
)允许您将元素从正常的文档流中取出,并使它们的行为不同,例如,通过放置在另一个的顶部或始终保持在浏览器视口中的相同位置。本文解释了不同的position值以及如何使用它们。7.1 定位介绍
定位允许我们通过覆盖正常的文档流来产生有趣的结果
。如果你想稍微改变一些盒子的位置,让它们偏离默认的流位置,给人一种有点古怪的感觉呢?定位是你的工具。或者,如果你想创建一个UI元素,它漂浮在页面的其他部分的顶部,或者无论页面滚动多少,它总是位于浏览器窗口的同一位置,该怎么办?定位使这种布局工作成为可能。7.2 静态定位
中添加一个
positioned
类:<p class="positioned">…p>
.positioned {
position: static;
background: yellow;
}
7.3 相对定位
position: relative;
top、bottom、left 和 right
top: 30px;
left: 30px;
很酷,不是吗?好吧,这可能不是你想要的。如果我们指定了top
和left
,为什么它会移动到底部和右侧?这似乎有悖常理。你需要把它想象成有一种看不见的力量在推动箱子的特定一侧,使它朝相反的方向移动。因此,例如,如果您指定top: 30px;
,就好像有一个力将推动框的顶部,使其向下移动30px。
7.4 绝对定位
设置 position: absolute
position: absolute;
首先,注意文档流中定位元素应该存在的间隙不再存在—第一个和第三个元素闭合在一起,就像它不再存在一样!在某种程度上,这是真的。绝对定位的元素不在正常的文档流中。相反,它有自己的一层,与其他东西分开。这是非常有用的:这意味着我们可以创建独立的UI功能,而不会干扰页面上其他元素的布局。例如,弹出式信息框、控制菜单、滚动面板、可以在页面上任意位置拖放的UI特性,等等。这是因为 top、bottom、left和 right在绝对定位时的行为方式不同
。它们不是根据元素在正常文档流中的相对位置来定位元素,而是指定元素与包含元素的每个边之间的距离。所以在这个例子中,我们说绝对定位的元素应该位于距“包含元素”顶部30px和左侧30px的位置。(在这种例子下,“包含元素”是初始的包含块(initial containing block)。有关更多信息,请参阅下面的部分)
top: 0; bottom: 0; left: 0; right: 0;
和margin: 0;
,看看会发生什么!然后再放回去……
定位上下文
containing element
)”?这在很大程度上取决于被定位元素的祖先元素的position
属性(参见标识包含块)。initial containing block
)中。初始的包含块具有视口的尺寸,并且也是包含元素的块。换句话说,绝对定位的元素将显示在
元素的外部,并相对于初始视口进行定位。
中,但在最终布局中,它距离页面的顶部和左边缘30px。我们可以改变定位上下文(
positioning context
),也就是说,绝对定位元素相对于哪个元素定位。这是通过在元素的一个祖先上设置定位来实现的:它嵌套在其中的一个元素上(你不能将它相对于它没有嵌套在其中的元素进行定位)。要看到这一点,将以下声明添加到你的body
规则中:position: relative;
介绍 z-index
p:nth-of-type(1) {
position: absolute;
background: lime;
top: 10px;
right: 30px;
}
.positioned
段落的下面。这是因为.positioned
的段落是源顺序中的第二个段落,并且源顺序中较晚的定位元素胜过源顺序中较早的定位元素。“z-index”是对z轴的引用
。你可能还记得以前的points 在课程中,我们讨论了网页使用水平(x轴)和垂直(y轴)坐标,以制定出定位的东西,如背景图像和投影偏移。对于从左到右运行的语言,(0,0)位于页面(或元素)的左上角,x轴和y轴在页面的右侧和下方运行。z-index
值影响定位元素在该轴上的位置;正值使它们在堆栈中向上移动,负值使它们在堆栈中向下移动。默认情况下,定位元素的z-index
都是auto
,值为0
。p:nth-of-type(1)
规则中添加以下声明:z-index: 1;
注意z-index
只接受无单位的索引值;你不能指定你想要一个元素在z轴上23像素——这是行不通的。较高的值将高于较低的值,这取决于你使用什么值。使用2或3的值会产生与300或40000相同的效果。
7.5 固定定位
尽管绝对定位在相对于其最接近的定位祖先(初始包含块如果没有一个)的位置上修复了一个元素,但固定定位(fixed positioning)通常会修复相对于viewport可见部分的元素
。(如果元素的祖先之一是一个固定的块,因为它的转换属性有一个none
以外的值,那么这就会发生例外。)这意味着您可以创建固定的有用的UI项,比如持久的导航菜单,不管页面滚动多少,都是可见的。p:nth-of-type(1)
和.positioned
的规则。body
规则,移除position: relative;
声明并增加固定的高度,像这样:body {
width: 500px;
height: 1400px;
margin: 0 auto;
}
h1
元素position: fixed;
,并把它放置在viewport的顶部。为您的CSS添加以下规则:h1 {
position: fixed;
top: 0;
width: 500px;
margin-top: 0;
background: white;
padding: 10px;
}
top: 0;
需要让它粘在屏幕的顶部。我们给标题与内容列相同的宽度,然后是一个白色的背景和一些填充和边缘,这样内容就不能在它下面看到。p:nth-of-type(1) {
margin-top: 60px;
}
7.6 粘性定位
position: sticky
,它比其他位置值更新一些。这基本上是相对位置和固定位置的混合。它允许一个定位的元素表现得像它的相对定位,直到它被滚动到一个特定的阈值(例如,从viewport顶部10px),之后它变得固定。基本示例
.positioned {
position: sticky;
top: 30px;
left: 30px;
}
滚动索引
position: sticky
的一个有趣且常见的用法是创建一个滚动的索引页面,其中不同的标题在到达页面顶部时粘在页面顶部。这样一个例子的标记可能看起来像这样:<h1>Sticky positioningh1>
<dl>
<dt>Adt>
<dd>Appledd>
<dd>Antdd>
<dd>Altimeterdd>
<dd>Airplanedd>
<dt>Bdt>
<dd>Birddd>
<dd>Buzzarddd>
<dd>Beedd>
<dd>Bananadd>
<dd>Beanstalkdd>
<dt>Cdt>
<dd>Calculatordd>
<dd>Canedd>
<dd>Cameradd>
<dd>Cameldd>
<dt>Ddt>
<dd>Duckdd>
<dd>Dimedd>
<dd>Dipstickdd>
<dd>Dronedd>
<dt>Edt>
<dd>Eggdd>
<dd>Elephantdd>
<dd>Egretdd>
dl>
元素将随着内容滚动。当我们将
position: sticky
添加到元素中,并将
top
值设置为0
时,支持浏览器将在到达该位置时将标题粘贴到视口的顶部。每个后续的标题将替换前一个,因为它向上滚动到该位置。dt {
background-color: black;
color: white;
padding: 10px;
position: sticky;
top: 0;
left: 0;
margin: 1em 0;
}
7.7 测试
8、多列布局
8.1 一个基本的例子
multicol
。您可以下载multicol起始点文件并将CSS添加到适当的位置。在本节的底部,您可以看到一个示例,说明最终代码应该是什么样子。三栏布局
container
类的包装器,其中包含一个标题和一些段落。container
类的column-count
属性以一个数字作为其值,并创建该数量的列。如果你将以下CSS添加到样式表中并重新加载页面,你将得到三列:
.container {
column-count: 3;
}
设置 column-width
.container {
column-width: 200px;
}
8.2 样式化列
column-gap
属性来更改间距的大小。您可以使用不同的值-该属性接受任何长度单位。column-rule
在列之间添加一条规则。与您在前几课中遇到的border属性类似,column-rule是column-rule-color、column-rule-style和column-rule-width的简写,接受与border
相同的值。.container {
column-count: 3;
column-gap: 20px;
column-rule: 4px dotted rgb(79, 185, 227);
}
8.3 跨列
none
(默认值)或all
的值。8.4 列与内容片断
break
)。分裂的盒子
multicol
来布局一系列的框,每个框都有一个标题和一些文本。如果列在标题和文本之间分割,则标题和文本将分开。<div class="container">
<div class="card">
<h2>I am the headingh2>
<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.
p>
div>
<div class="card">
<h2>I am the headingh2>
<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.
p>
div>
<div class="card">
<h2>I am the headingh2>
<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.
p>
div>
<div class="card">
<h2>I am the headingh2>
<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.
p>
div>
<div class="card">
<h2>I am the headingh2>
<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.
p>
div>
<div class="card">
<h2>I am the headingh2>
<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.
p>
div>
<div class="card">
<h2>I am the headingh2>
<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.
p>
div>
div>
.container {
column-width: 250px;
column-gap: 20px;
}
.card {
background-color: rgb(207, 232, 220);
border: 2px solid rgb(79, 185, 227);
padding: 10px;
margin: 0 0 1em 0;
}
设置 break-inside
.card
的规则中添加属性break-inside,其值为avoid
。这是标题和文本的容器,所以我们不希望它碎片化。.card {
break-inside: avoid;
background-color: rgb(207, 232, 220);
border: 2px solid rgb(79, 185, 227);
padding: 10px;
margin: 0 0 1em 0;
}
8.5 测试