position
Baseline
Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2015年7月.
position CSS 属性用于指定一个元素在文档中的定位方式。top、right、bottom、left 物理属性和 inset-block-start、inset-block-end、inset-inline-start、inset-inline-end 流相对逻辑属性则可用于决定定位元素的最终位置。
尝试一下
position: static;
position: relative;
top: 40px;
left: 40px;
position: absolute;
inset-inline-start: 40px;
inset-block-start: 40px;
position: sticky;
top: 20px;
<section class="default-example" id="default-example">
<div id="example-element-container">
<p>在此演示中你可以控制黄色盒子的 <code>position</code> 属性。</p>
<div class="box"></div>
<div class="box" id="example-element"></div>
<div class="box"></div>
<p class="clear">
要观察 <code>sticky</code> 定位的效果,选择
<code>position: sticky</code> 选项并滚动此容器。
</p>
<p>
元素将随着容器滚动,直到位于容器顶部(或达到
<code>top</code> 中指定的偏移量),然后停止滚动,保持可见。
</p>
<p>剩下的文字只是为了确保容器溢出,以便滚动容器查看效果。</p>
<hr />
<p>
在银河系西旋臂不时髦的一端,遥远的无人知晓的后方,有一个无人问津的黄色小太阳。在距离太阳大约九千二百万英里的地方,有一颗极其微不足道的蓝绿色小行星,它的猿人后裔生命形式原始得令人吃惊,以至于他们仍然认为电子表是个相当不错的主意。
</p>
</div>
</section>
section {
align-items: flex-start;
overflow: auto;
}
.box {
background-color: rgb(0 0 255 / 0.2);
border: 3px solid blue;
float: left;
width: 65px;
height: 65px;
}
.box + .box {
margin-left: 10px;
}
.clear {
clear: both;
padding-top: 1em;
}
#example-element-container {
position: relative;
text-align: left;
}
#example-element {
background-color: yellow;
border: 3px solid red;
z-index: 1;
}
语法
position: static;
position: relative;
position: absolute;
position: fixed;
position: sticky;
/* 全局值 */
position: inherit;
position: initial;
position: revert;
position: revert-layer;
position: unset;
值
static-
该关键字指定元素使用正常的布局行为,即元素在文档正常布局流中当前的布局位置。此时
top、right、bottom、left和z-index属性无效。这是默认值。 relative-
元素根据文档的正常流程定位,然后根据
top、right、bottom和left的值相对于自身偏移。偏移量不会影响任何其他元素的位置;因此,在页面布局中为该元素提供的空间与位置为static时相同。当
z-index的值不是auto时,该值会创建一个新的层叠上下文。它对table-*-group、table-row、table-column、table-cell和table-caption元素的影响未定义。 absolute-
该元素将从正常文档流中移除,页面布局中不会为该元素创建任何空间。元素的位置是相对于其位置最近的祖先(如果有)或初始包含块。其最终位置由
top、right、bottom和left的值决定。 fixed-
元素会被移出正常文档流,并不为元素预留空间。元素的位置是相对于其初始包含块,也就是视觉媒体的视口。其最终位置由
top、right、bottom和left的值决定。该值总会创建一个新的层叠上下文。在打印的文档中,该元素在每一页上的位置都是相同的。
sticky-
元素根据正常文档流进行定位,然后相对它的最近滚动祖先和包含块(最近块级祖先),包括表格相关元素,基于
top、right、bottom和left的值进行偏移。偏移值不会影响任何其他元素的位置。该值总是创建一个新的层叠上下文。注意,一个 sticky 元素会“固定”在离它最近的一个拥有“滚动机制”的祖先上(当该祖先的
overflow是hidden、scroll、auto或overlay时),即便这个祖先不是最近的真实可滚动祖先。备注: 至少有一个 inset 属性(
top、inset-block-start、right、inset-inline-end等)需要设置为非auto值。如果某个轴的两个inset属性都设置为auto,则该轴上的sticky值将表现为relative。
描述
>定位类型
- 定位元素(positioned element)是其计算后
position属性为relative、absolute、fixed或sticky的一个元素(换句话说,除static以外的任何东西)。 - 相对定位元素(relatively positioned element)是计算后
position属性为relative的元素。top和bottom属性指定了与正常位置的垂直偏移;left和right指定了水平偏移。 - 绝对定位元素(absolutely positioned element)是计算后
position属性为absolute或fixed的元素。top、right、bottom和left属性指定了从元素包含块边缘的偏移量。(包含块是相对于该元素定位的祖先块)。如果元素有边距,则边距会添加到偏移量中。该元素将为其内容建立一个新的区块格式化上下文(BFC)。 - 粘性定位元素(stickily positioned element)是计算后
position属性为sticky的元素。在其包含块在其流根(或其滚动的容器)内越过指定临界值(例如将top设置为 auto 以外的值)之前,它被视为相对定位,此时它被视为“卡住”,直到遇到其包含块的对边。
大多数情况下,height 和 width 被设定为 auto 的绝对定位元素,按其内容大小调整尺寸。但是,非可替换绝对定位元素可以通过指定 top 和 bottom,保留 height 未指定(即 auto),来填充可用的垂直空间。它们同样可以通过指定 left 和 right 并将 width 指定为 auto 来填充可用的水平空间。
除了刚刚描述的情况(绝对定位元素填充可用空间):
无障碍
确保使用 absolute 或 fixed 值定位的元素在页面缩放以增大文字大小时不会遮挡其他内容。
性能和无障碍
包含 fixed 或 sticky 内容的滚动元素会导致性能和无障碍问题。当用户滚动时,浏览器必须在新的位置重新绘制粘性或固定内容。根据需要重新绘制的内容、浏览器的性能和设备的处理速度,浏览器可能无法以 60 fps 的速度管理重新绘制。这种情况可能会导致卡顿,更重要的是,会给敏感人群带来无障碍问题。一种解决方案是在定位元素中添加 will-change: transform,以在独立层中渲染元素,提高重绘速度,从而改善性能和无障碍性。
形式定义
| 初始值 | static |
|---|---|
| 适用元素 | 所有元素 |
| 是否是继承属性 | 否 |
| 计算值 | as specified |
| 动画类型 | 离散值 |
| Creates stacking context | 是 |
形式语法
position =
static |
relative |
absolute |
sticky |
fixed |
<running()>
<running()> =
running( <custom-ident> )
示例
>相对定位
相对定位的元素是在文档中的正常位置偏移给定的值,但是不影响其他元素的偏移。下面的例子中,注意未应用定位的其他元素是按照“二”在正常位置的情况下进行布局的。
HTML
<div class="box" id="one">一</div>
<div class="box" id="two">二</div>
<div class="box" id="three">三</div>
<div class="box" id="four">四</div>
CSS
* {
box-sizing: border-box;
}
.box {
display: inline-block;
width: 100px;
height: 100px;
background: red;
color: white;
}
#two {
position: relative;
top: 20px;
left: 20px;
background: blue;
}
绝对定位
相对定位的元素会保持在文档的正常流中。与此相反,绝对定位的元素会被移出流程;因此,其他元素的定位就好像它不存在一样。绝对定位的元素是相对于其最近定位的祖先(即非 static 的最近祖先)定位的。如果定位祖先不存在,则相对于 ICB(初始包含块)定位,ICB 是文档根元素的包含块。
HTML
<h1>绝对定位</h1>
<p>我是一个基本块级元素。相邻的块级元素位于我下方新的一行上。</p>
<p class="positioned">
默认情况下,我们的宽度是父元素宽度的
100%,高度与子元素的内容相同。我们的总宽度和高度为内容 + 内边距 +
边框宽度/高度。
</p>
<p>
我们被外边距分开了。由于外边距折叠,我们是被其中一个外边距的宽度分开,而不是两个边距都分开。
</p>
<p>
如果同一行有空白,<span>像这样</span>和<span>那样</span>的行级元素和相邻的文本节点会位于同一行。如果可能的话,溢出的行内元素<span>会折行——就像这个包含文本的元素</span>,如果不可能的话,就换行,就像这个图片一样:
<img src="https://mdn.github.io/shared-assets/images/examples/long.jpg" />
</p>
CSS
* {
box-sizing: border-box;
}
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;
}
结果
固定定位
固定定位与绝对定位类似,但元素的包含块是视口建立的初始包含块,除非任何祖先的 transform、perspective 或 filter 属性设置为除 none 以外的其他属性(请参阅固定定位包含块),这样就会使该祖先取代元素包含块。这可以用来创建一个“浮动”元素,无论滚动与否,它都会保持在同一位置。在下面的示例中,盒子“一”被固定在距离页面顶部 80 像素和左侧 10 像素的位置。即使滚动后,它也会保持在相对于视口的同一位置。此外,当 will-change 属性设置为 transform 时,会建立一个新的包含块。
HTML
<div class="outer">
<p>
但我得向你解释,所有这些谴责快乐和颂扬痛苦的错误观念是如何产生的。为此,我会向你一五一十地说明这一体系,并阐述伟大的真理探索者、人类幸福的杰出建设者的真实教义。没有人因为快乐是快乐而拒绝、厌恶或回避快乐本身,而是因为不知道如何理性地追求快乐的人会遭遇极其痛苦的后果。也没有人因痛苦是痛苦而喜欢或追求或渴望获得痛苦本身,但也偶有辛劳和痛苦能带来极大的快乐的情景。举个微不足道的例子,若不是从中获得好处,我们当中有谁会进行艰苦的体育锻炼?但是,倘若没有恼人的后果,谁有权利指责选择享受快乐的人呢?或者倘若得不到相应快乐,谁能谴责选择避免痛苦的人呢?
</p>
<p>
另一方面,我们以正义的愤慨谴责并厌恶那些被及时行乐迷惑得萎靡不振,被欲望蒙蔽得看不见大难临头的人;因意志软弱而不能履行职责的人,也应受到同样的谴责,这无异于在辛劳和痛苦前退缩。这些情况非常简单且容易区分。闲暇时,当我们的选择权不受限制,当没有什么可以阻止我们做自己最喜欢的事情时,任何快乐都应该受到欢迎,任何痛苦都应该避免。但是在某些情况下,由于责任或商业义务的要求,不时会有不得不拒绝享乐而接受烦恼的情况。因此,智者在这些事情上总是坚持选择的原则:拒绝快乐以获得更大的快乐,或者忍受痛苦以避免更重的痛苦。
</p>
<div class="box" id="one">一</div>
</div>
CSS
* {
box-sizing: border-box;
}
.box {
width: 100px;
height: 100px;
background: red;
color: white;
}
#one {
position: fixed;
top: 80px;
left: 10px;
background: blue;
}
.outer {
width: 500px;
height: 300px;
overflow: scroll;
padding-left: 150px;
}
结果
粘性定位
以下 CSS 规则将 id 为 one 的元素相对定位,直到视口滚动到距离顶部 10 像素为止。超过该阈值后,元素将固定在距顶部 10 像素的位置。
#one {
position: sticky;
top: 10px;
}
具有粘性标题的列表
粘性定位的一个常见用途是按字母顺序排列的列表中的标题。“B”标题将出现在以“A”开头的项目下方,直到它们被滚动到屏幕之外。“B”标题不会与其他内容一起滑出屏幕,而是固定在视口顶部,直到所有“B”项都滚动到屏幕之外,然后再被“C”标题覆盖,以此类推。
必须指定一个阈值,该阈值至少包含 top、right、bottom 或 left 中的一个,这样粘性定位才会按照预期运行。否则,它将与相对定位无异。
HTML
<dl>
<div>
<dt>A</dt>
<dd>a</dd>
<dd>ai</dd>
<dd>an</dd>
<dd>ang</dd>
<dd>ao</dd>
</div>
<div>
<dt>C</dt>
<dd>ca</dd>
<dd>cai</dd>
<dd>can</dd>
<dd>cao</dd>
<dd>ce</dd>
</div>
<div>
<dt>E</dt>
<dd>ei</dd>
<dd>en</dd>
<dd>er</dd>
</div>
<div>
<dt>T</dt>
<dd>ta</dd>
<dd>tai</dd>
<dd>tan</dd>
<dd>tang</dd>
<dd>tao</dd>
</div>
</dl>
CSS
* {
box-sizing: border-box;
}
dl > div {
background: #fff;
padding: 24px 0 0 0;
}
dt {
background: #b8c1c8;
border-bottom: 1px solid #989ea4;
border-top: 1px solid #717d85;
color: #fff;
font:
bold 18px/21px Helvetica,
Arial,
sans-serif;
margin: 0;
padding: 2px 0 0 12px;
position: -webkit-sticky;
position: sticky;
top: -1px;
}
dd {
font:
bold 20px/45px Helvetica,
Arial,
sans-serif;
margin: 0;
padding: 0 0 0 12px;
white-space: nowrap;
}
dd + dd {
border-top: 1px solid #ccc;
}
结果
设置了所有嵌入边界的粘性定位
下面的示例演示了设置所有嵌入边界时元素的行为。这里,我们在一个段落中有两个灯泡表情符号。灯泡使用粘性定位,嵌入边界指定为距顶部 50px、距右侧 100px、距底部 50px 和距左侧 50px。父 div 元素上的灰色背景标记了嵌入区域。
HTML
使用滚动条将灯泡(💡)放到下面文字的正确位置:
<div>
<p>
用灯泡(<span class="bulb">💡</span
>)来代表一个想法是一个常用的比喻,象征着灵感迸发或新想法诞生的时刻。灯泡与创意之间的联系可以追溯到
19 世纪末托马斯·爱迪生发明的白炽灯泡(<span class="bulb">💡</span
>)。灯泡是一个强有力的象征,因为它代表着照明、清晰和思想或理解的突然明亮。当一个人有了一个想法时,通常会被描述为他脑海中的灯泡亮了起来,象征着洞察力或创造力的迸发。灯泡的形象也暗示了能量、力量以及成长和发展潜力的概念。
</p>
</div>
CSS
.bulb {
position: sticky;
inset: 50px 100px 50px 100px;
}
div {
/* 使用灰色标记插入边界所定义的区域 */
background: linear-gradient(#9999, #9999) 100px 50px / 192px 100px no-repeat;
}
结果
将两个灯泡放在适当的位置后,你会发现它们相对位于嵌入区域内。当将它们移出嵌入区时,它们就会固定(粘住)在嵌入区边界的那个方向上。
规范
| Specification |
|---|
| CSS Positioned Layout Module Level 3> # position-property> |
浏览器兼容性
Loading…