定位的整个想法是允许我们覆盖上面描述的基本文档流行为,以产生有趣的效果。如果你想稍微改变布局中一些盒子的位置,使它们的默认布局流程位置稍微有点古怪,不舒服的感觉呢?定位是你的工具。或者,如果您想要创建一个浮动在页面其他部分顶部的UI元素,并且/或者始终停留在浏览器窗口内的相同位置,无论页面滚动多少?定位使这种布局工作成为可能。

有许多不同类型的定位,您可以对HTML元素生效。要使某个元素上的特定类型的定位,我们使用[position](https://developer.mozilla.org/zh-CN/docs/Web/CSS/position)属性。

静态定位

静态定位是每个元素获取的默认值——它只是意味着“将元素放入它在文档布局流中的正常位置 ——这里没有什么特别的。

为了演示这一点,并为以后的部分设置示例,首先在HTML中添加一个positionedclass 到第二个``

  1. <p class="positioned"> ... </p>

Copy to Clipboard

现在,将以下规则添加到CSS的底部:

  1. .positioned {
  2. position: static;
  3. background: yellow;
  4. }

Copy to Clipboard

如果现在保存和刷新,除了第2段的更新的背景颜色,根本没有差别。这很好——正如我们之前所说,静态定位是默认行为!

注意:你可以在 1_static-positioning.html 查看这个例子 (see source code)。

相对定位

相对定位是我们将要看的第一个位置类型。 它与静态定位非常相似,占据在正常的文档流中,除了你仍然可以修改它的最终位置,包括让它与页面上的其他元素重叠。 让我们继续并更新代码中的 position 属性:

  1. position: relative;

Copy to Clipboard

如果您在此阶段保存并刷新,则结果根本不会发生变化。那么如何修改元素的位置呢? 您需要使用[top](https://developer.mozilla.org/zh-CN/docs/Web/CSS/top)[bottom](https://developer.mozilla.org/zh-CN/docs/Web/CSS/bottom)[left](https://developer.mozilla.org/zh-CN/docs/Web/CSS/left)[right](https://developer.mozilla.org/zh-CN/docs/Web/CSS/right)属性 ,我们将在下一节中解释。

介绍 top, bottom, left, right

[top](https://developer.mozilla.org/zh-CN/docs/Web/CSS/top), [bottom](https://developer.mozilla.org/zh-CN/docs/Web/CSS/bottom), [left](https://developer.mozilla.org/zh-CN/docs/Web/CSS/left), 和 [right](https://developer.mozilla.org/zh-CN/docs/Web/CSS/right) 来精确指定要将定位元素移动到的位置。 要尝试这样做,请在CSS中的 .positioned 规则中添加以下声明:

  1. top: 30px;
  2. left: 30px;

注意:这些属性的值可以采用逻辑上期望的任何单位 ——px,mm,rems,%等。

如果你现在保存和刷新,你会得到一个这样的结果:
Snipaste_2021-06-15_18-19-36.png
酷,是吗? 好吧,所以这个结果这可能不是你期待的——为什么它移动到底部和右边,但我们指定顶部和左边? 听起来不合逻辑,但这只是相对定位工作的方式——你需要考虑一个看不见的力,推动定位的盒子的一侧,移动它的相反方向。 所以例如,如果你指定 top: 30px;一个力推动框的顶部,使它向下移动30px。

注意: 你可以在 2_relative-positioning.html 查看这个例子 (see source code)。

绝对定位

绝对定位带来了非常不同的结果。让我们尝试改变代码中的位置声明如下:

  1. position: absolute;

如果你现在保存和刷新,你应该看到这样:
10.png

首先,请注意,定位的元素应该在文档流中的间隙不再存在——第一和第三元素已经靠在一起,就像第二个元素不再存在!好吧,在某种程度上,这是真的。绝对定位的元素不再存在于正常文档布局流中。相反,它坐在它自己的层独立于一切。这是非常有用的:这意味着我们可以创建不干扰页面上其他元素的位置的隔离的UI功能 。例如,弹出信息框和控制菜单;翻转面板;可以在页面上的任何地方拖放的UI功能……

第二,注意元素的位置已经改变——这是因为[top](https://developer.mozilla.org/zh-CN/docs/Web/CSS/top)[bottom](https://developer.mozilla.org/zh-CN/docs/Web/CSS/bottom)[left](https://developer.mozilla.org/zh-CN/docs/Web/CSS/left)[right](https://developer.mozilla.org/zh-CN/docs/Web/CSS/right)以不同的方式在绝对定位。 它们指定元素应距离每个包含元素的边的距离,而不是指定元素应该移入的方向。 所以在这种情况下,我们说的绝对定位元素应该位于从“包含元素”的顶部30px,从左边30px。

注意:如果需要,您可以使用[top](https://developer.mozilla.org/zh-CN/docs/Web/CSS/top)[bottom](https://developer.mozilla.org/zh-CN/docs/Web/CSS/bottom)[left](https://developer.mozilla.org/zh-CN/docs/Web/CSS/left)[right](https://developer.mozilla.org/zh-CN/docs/Web/CSS/right) 调整元素大小。 尝试设置 top: 0; bottom: 0; left: 0; right: 0;margin: 0; 对你定位的元素,看看会发生什么! 之后再回来

注意:是的,margins 仍会影响定位的元素。 然而margin collapsing不会。

注意:你可以在3_absolute-positioning.html 查看这个例子(see source code)。

定位上下文

哪个元素是绝对定位元素的“包含元素“?这取决于绝对定位元素的父元素的position属性。(参见 Identifying the containing block).

如果所有的父元素都没有显式地定义position属性,那么所有的父元素默认情况下position属性都是static。结果,绝对定位元素会被包含在初始块容器中。这个初始块容器有着和浏览器视口一样的尺寸,并且元素也被包含在这个容器里面。简单来说,绝对定位元素会被放在元素的外面,并且根据浏览器视口来定位。

绝对定位元素在HTML源代码中,是被放在中的,但是在最终的布局里面,它离页面(而不是)的左边界、上边界有30px的距离。我们可以改变定位上下文 —— 绝对定位的元素的相对位置元素。通过设置其中一个父元素的定位属性 —— 也就是包含绝对定位元素的那个元素(如果要设置绝对定位元素的相对元素,那么这个元素一定要包含绝对定位元素)。 为了演示这一点,将以下声明添加到您的body规则中:

  1. position: relative;

应该得到以下结果:
11.png

定位的元素现在相对于``元素。

注意:你可以在这里看到这个例子 4_positioning-context.html (see source code).

介绍 z-index

所有这些绝对定位很有趣,但还有另一件事我们还没有考虑到 ——当元素开始重叠,什么决定哪些元素出现在其他元素的顶部? 在我们已经看到的示例中,我们在定位上下文中只有一个定位的元素,它出现在顶部,因为定位的元素胜过未定位的元素。 当我们有不止一个的时候呢?

尝试添加以下到您的CSS,使第一段也是绝对定位:

  1. p:nth-of-type(1) {
  2. position: absolute;
  3. background: lime;
  4. top: 10px;
  5. right: 30px;
  6. }

此时,您将看到第一段的颜色为绿色,移出文档流程,并位于原始位置上方一点。它也堆叠在原始的 .positioned 段落下,其中两个重叠。这是因为 .positioned 段落是源顺序(HTML标记)中的第二个段落,并且源顺序中后定位的元素将赢得先定位的元素。

您可以更改堆叠顺序吗?是的,您可以使用[z-index](https://developer.mozilla.org/zh-CN/docs/Web/CSS/z-index)属性。 “z-index”是对z轴的参考。你可以从源代码中的上一点回想一下,我们使用水平(x轴)和垂直(y轴)坐标来讨论网页,以确定像背景图像和阴影偏移之类的东西的位置。 (0,0)位于页面(或元素)的左上角,x和y轴跨页面向右和向下(适合从左到右的语言,无论如何)。

网页也有一个z轴:一条从屏幕表面到你的脸(或者在屏幕前面你喜欢的任何其他东西)的虚线。[z-index](https://developer.mozilla.org/zh-CN/docs/Web/CSS/z-index) 值影响定位元素位于该轴上的位置;正值将它们移动到堆栈上方,负值将它们向下移动到堆栈中。默认情况下,定位的元素都具有z-index为auto,实际上为0。

要更改堆叠顺序,请尝试将以下声明添加到 p:nth-of-type(1) 规则中:

  1. z-index: 1;

你现在应该可以看到完成的例子:
12.png

请注意,z-index只接受无单位索引值;你不能指定你想要一个元素是Z轴上23像素—— 它不这样工作。 较高的值将高于较低的值,这取决于您使用的值。 使用2和3将产生与300和40000相同的效果。

注意:你可以在这里看到这个例子 5_z-index.html (see source code).

固定定位

还有一种类型的定位覆盖——fixed。 这与绝对定位的工作方式完全相同,只有一个主要区别:绝对定位固定元素是相对于 `` 元素或其最近的定位祖先,而固定定位固定元素则是相对于浏览器视口本身。 这意味着您可以创建固定的有用的UI项目,如持久导航菜单。

让我们举一个简单的例子来说明我们的意思。首先,从CSS中删除现有的 p:nth-of-type(1).positioned 规则。

现在,更新 body 规则以删除position: relative; 声明并添加固定高度,如此:

  1. body {
  2. width: 500px;
  3. height: 1400px;
  4. margin: 0 auto;
  5. }

现在我们要给 (en-US)元素 position: fixed;,并让它坐在视口的顶部中心。将以下规则添加到CSS:

  1. h1 {
  2. position: fixed;
  3. top: 0;
  4. width: 500px;
  5. margin: 0 auto;
  6. background: white;
  7. padding: 10px;
  8. }

top: 0;是要使它贴在屏幕的顶部;我们然后给出标题与内容列相同的宽度,并使用可靠的老技巧 margin: 0 auto; 使它居中。 然后我们给它一个白色背景和一些内边距,所以内容将不会在它下面可见。

如果您现在保存并刷新,您会看到一个有趣的小效果,标题保持固定,内容显示向上滚动并消失在其下。 但是我们可以改进这一点——目前标题下面挡住一些内容的开头。这是因为定位的标题不再出现在文档流中,所以其他内容向上移动到顶部。 我们要把它向下移动一点;我们可以通过在第一段设置一些顶部边距来做到这一点。添加:

  1. p:nth-of-type(1) {
  2. margin-top: 60px;
  3. }

你现在应该看到完成的例子:
13.png

注意:你可以在这里看到这个例子6_fixed-positioning.html (see source code).

position: sticky

还有一个可用的位置值称为 position: sticky,比起其他位置值要新一些。它基本上是相对位置和固定位置的混合体,它允许被定位的元素表现得像相对定位一样,直到它滚动到某个阈值点(例如,从视口顶部起10像素)为止,此后它就变得固定了。例如,它可用于使导航栏随页面滚动直到特定点,然后粘贴在页面顶部。

  1. .positioned {
  2. position: sticky;
  3. top: 30px;
  4. left: 30px;
  5. }

position: sticky 的另一种有趣且常用的用法,是创建一个滚动索引页面。在此页面上,不同的标题会停留在页面顶部。这样的示例的标记可能如下所示:

  1. <h1>Sticky positioning</h1>
  2. <dl>
  3. <dt>A</dt>
  4. <dd>Apple</dd>
  5. <dd>Ant</dd>
  6. <dd>Altimeter</dd>
  7. <dd>Airplane</dd>
  8. <dt>B</dt>
  9. <dd>Bird</dd>
  10. <dd>Buzzard</dd>
  11. <dd>Bee</dd>
  12. <dd>Banana</dd>
  13. <dd>Beanstalk</dd>
  14. <dt>C</dt>
  15. <dd>Calculator</dd>
  16. <dd>Cane</dd>
  17. <dd>Camera</dd>
  18. <dd>Camel</dd>
  19. <dt>D</dt>
  20. <dd>Duck</dd>
  21. <dd>Dime</dd>
  22. <dd>Dipstick</dd>
  23. <dd>Drone</dd>
  24. <dt>E</dt>
  25. <dd>Egg</dd>
  26. <dd>Elephant</dd>
  27. <dd>Egret</dd>
  28. </dl>

CSS可能如下所示。在正常布局流中,[](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/dt)元素将随内容滚动。当我们在[](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/dt)元素上添加position: sticky,并将[top](https://developer.mozilla.org/zh-CN/docs/Web/CSS/top)的值设置为0,当标题滚动到视口的顶部时,支持此属性的浏览器会将标题粘贴到那个位置。随后,每个后续标题将替换前一个标题,直到它向上滚动到该位置。

  1. dt {
  2. background-color: black;
  3. color: white;
  4. padding: 10px;
  5. position: sticky;
  6. top: 0;
  7. left: 0;
  8. margin: 1em 0;
  9. }