aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/learn/css/css_layout/positioning/index.html
blob: cbfa094300f680ad5eb4c8647184d98ab8fe26a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
---
title: 定位
slug: Learn/CSS/CSS_layout/定位
tags:
  - CSS
  - 初学者
  - 定位
  - 布局
  - 指南
  - 相对定位
  - 绝对定位
translation_of: Learn/CSS/CSS_layout/Positioning
---
<div>
<p>{{LearnSidebar}}</p>

<p>{{PreviousMenuNext("Learn/CSS/CSS_layout/Floats", "Learn/CSS/CSS_layout/Practical_positioning_examples", "Learn/CSS/CSS_layout")}}</p>
</div>

<p class="summary">定位允许您从正常的文档流布局中取出元素,并使它们具有不同的行为,例如放在另一个元素的上面,或者始终保持在浏览器视窗内的同一位置。 本文解释的是定位({{cssxref("position")}})的各种不同值,以及如何使用它们。</p>

<table class="learn-box standard-table">
 <tbody>
  <tr>
   <th scope="row">预备知识:</th>
   <td>HTML 基础 (学习 <a href="/zh-CN/docs/learn/HTML/Introduction_to_HTML">HTML导学</a>)和CSS怎样工作的 (学习<a href="/zh-CN/docs/Learn/CSS/Introduction_to_CSS"> CSS导学</a>)</td>
  </tr>
  <tr>
   <th scope="row">目的:</th>
   <td>了解CSS定位的工作原理</td>
  </tr>
 </tbody>
</table>

<h2 id="文档流">文档流</h2>

<p>定位是一个相当复杂的话题,所以我们深入了解代码之前,让我们审视一下布局理论,并让我们了解它的工作原理。</p>

<p>首先,围绕元素内容添加任何内边距、边界和外边距来布置单个元素盒子——这就是 <a href="/zh-CN/docs/Learn/CSS/Introduction_to_CSS/Box_model">盒模型</a> ,我们前面看过。 默认情况下,块级元素的内容宽度是其父元素的宽度的100%,并且与其内容一样高。内联元素高宽与他们的内容高宽一样。您不能对内联元素设置宽度或高度——它们只是位于块级元素的内容中。 如果要以这种方式控制内联元素的大小,则需要将其设置为类似块级元素 <code>display: block;</code></p>

<p>这只是解释了单个元素,但是元素相互之间如何交互呢? <strong>正常的布局流</strong>(在布局介绍文章中提到)是将元素放置在浏览器视口内的系统。默认情况下,块级元素在视口中垂直布局——每个都将显示在上一个元素下面的新行上,并且它们的外边距将分隔开它们。</p>

<p>内联元素表现不一样——它们不会出现在新行上;相反,它们互相之间以及任何相邻(或被包裹)的文本内容位于同一行上,只要在父块级元素的宽度内有空间可以这样做。如果没有空间,那么溢流的文本或元素将向下移动到新行。</p>

<p>如果两个相邻元素都在其上设置外边距,并且两个外边距接触,则两个外边距中的较大者保留,较小的一个消失——这叫<a href="/zh-CN/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing">外边距折叠</a>, 我们之前也遇到过。</p>

<p>让我们来看一个简单的例子来解析这一切:</p>

<pre class="brush: html notranslate">&lt;h1&gt;Basic document flow&lt;/h1&gt;

&lt;p&gt;I am a basic block level element. My adjacent block level elements sit on new lines below me.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.&lt;/p&gt;

&lt;p&gt;inline elements &lt;span&gt;like this one&lt;/span&gt; and &lt;span&gt;this one&lt;/span&gt; sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements will &lt;span&gt;wrap onto a new line if possible (like this one containing text)&lt;/span&gt;, or just go on to a new line if not, much like this image will do: &lt;img src="https://mdn.mozillademos.org/files/13360/long.jpg"&gt;&lt;/p&gt;</pre>

<pre class="brush: css notranslate">body {
  width: 500px;
  margin: 0 auto;
}

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

span {
  background: red;
  border: 1px solid black;
}</pre>

<p>{{ EmbedLiveSample('文档流', '100%', 500) }}</p>

<p>在我们阅读本文时,我们将多次重复这个例子,因为我们要展示不同定位选项的效果。</p>

<p>如果可能,我们希望您在本地计算机上跟随练习 — 从GitHub仓库下载一个<code><a href="http://mdn.github.io/learning-area/css/css-layout/positioning/0_basic-flow.html">0_basic-flow.html</a></code> (<a href="https://github.com/mdn/learning-area/blob/master/css/css-layout/positioning/1_static-positioning.html">源代码</a>) 然后用它作为我们的起步点。</p>

<h2 id="介绍定位">介绍定位</h2>

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

<p>有许多不同类型的定位,您可以对HTML元素生效。要使某个元素上的特定类型的定位,我们使用{{cssxref("position")}}属性。</p>

<h3 id="静态定位">静态定位</h3>

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

<p>为了演示这一点,并为以后的部分设置示例,首先在HTML中添加一个<code>positioned</code> 的 <code>class</code> 到第二个{{htmlelement("p")}}</p>

<pre class="brush: html notranslate">&lt;p class="positioned"&gt; ... &lt;/p&gt;</pre>

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

<pre class="brush: css notranslate">.positioned {
  position: static;
  background: yellow;
}</pre>

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

<div class="note">
<p><strong>注意:</strong>你可以在 <code><a href="http://mdn.github.io/learning-area/css/css-layout/positioning/1_static-positioning.html">1_static-positioning.html</a></code> 查看这个例子 (<a href="https://github.com/mdn/learning-area/blob/master/css/css-layout/positioning/1_static-positioning.html">see source code</a>)。</p>
</div>

<h3 id="相对定位">相对定位</h3>

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

<pre class="brush: css notranslate">position: relative;</pre>

<p>如果您在此阶段保存并刷新,则结果根本不会发生变化。那么如何修改元素的位置呢? 您需要使用{{cssxref("top")}}{{cssxref("bottom")}}{{cssxref("left")}}{{cssxref("right")}}属性 ,我们将在下一节中解释。</p>

<h3 id="介绍_top_bottom_left_right">介绍 top, bottom, left,  right</h3>

<p>{{cssxref("top")}}, {{cssxref("bottom")}}, {{cssxref("left")}}, 和 {{cssxref("right")}} 来精确指定要将定位元素移动到的位置。 要尝试这样做,请在CSS中的 <code>.positioned</code> 规则中添加以下声明:</p>

<pre class="notranslate">top: 30px;
left: 30px;</pre>

<div class="note">
<p><strong>注意:</strong>这些属性的值可以采用逻辑上期望的任何单位 ——px,mm,rems,%等。</p>
</div>

<p>如果你现在保存和刷新,你会得到一个这样的结果:</p>

<div class="hidden">
<pre class="brush: html notranslate">&lt;h1&gt;Relative positioning&lt;/h1&gt;

&lt;p&gt;I am a basic block level element. My adjacent block level elements sit on new lines below me.&lt;/p&gt;

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

&lt;p&gt;We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.&lt;/p&gt;

&lt;p&gt;inline elements &lt;span&gt;like this one&lt;/span&gt; and &lt;span&gt;this one&lt;/span&gt; sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements &lt;span&gt;wrap onto a new line if possible — like this one containing text&lt;/span&gt;, or just go on to a new line if not, much like this image will do: &lt;img src="https://mdn.mozillademos.org/files/13360/long.jpg"&gt;&lt;/p&gt;</pre>

<pre class="brush: css notranslate">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;
}</pre>
</div>

<p>{{ EmbedLiveSample('介绍_top_bottom_left_right', '100%', 500) }}</p>

<p>酷,是吗? 好吧,所以这个结果这可能不是你期待的——为什么它移动到底部和右边,但我们指定顶部和左边? 听起来不合逻辑,但这只是相对定位工作的方式——你需要考虑一个看不见的力,推动定位的盒子的一侧,移动它的相反方向。 所以例如,如果你指定 <code>top: 30px;</code>一个力推动框的顶部,使它向下移动30px。</p>

<div class="note">
<p><strong>注意:</strong> 你可以在 <code><a href="http://mdn.github.io/learning-area/css/css-layout/positioning/2_relative-positioning.html">2_relative-positioning.html</a></code> 查看这个例子 (<a href="https://github.com/mdn/learning-area/blob/master/css/css-layout/positioning/2_relative-positioning.html">see source code</a>)。</p>
</div>

<h3 id="绝对定位">绝对定位</h3>

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

<pre class="notranslate">position: absolute;</pre>

<p>如果你现在保存和刷新,你应该看到这样:</p>

<div class="hidden">
<pre class="brush: html notranslate">&lt;h1&gt;Absolute positioning&lt;/h1&gt;

&lt;p&gt;I am a basic block level element. My adjacent block level elements sit on new lines below me.&lt;/p&gt;

&lt;p class="positioned"&gt;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.&lt;/p&gt;

&lt;p&gt;We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.&lt;/p&gt;

&lt;p&gt;inline elements &lt;span&gt;like this one&lt;/span&gt; and &lt;span&gt;this one&lt;/span&gt; sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements &lt;span&gt;wrap onto a new line if possible — like this one containing text&lt;/span&gt;, or just go on to a new line if not, much like this image will do: &lt;img src="https://mdn.mozillademos.org/files/13360/long.jpg"&gt;&lt;/p&gt;</pre>

<pre class="brush: css notranslate">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;
}</pre>
</div>

<p>{{ EmbedLiveSample('绝对定位', '100%', 420) }}</p>

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

<p>第二,注意元素的位置已经改变——这是因为{{cssxref("top")}}{{cssxref("bottom")}}{{cssxref("left")}}{{cssxref("right")}}以不同的方式在绝对定位。 它们指定元素应距离每个包含元素的边的距离,而不是指定元素应该移入的方向。 所以在这种情况下,我们说的绝对定位元素应该位于从“包含元素”的顶部30px,从左边30px。</p>

<div class="note">
<p><strong>注意:</strong>如果需要,您可以使用{{cssxref("top")}}{{cssxref("bottom")}}{{cssxref("left")}}{{cssxref("right")}} 调整元素大小。 尝试设置 <code>top: 0; bottom: 0; left: 0; right: 0;</code> 和 <code>margin: 0;</code> 对你定位的元素,看看会发生什么! 之后再回来</p>
</div>

<div class="note">
<p><strong>注意:</strong>是的,margins 仍会影响定位的元素。 然而margin collapsing不会。</p>
</div>

<div class="note">
<p><strong>注意:</strong>你可以在<code><a href="http://mdn.github.io/learning-area/css/css-layout/positioning/3_absolute-positioning.html">3_absolute-positioning.html</a></code> 查看这个例子(<a href="https://github.com/mdn/learning-area/blob/master/css/css-layout/positioning/3_absolute-positioning.html">see source code</a>)。</p>
</div>

<h3 id="定位上下文">定位上下文</h3>

<p>哪个元素是绝对定位元素的“包含元素“?这取决于绝对定位元素的父元素的position属性。(参见 <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#Identifying_the_containing_block">Identifying the containing block</a>).</p>

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

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

<pre class="notranslate">position: relative;</pre>

<p>应该得到以下结果:</p>

<div class="hidden">
<pre class="brush: html notranslate">&lt;h1&gt;Positioning context&lt;/h1&gt;

&lt;p&gt;I am a basic block level element. My adjacent block level elements sit on new lines below me.&lt;/p&gt;

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

&lt;p&gt;We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.&lt;/p&gt;

&lt;p&gt;inline elements &lt;span&gt;like this one&lt;/span&gt; and &lt;span&gt;this one&lt;/span&gt; sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements &lt;span&gt;wrap onto a new line if possible — like this one containing text&lt;/span&gt;, or just go on to a new line if not, much like this image will do: &lt;img src="https://mdn.mozillademos.org/files/13360/long.jpg"&gt;&lt;/p&gt;</pre>

<pre class="brush: css notranslate">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;
}</pre>
</div>

<p>{{ EmbedLiveSample('定位上下文', '100%', 420) }}</p>

<p>定位的元素现在相对于{{htmlelement("body")}}元素。</p>

<div class="note">
<p>注意:你可以在这里看到这个例子 <code><a href="http://mdn.github.io/learning-area/css/css-layout/positioning/4_positioning-context.html">4_positioning-context.html</a></code> (<a href="https://github.com/mdn/learning-area/blob/master/css/css-layout/positioning/4_positioning-context.html">see source code</a>).</p>
</div>

<h3 id="介绍_z-index">介绍 z-index</h3>

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

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

<pre class="notranslate">p:nth-of-type(1) {
  position: absolute;
  background: lime;
  top: 10px;
  right: 30px;
}</pre>

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

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

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

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

<pre class="notranslate">z-index: 1;</pre>

<p>你现在应该可以看到完成的例子:</p>

<div class="hidden">
<pre class="brush: html notranslate">&lt;h1&gt;z-index&lt;/h1&gt;

&lt;p&gt;I am a basic block level element. My adjacent block level elements sit on new lines below me.&lt;/p&gt;

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

&lt;p&gt;We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.&lt;/p&gt;

&lt;p&gt;inline elements &lt;span&gt;like this one&lt;/span&gt; and &lt;span&gt;this one&lt;/span&gt; sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements &lt;span&gt;wrap onto a new line if possible — like this one containing text&lt;/span&gt;, or just go on to a new line if not, much like this image will do: &lt;img src="https://mdn.mozillademos.org/files/13360/long.jpg"&gt;&lt;/p&gt;</pre>

<pre class="brush: css notranslate">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;
}
</pre>
</div>

<p>{{ EmbedLiveSample('介绍_z-index', '100%', 400) }}</p>

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

<div class="note">
<p><strong>注意:</strong>你可以在这里看到这个例子 <code><a href="http://mdn.github.io/learning-area/css/css-layout/positioning/5_z-index.html">5_z-index.html</a></code> (<a href="https://github.com/mdn/learning-area/blob/master/css/css-layout/positioning/5_z-index.html">see source code</a>).</p>
</div>

<h3 id="固定定位">固定定位</h3>

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

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

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

<pre class="notranslate">body {
  width: 500px;
  height: 1400px;
  margin: 0 auto;
}</pre>

<p>现在我们要给{{htmlelement("h1")}}元素 <code>position: fixed;</code>,并让它坐在视口的顶部中心。将以下规则添加到CSS:</p>

<pre class="notranslate">h1 {
  position: fixed;
  top: 0;
  width: 500px;
  margin: 0 auto;
  background: white;
  padding: 10px;
}</pre>

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

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

<pre class="notranslate">p:nth-of-type(1) {
  margin-top: 60px;
}</pre>

<p>你现在应该看到完成的例子:</p>

<div class="hidden">
<pre class="brush: html notranslate">&lt;h1&gt;Fixed positioning&lt;/h1&gt;

&lt;p&gt;I am a basic block level element. My adjacent block level elements sit on new lines below me.&lt;/p&gt;

&lt;p class="positioned"&gt;I'm not positioned any more...&lt;/p&gt;

&lt;p&gt;We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.&lt;/p&gt;

&lt;p&gt;inline elements &lt;span&gt;like this one&lt;/span&gt; and &lt;span&gt;this one&lt;/span&gt; sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements &lt;span&gt;wrap onto a new line if possible — like this one containing text&lt;/span&gt;, or just go on to a new line if not, much like this image will do: &lt;img src="https://mdn.mozillademos.org/files/13360/long.jpg"&gt;&lt;/p&gt;</pre>

<pre class="brush: css notranslate">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;
  margin: 0 auto;
  background: white;
  padding: 10px;
}

p:nth-of-type(1) {
  margin-top: 60px;
}</pre>
</div>

<p>{{ EmbedLiveSample('固定定位', '100%', 400) }}</p>

<div class="note">
<p><strong>注意:</strong>你可以在这里看到这个例子<code><a href="http://mdn.github.io/learning-area/css/css-layout/positioning/6_fixed-positioning.html">6_fixed-positioning.html</a></code> (<a href="https://github.com/mdn/learning-area/blob/master/css/css-layout/positioning/6_fixed-positioning.html">see source code</a>).</p>
</div>

<h3 id="position_sticky">position: sticky</h3>

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

<div class="hidden">
<h6 id="Sticky_positioning_example">Sticky positioning example</h6>

<pre class="brush: html notranslate">&lt;h1&gt;Sticky positioning&lt;/h1&gt;

&lt;p&gt; 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.&lt;/p&gt;

&lt;div class="positioned"&gt;Sticky&lt;/div&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt; 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.&lt;/p&gt;
</pre>

<pre class="brush: css notranslate">body {
  width: 500px;
  margin: 0 auto;
}

.positioned {
  background: rgba(255,84,104,.3);
  border: 2px solid rgb(255,84,104);
  padding: 10px;
  margin: 10px;
  border-radius: 5px;
}</pre>
</div>

<pre class="notranslate">.positioned {
  position: sticky;
  top: 30px;
  left: 30px;
}</pre>

<p>{{ EmbedLiveSample('Sticky_1', '100%', 200) }}</p>

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

<pre class="notranslate">&lt;h1&gt;Sticky positioning&lt;/h1&gt;

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

<p>CSS可能如下所示。在正常布局流中,{{htmlelement("dt")}}元素将随内容滚动。当我们在{{htmlelement("dt")}}元素上添加<code>position: sticky</code>,并将{{cssxref("top")}}的值设置为0,当标题滚动到视口的顶部时,支持此属性的浏览器会将标题粘贴到那个位置。随后,每个后续标题将替换前一个标题,直到它向上滚动到该位置。</p>

<pre class="notranslate">dt {
  background-color: black;
  color: white;
  padding: 10px;
  position: sticky;
  top: 0;
  left: 0;
  margin: 1em 0;
}
</pre>

<div class="hidden">
<pre class="notranslate">body {
  width: 500px;
  height: 1400px;
  margin: 0 auto;
}

dt {
  background-color: black;
  color: white;
  padding: 10px;
  position: sticky;
  top: 0;
  left: 0;
  margin: 1em 0;
}
</pre>

<pre class="notranslate">&lt;h1&gt;Sticky positioning&lt;/h1&gt;

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

<p>{{ EmbedLiveSample('Sticky_2', '100%', 200) }}</p>

<div class="blockIndicator note">
<p><strong>注意:</strong>你可以在 <code><a href="http://mdn.github.io/learning-area/css/css-layout/positioning/7_sticky-positioning.html">7_sticky-positioning.html</a></code> 查看这个例子(<a href="https://github.com/mdn/learning-area/blob/master/css/css-layout/positioning/7_sticky-positioning.html">see source code</a>)。</p>
</div>

<h2 id="试试你的技术!">试试你的技术!</h2>

<p>这篇文章到此为止了,但你们能记住最重要的信息吗?在继续之前,您可以找到一些进一步的测试来验证是否完全掌握了这个知识:<a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Position_skills">试试你的技术</a></p>

<h2 id="总结">总结</h2>

<p>我相信你用基本定位愉快地玩耍;它是创建复杂的CSS布局和UI功能背后的基本工具之一。 考虑到这一点,在下一篇文章中,我们将更有趣的定位——我们将进一步,开始建立一些真实世界有用的东西。</p>

<p>{{PreviousMenuNext("Learn/CSS/CSS_layout/Floats", "Learn/CSS/CSS_layout/Practical_positioning_examples", "Learn/CSS/CSS_layout")}}</p>

<h2 id="在本单元中">在本单元中</h2>

<ul>
 <li><a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Introduction">布局介绍</a></li>
 <li><a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Floats">浮动</a></li>
 <li><a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Positioning">定位</a></li>
 <li><a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Practical_positioning_examples">定位练习案例</a></li>
 <li><a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox">弹性盒子</a></li>
 <li><a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Grids">Grids</a></li>
</ul>