定位

定位允许你将元素从正常文档流中取出,并使它们表现不同,例如,通过相互叠放或始终保持在浏览器视口内的同一位置。本文介绍了不同的 position 值以及如何使用它们。

¥Positioning allows you to take elements out of normal document flow and make them behave differently, for example, by sitting on top of one another or by always remaining in the same place inside the browser viewport. This article explains the different position values and how to use them.

先决条件: HTML 基础知识(研究 HTML 简介),以及 CSS 如何工作的想法(研究 CSS 简介)。
目标: 了解 CSS 定位的工作原理。

我们希望你在本地计算机上进行以下练习。如果可能,请从我们的 GitHub 存储库 (源代码在这里) 获取 0_basic-flow.html 的副本,并将其用作起点。

¥We'd like you to do the following exercises on your local computer. If possible, grab a copy of 0_basic-flow.html from our GitHub repo (source code here) and use that as a starting point.

介绍定位

¥Introducing positioning

定位允许我们通过覆盖正常的文档流来产生有趣的结果。如果你想稍微改变一些框的默认流动位置,以给人一种稍微古怪、痛苦的感觉,该怎么办?定位是你的工具。或者,如果你想创建一个浮动在页面其他部分顶部和/或无论页面滚动多少都始终位于浏览器窗口内同一位置的 UI 元素,该怎么办?定位使这种布局工作成为可能。

¥Positioning allows us to produce interesting results by overriding normal document flow. What if you want to slightly alter the position of some boxes from their default flow position to give a slightly quirky, distressed feel? Positioning is your tool. Or what if you want to create a UI element that floats over the top of other parts of the page and/or always sits in the same place inside the browser window no matter how much the page is scrolled? Positioning makes such layout work possible.

你可以对 HTML 元素实现多种不同类型的定位。为了在元素上激活特定类型的定位,我们使用 position 属性。

¥There are a number of different types of positioning that you can put into effect on HTML elements. To make a specific type of positioning active on an element, we use the position property.

静态定位

¥Static positioning

静态定位是每个元素的默认定位。它只是意味着 "将元素置于文档流中的正常位置 - 这里没有什么特别的地方。"

¥Static positioning is the default that every element gets. It just means "put the element into its normal position in the document flow — nothing special to see here."

要查看此内容(并为以后的部分设置示例),请首先将 classpositioned 添加到 HTML 中的第二个 <p>

¥To see this (and get your example set up for future sections) first add a class of positioned to the second <p> in the HTML:

html
<p class="positioned"></p>

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

¥Now add the following rule to the bottom of your CSS:

css
.positioned {
  position: static;
  background: yellow;
}

如果保存并刷新,除了第二段的背景颜色更新外,你将看不到任何差异。这很好 - 正如我们之前所说,静态定位是默认行为!

¥If you save and refresh, you'll see no difference at all, except for the updated background color of the 2nd paragraph. This is fine — as we said before, static positioning is the default behavior!

注意:你可以在 1_static-positioning.html (查看源代码) 实时查看该示例。

¥Note: You can see the example at this point live at 1_static-positioning.html (see source code).

相对定位

¥Relative positioning

相对定位是我们要讨论的第一个位置类型。这与静态定位非常相似,只不过一旦定位的元素在正常流程中占据了位置,你就可以修改其最终位置,包括使其与页面上的其他元素重叠。继续更新代码中的 position 声明:

¥Relative positioning is the first position type we'll take a look at. This is very similar to static positioning, except that once the positioned element has taken its place in the normal flow, you can then modify its final position, including making it overlap other elements on the page. Go ahead and update the position declaration in your code:

css
position: relative;

如果你在此阶段保存并刷新,你将不会看到结果发生任何变化。那么如何修改元素的位置呢?你需要使用 topbottomleftright 属性,我们将在下一节中解释这些属性。

¥If you save and refresh at this stage, you won't see a change in the result at all. So how do you modify the element's position? You need to use the top, bottom, left, and right properties, which we'll explain in the next section.

介绍顶部、底部、左侧和右侧

¥Introducing top, bottom, left, and right

topbottomleftrightposition 一起使用来准确指定将定位元素移动到的位置。要尝试此操作,请将以下声明添加到 CSS 中的 .positioned 规则中:

¥top, bottom, left, and right are used alongside position to specify exactly where to move the positioned element to. To try this out, add the following declarations to the .positioned rule in your CSS:

css
top: 30px;
left: 30px;

注意:这些属性的值可以采用你合理期望的任何 units:像素、mm、rems、% 等

¥Note: The values of these properties can take any units you'd reasonably expect: pixels, mm, rems, %, etc.

如果你现在保存并刷新,你将得到如下结果:

¥If you now save and refresh, you'll get a result something like this:

html
<h1>Relative positioning</h1>

<p>
  I am a basic block level element. My adjacent block level elements sit on new
  lines below me.
</p>

<p class="positioned">
  By default we span 100% of the width of our parent element, and we are as tall
  as our child content. Our total width and height is our content + padding +
  border width/height.
</p>

<p>
  We are separated by our margins. Because of margin collapsing, we are
  separated by the width of one of our margins, not both.
</p>

<p>
  Inline elements <span>like this one</span> and <span>this one</span> sit on
  the same line as one another, and adjacent text nodes, if there is space on
  the same line. Overflowing inline elements
  <span>wrap onto a new line if possible — like this one containing text</span>,
  or just go on to a new line if not, much like this image will do:
  <img src="long.jpg" alt="snippet of cloth" />
</p>
css
body {
  width: 500px;
  margin: 0 auto;
}

p {
  background: aqua;
  border: 3px solid blue;
  padding: 10px;
  margin: 10px;
}

span {
  background: red;
  border: 1px solid black;
}

.positioned {
  position: relative;
  background: yellow;
  top: 30px;
  left: 30px;
}

很酷吧?好吧,这可能不是你所期望的。如果我们指定了顶部和左侧,为什么它会移动到底部和右侧?这可能看起来违反直觉。你需要将其视为好像有一种看不见的力推动定位框的指定侧,使其向相反方向移动。因此,例如,如果你指定 top: 30px;,就好像有一个力会推动框的顶部,导致它向下移动 30px。

¥Cool, huh? Ok, so this probably wasn't what you were expecting. Why has it moved to the bottom and to the right if we specified top and left? This may seem counterintuitive. You need to think of it as if there's an invisible force that pushes the specified side of the positioned box, moving it in the opposite direction. So, for example, if you specify top: 30px;, it's as if a force will push the top of the box, causing it to move downwards by 30px.

注意:你可以在 2_relative-positioning.html (查看源代码) 实时查看该示例。

¥Note: You can see the example at this point live at 2_relative-positioning.html (see source code).

绝对定位

¥Absolute positioning

绝对定位会带来截然不同的结果。

¥Absolute positioning brings very different results.

设置位置:absolute

¥Setting position: absolute

让我们尝试更改代码中的位置声明,如下所示:

¥Let's try changing the position declaration in your code as follows:

css
position: absolute;

如果你现在保存并刷新,你应该看到类似这样的内容:

¥If you now save and refresh, you should see something like so:

html
<h1>Absolute positioning</h1>

<p>
  I am a basic block level element. My adjacent block level elements sit on new
  lines below me.
</p>

<p class="positioned">
  By default we span 100% of the width of our parent element, and we are as tall
  as our child content. Our total width and height is our content + padding +
  border width/height.
</p>

<p>
  We are separated by our margins. Because of margin collapsing, we are
  separated by the width of one of our margins, not both.
</p>

<p>
  inline elements <span>like this one</span> and <span>this one</span> sit on
  the same line as one another, and adjacent text nodes, if there is space on
  the same line. Overflowing inline elements
  <span>wrap onto a new line if possible — like this one containing text</span>,
  or just go on to a new line if not, much like this image will do:
  <img src="long.jpg" alt="snippet of cloth" />
</p>
css
body {
  width: 500px;
  margin: 0 auto;
}

p {
  background: aqua;
  border: 3px solid blue;
  padding: 10px;
  margin: 10px;
}

span {
  background: red;
  border: 1px solid black;
}

.positioned {
  position: absolute;
  background: yellow;
  top: 30px;
  left: 30px;
}

首先,请注意,文档流中定位元素应位于的间隙已不复存在 - 第一个和第三个元素已闭合在一起,就像不再存在一样!嗯,在某种程度上,这是真的。正常文档流中不再存在绝对定位的元素。相反,它位于与其他所有内容分开的自己的层上。这非常有用:这意味着我们可以创建独立的 UI 功能,不会干扰页面上其他元素的布局。例如,弹出信息框、控制菜单、翻转面板、可以拖放到页面上任何位置的 UI 功能等等。

¥First of all, note that the gap where the positioned element should be in the document flow is no longer there — the first and third elements have closed together like it no longer exists! Well, in a way, this is true. An absolutely positioned element no longer exists in the normal document flow. Instead, it sits on its own layer separate from everything else. This is very useful: it means that we can create isolated UI features that don't interfere with the layout of other elements on the page. For example, popup information boxes, control menus, rollover panels, UI features that can be dragged and dropped anywhere on the page, and so on.

其次,请注意元素的位置已更改。这是因为 topbottomleftright 对于绝对定位的行为方式不同。它们不是根据元素在正常文档流中的相对位置来定位元素,而是指定元素距包含元素各边的距离。所以在这种情况下,我们说绝对定位的元素应该距离 "含有元素" 顶部 30 像素,距离左侧 30 像素。(在本例中,"含有元素" 是初始包含块。有关更多信息,请参阅下面的部分)

¥Second, notice that the position of the element has changed. This is because top, bottom, left, and right behave in a different way with absolute positioning. Rather than positioning the element based on its relative position within the normal document flow, they specify the distance the element should be from each of the containing element's sides. So in this case, we are saying that the absolutely positioned element should sit 30px from the top of the "containing element" and 30px from the left. (In this case, the "containing element" is the initial containing block. See the section below for more information)

注意:如果需要,你可以使用 topbottomleftright 来调整元素的大小。尝试在定位的元素上设置 top: 0; bottom: 0; left: 0; right: 0;margin: 0;,看看会发生什么!之后再把它放回去...

¥Note: You can use top, bottom, left, and right to resize elements if you need to. Try setting top: 0; bottom: 0; left: 0; right: 0; and margin: 0; on your positioned elements and see what happens! Put it back again afterwards…

注意:是的,边距仍然影响定位的元素。然而,利润率的崩溃却没有。

¥Note: Yes, margins still affect positioned elements. Margin collapsing doesn't, however.

注意:你可以在 3_absolute-positioning.html (查看源代码) 实时查看该示例。

¥Note: You can see the example at this point live at 3_absolute-positioning.html (see source code).

定位上下文

¥Positioning contexts

绝对定位元素的 "含有元素" 是哪个元素?这在很大程度上取决于定位元素的祖级的位置属性(参见 识别包含块)。

¥Which element is the "containing element" of an absolutely positioned element? This is very much dependent on the position property of the ancestors of the positioned element (See Identifying the containing block).

如果没有显式定义祖级元素的位置属性,则默认情况下所有祖级元素都将具有静态位置。其结果是绝对定位的元素将包含在初始包含块中。初始包含块具有视口的尺寸,也是包含 <html> 元素的块。换句话说,绝对定位的元素将显示在 <html> 元素之外,并相对于初始视口定位。

¥If no ancestor elements have their position property explicitly defined, then by default all ancestor elements will have a static position. The result of this is the absolutely positioned element will be contained in the initial containing block. The initial containing block has the dimensions of the viewport and is also the block that contains the <html> element. In other words, the absolutely positioned element will be displayed outside of the <html> element and be positioned relative to the initial viewport.

定位元素嵌套在 HTML 源代码中的 <body> 内,但在最终布局中,它距页面顶部和左边缘 30px。我们可以改变定位上下文,即绝对定位的元素相对于哪个元素定位。这是通过在元素的祖级之一上设置定位来完成的:到它嵌套在其中的元素之一(你不能相对于它未嵌套在其中的元素定位它)。要查看这一点,请将以下声明添加到你的 body 规则中:

¥The positioned element is nested inside the <body> in the HTML source, but in the final layout it's 30px away from the top and the left edges of the page. We can change the positioning context, that is, which element the absolutely positioned element is positioned relative to. This is done by setting positioning on one of the element's ancestors: to one of the elements it's nested inside of (you can't position it relative to an element it's not nested inside of). To see this, add the following declaration to your body rule:

css
position: relative;

这应该给出以下结果:

¥This should give the following result:

html
<h1>Positioning context</h1>

<p>
  I am a basic block level element. My adjacent block level elements sit on new
  lines below me.
</p>

<p class="positioned">
  Now I'm absolutely positioned relative to the
  <code>&lt;body&gt;</code> element, not the <code>&lt;html&gt;</code> element!
</p>

<p>
  We are separated by our margins. Because of margin collapsing, we are
  separated by the width of one of our margins, not both.
</p>

<p>
  inline elements <span>like this one</span> and <span>this one</span> sit on
  the same line as one another, and adjacent text nodes, if there is space on
  the same line. Overflowing inline elements
  <span>wrap onto a new line if possible — like this one containing text</span>,
  or just go on to a new line if not, much like this image will do:
  <img src="long.jpg" alt="snippet of cloth" />
</p>
css
body {
  width: 500px;
  margin: 0 auto;
  position: relative;
}

p {
  background: aqua;
  border: 3px solid blue;
  padding: 10px;
  margin: 10px;
}

span {
  background: red;
  border: 1px solid black;
}

.positioned {
  position: absolute;
  background: yellow;
  top: 30px;
  left: 30px;
}

定位的元素现在相对于 <body> 元素定位。

¥The positioned element now sits relative to the <body> element.

注意:你可以在 4_positioning-context.html (查看源代码) 实时查看该示例。

¥Note: You can see the example at this point live at 4_positioning-context.html (see source code).

引入 z 索引

¥Introducing z-index

所有这些绝对定位都很有趣,但还有另一个功能我们尚未考虑。当元素开始重叠时,什么决定哪些元素出现在其他元素之上以及哪些元素出现在其他元素之下?在我们到目前为止看到的示例中,定位上下文中只有一个定位元素,并且它出现在顶部,因为定位元素胜过非定位元素。当我们有多个时怎么办?

¥All this absolute positioning is good fun, but there's another feature we haven't considered yet. When elements start to overlap, what determines which elements appear over others and which elements appear under others? In the example we've seen so far, we only have one positioned element in the positioning context, and it appears on the top since positioned elements win over non-positioned elements. What about when we have more than one?

尝试将以下内容添加到 CSS 中,以使第一段也绝对定位:

¥Try adding the following to your CSS to make the first paragraph absolutely positioned too:

css
p:nth-of-type(1) {
  position: absolute;
  background: lime;
  top: 10px;
  right: 30px;
}

此时,你将看到第一段呈石灰色,已移出文档流,并且位置比原来的位置稍靠上方。它也堆叠在原始 .positioned 段落下方,两者重叠。这是因为 .positioned 段落是源顺序中的第二段,并且源顺序中较晚的定位元素胜过源顺序中较早的定位元素。

¥At this point you'll see the first paragraph colored lime, moved out of the document flow, and positioned a bit above from where it originally was. It's also stacked below the original .positioned paragraph where the two overlap. This is because the .positioned paragraph is the second paragraph in the source order, and positioned elements later in the source order win over positioned elements earlier in the source order.

你可以更改堆叠顺序吗?是的,你可以通过使用 z-index 属性。"z-index" 是 z 轴的参考。你可能还记得在课程的前面部分,我们讨论了使用水平(x 轴)和垂直(y 轴)坐标来计算背景图片和投影偏移等内容的位置的网页。对于从左到右运行的语言,(0,0) 位于页面(或元素)的左上角,x 轴和 y 轴穿过页面的右侧和下方。

¥Can you change the stacking order? Yes, you can, by using the z-index property. "z-index" is a reference to the z-axis. You may recall from previous points in the course where we discussed web pages using horizontal (x-axis) and vertical (y-axis) coordinates to work out positioning for things like background images and drop shadow offsets. For languages that run left to right, (0,0) is at the top left of the page (or element), and the x- and y-axes run across to the right and down the page.

网页也有 z 轴:从屏幕表面延伸到你的脸部(或你喜欢在屏幕前面的任何其他对象)的假想线。z-index 值影响定位元素在该轴上的位置;正值将它们移动到堆栈的较高位置,负值将它们移动到堆栈的较低位置。默认情况下,定位元素的 z-index 均为 auto,实际上为 0。

¥Web pages also have a z-axis: an imaginary line that runs from the surface of your screen towards your face (or whatever else you like to have in front of the screen). z-index values affect where positioned elements sit on that axis; positive values move them higher up the stack, negative values move them lower down the stack. By default, positioned elements all have a z-index of auto, which is effectively 0.

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

¥To change the stacking order, try adding the following declaration to your p:nth-of-type(1) rule:

css
z-index: 1;

你现在应该看到顶部的石灰段落:

¥You should now see the lime paragraph on top:

html
<h1>z-index</h1>

<p>
  I am a basic block level element. My adjacent block level elements sit on new
  lines below me.
</p>

<p class="positioned">
  Now I'm absolutely positioned relative to the
  <code>&lt;body&gt;</code> element, not the <code>&lt;html&gt;</code> element!
</p>

<p>
  We are separated by our margins. Because of margin collapsing, we are
  separated by the width of one of our margins, not both.
</p>

<p>
  inline elements <span>like this one</span> and <span>this one</span> sit on
  the same line as one another, and adjacent text nodes, if there is space on
  the same line. Overflowing inline elements
  <span>wrap onto a new line if possible — like this one containing text</span>,
  or just go on to a new line if not, much like this image will do:
  <img src="long.jpg" alt="snippet of cloth" />
</p>
css
body {
  width: 500px;
  margin: 0 auto;
  position: relative;
}

p {
  background: aqua;
  border: 3px solid blue;
  padding: 10px;
  margin: 10px;
}

span {
  background: red;
  border: 1px solid black;
}

.positioned {
  position: absolute;
  background: yellow;
  top: 30px;
  left: 30px;
}

p:nth-of-type(1) {
  position: absolute;
  background: lime;
  top: 10px;
  right: 30px;
  z-index: 1;
}

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

¥Note that z-index only accepts unitless index values; you can't specify that you want one element to be 23 pixels up the Z-axis — it doesn't work like that. Higher values will go above lower values and it's up to you what values you use. Using values of 2 or 3 would give the same effect as values of 300 or 40000.

注意:你可以在 5_z-index.html (查看源代码) 观看直播示例。

¥Note: You can see an example for this live at 5_z-index.html (see source code).

固定定位

¥Fixed positioning

现在让我们看看固定定位。这与绝对定位的工作方式完全相同,但有一个关键区别:绝对定位将元素相对于其最近的定位祖级(如果没有的话,则为初始包含块)固定在适当的位置,而固定定位通常将元素相对于视口的可见部分固定在适当的位置。(如果元素的祖级之一是固定包含块,则出现例外情况,因为它的 变换属性 具有除“无”以外的值。)这意味着你可以创建固定在适当位置的有用 UI 项目,例如无论页面滚动多少都始终可见的持久导航菜单。

¥Let's now look at fixed positioning. This works in exactly the same way as absolute positioning, with one key difference: whereas absolute positioning fixes an element in place relative to its nearest positioned ancestor (the initial containing block if there isn't one), fixed positioning usually fixes an element in place relative to the visible portion of the viewport. (An exception to this occurs if one of the element's ancestors is a fixed containing block because its transform property has a value other than none.) This means that you can create useful UI items that are fixed in place, like persistent navigation menus that are always visible no matter how much the page scrolls.

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

¥Let's put together a simple example to show what we mean. First of all, delete the existing p:nth-of-type(1) and .positioned rules from your CSS.

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

¥Now update the body rule to remove the position: relative; declaration and add a fixed height, like so:

css
body {
  width: 500px;
  height: 1400px;
  margin: 0 auto;
}

现在我们要给 h1 元素 position: fixed; 并让它位于视口的顶部。将以下规则添加到你的 CSS 中:

¥Now we're going to give the h1 element position: fixed; and have it sit at the top of the viewport. Add the following rule to your CSS:

css
h1 {
  position: fixed;
  top: 0;
  width: 500px;
  margin-top: 0;
  background: white;
  padding: 10px;
}

需要 top: 0; 才能使其粘在屏幕顶部。我们为标题设置与内容列相同的宽度,然后设置白色背景以及一些填充和边距,以便内容在其下方不可见。

¥The top: 0; is required to make it stick to the top of the screen. We give the heading the same width as the content column and then a white background and some padding and margin so the content won't be visible underneath it.

如果保存并刷新,你会看到标题保持固定的有趣小效果 - 内容似乎向上滚动并消失在其下方。但请注意一些内容最初是如何剪辑在标题下的。这是因为定位的标题不再出现在文档流中,因此其余内容向上移动到顶部。我们可以通过将段落全部下移一点来改进这一点。我们可以通过在第一段上设置一些上边距来做到这一点。现在添加这个:

¥If you save and refresh, you'll see a fun little effect of the heading staying fixed — the content appears to scroll up and disappear underneath it. But notice how some of the content is initially clipped under the heading. This is because the positioned heading no longer appears in the document flow, so the rest of the content moves up to the top. We could improve this by moving the paragraphs all down a bit. We can do this by setting some top margin on the first paragraph. Add this now:

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

你现在应该看到完成的示例:

¥You should now see the finished example:

html
<h1>Fixed positioning</h1>

<p>
  I am a basic block level element. My adjacent block level elements sit on new
  lines below me.
</p>

<p class="positioned">I'm not positioned any more.</p>

<p>
  We are separated by our margins. Because of margin collapsing, we are
  separated by the width of one of our margins, not both.
</p>

<p>
  Inline elements <span>like this one</span> and <span>this one</span> sit on
  the same line as one another, and adjacent text nodes, if there is space on
  the same line. Overflowing inline elements
  <span>wrap onto a new line if possible — like this one containing text</span>,
  or just go on to a new line if not, much like this image will do:
  <img src="long.jpg" alt="snippet of cloth" />
</p>
css
body {
  width: 500px;
  height: 1400px;
  margin: 0 auto;
}

p {
  background: aqua;
  border: 3px solid blue;
  padding: 10px;
  margin: 10px;
}

span {
  background: red;
  border: 1px solid black;
}

h1 {
  position: fixed;
  top: 0px;
  width: 500px;
  background: white;
  padding: 10px;
}

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

注意:你可以在 6_fixed-positioning.html (查看源代码) 观看直播示例。

¥Note: You can see an example for this live at 6_fixed-positioning.html (see source code).

粘性定位

¥Sticky positioning

还有另一个可用的位置值,称为 position: sticky,它比其他值稍新。这基本上是相对位置和固定位置的混合。它允许定位元素表现得像相对定位的一样,直到滚动到某个阈值(例如,距视口顶部 10px),之后它就会固定。

¥There is another position value available called position: sticky, which is somewhat newer than the others. This is basically a hybrid between relative and fixed position. It allows a positioned element to act like it's relatively positioned until it's scrolled to a certain threshold (e.g., 10px from the top of the viewport), after which it becomes fixed.

基本示例

¥Basic example

例如,可以使用粘性定位来使导航栏随页面滚动直到某个点,然后粘在页面顶部。

¥Sticky positioning can be used, for example, to cause a navigation bar to scroll with the page until a certain point and then stick to the top of the page.

html
<h1>Sticky positioning</h1>

<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 class="positioned">Sticky</div>

<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>

<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>
css
body {
  width: 500px;
  margin: 0 auto;
}

.positioned {
  background: rgb(255 84 104 / 30%);
  border: 2px solid rgb(255 84 104);
  padding: 10px;
  margin: 10px;
  border-radius: 5px;
}
css
.positioned {
  position: sticky;
  top: 30px;
  left: 30px;
}

滚动索引

¥Scrolling index

position: sticky 的一个有趣且常见的用途是创建一个滚动索引页面,其中不同的标题在到达页面时会粘在页面顶部。此类示例的标记可能如下所示:

¥An interesting and common use of position: sticky is to create a scrolling index page where different headings stick to the top of the page as they reach it. The markup for such an example might look like so:

html
<h1>Sticky positioning</h1>

<dl>
  <dt>A</dt>
  <dd>Apple</dd>
  <dd>Ant</dd>
  <dd>Altimeter</dd>
  <dd>Airplane</dd>
  <dt>B</dt>
  <dd>Bird</dd>
  <dd>Buzzard</dd>
  <dd>Bee</dd>
  <dd>Banana</dd>
  <dd>Beanstalk</dd>
  <dt>C</dt>
  <dd>Calculator</dd>
  <dd>Cane</dd>
  <dd>Camera</dd>
  <dd>Camel</dd>
  <dt>D</dt>
  <dd>Duck</dd>
  <dd>Dime</dd>
  <dd>Dipstick</dd>
  <dd>Drone</dd>
  <dt>E</dt>
  <dd>Egg</dd>
  <dd>Elephant</dd>
  <dd>Egret</dd>
</dl>

CSS 可能如下所示。在正常流程中,<dt> 元素将随内容滚动。当我们将 position: sticky 添加到 <dt> 元素,并且 top 值为 0 时,支持的浏览器将在标题到达该位置时将其粘贴到视口的顶部。然后,每个后续标题将在向上滚动到该位置时替换前一个标题。

¥The CSS might look as follows. In normal flow the <dt> elements will scroll with the content. When we add position: sticky to the <dt> element, along with a top value of 0, supporting browsers will stick the headings to the top of the viewport as they reach that position. Each subsequent header will then replace the previous one as it scrolls up to that position.

css
dt {
  background-color: black;
  color: white;
  padding: 10px;
  position: sticky;
  top: 0;
  left: 0;
  margin: 1em 0;
}
css
body {
  width: 500px;
  height: 1400px;
  margin: 0 auto;
}
html
<h1>Sticky positioning</h1>

<dl>
  <dt>A</dt>
  <dd>Apple</dd>
  <dd>Ant</dd>
  <dd>Altimeter</dd>
  <dd>Airplane</dd>
  <dt>B</dt>
  <dd>Bird</dd>
  <dd>Buzzard</dd>
  <dd>Bee</dd>
  <dd>Banana</dd>
  <dd>Beanstalk</dd>
  <dt>C</dt>
  <dd>Calculator</dd>
  <dd>Cane</dd>
  <dd>Camera</dd>
  <dd>Camel</dd>
  <dt>D</dt>
  <dd>Duck</dd>
  <dd>Dime</dd>
  <dd>Dipstick</dd>
  <dd>Drone</dd>
  <dt>E</dt>
  <dd>Egg</dd>
  <dd>Elephant</dd>
  <dd>Egret</dd>
</dl>

粘性元素是相对于具有 "滚动机制" 的最近祖级的 "sticky",这是由其祖级的 position 属性决定的。

¥Sticky elements are "sticky" relative to the nearest ancestor with a "scrolling mechanism", which is determined by its ancestors' position property.

注意:你可以在 7_sticky-positioning.html (查看源代码) 现场观看此示例。

¥Note: You can see this example live at 7_sticky-positioning.html (see source code).

测试你的技能!

¥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: Positioning.

概括

¥Summary

我相信你在基本定位方面玩得很开心。虽然它不是用于整个布局的理想方法,但它适合许多特定目标。

¥I'm sure you had fun playing with basic positioning. While it's not an ideal method to use for entire layouts, there are many specific objectives it's suited for.

也可以看看

¥See also