position

Baseline 已廣泛支援

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2015 年 7 月⁩以來,各瀏覽器均已提供此特性。

position 這個 CSS 屬性用於設定一個元素在文件中的定位方式。當元素的 position 值不為 static 時,toprightbottomleft 這類物理屬性以及 inset-block-startinset-block-endinset-inline-startinset-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>
      In this demo you can control the <code>position</code> property for the
      yellow box.
    </p>
    <div class="box"></div>
    <div class="box" id="example-element"></div>
    <div class="box"></div>
    <p class="clear">
      To see the effect of <code>sticky</code> positioning, select the
      <code>position: sticky</code> option and scroll this container.
    </p>
    <p>
      The element will scroll along with its container, until it is at the top
      of the container (or reaches the offset specified in <code>top</code>),
      and will then stop scrolling, so it stays visible.
    </p>
    <p>
      The rest of this text is only supplied to make sure the container
      overflows, so as to enable you to scroll it and see the effect.
    </p>
    <hr />
    <p>
      Far out in the uncharted backwaters of the unfashionable end of the
      western spiral arm of the Galaxy lies a small unregarded yellow sun.
      Orbiting this at a distance of roughly ninety-two million miles is an
      utterly insignificant little blue green planet whose ape-descended life
      forms are so amazingly primitive that they still think digital watches are
      a pretty neat idea.
    </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;
}

語法

css
position: static;
position: relative;
position: absolute;
position: fixed;
position: sticky;

/* Global values */
position: inherit;
position: initial;
position: revert;
position: revert-layer;
position: unset;

static

該元素根據文件的常規流進行定位。toprightbottomleftz-index 屬性均無效。這是預設值。

relative

該元素根據文件的常規流進行定位,然後根據 toprightbottomleft 的值,相對於自己進行偏移。該偏移不會影響任何其他元素的位置;因此,頁面佈局中為該元素保留的空間與 positionstatic 時相同。

z-index 的值不為 auto 時,該值會建立一個新的層疊上下文。它對 table-*-grouptable-rowtable-columntable-celltable-caption 元素的影響是未定義的。

absolute

該元素會脫離常規的文件流,並且在頁面佈局中不會為其建立空間。該元素相對於其最近的已定位祖先元素(如果有)或初始包含塊進行定位。其最終位置由 toprightbottomleft 的值決定。

z-index 的值不為 auto 時,該值會建立一個新的層疊上下文。絕對定位的盒子的外邊距不會與其他外邊距發生摺疊

fixed

該元素會脫離常規的文件流,並且在頁面佈局中不會為其建立空間。該元素相對於其初始包含塊進行定位,對於視覺化媒體,該包含塊就是視口。其最終位置由 toprightbottomleft 的值決定。

該值總是會建立一個新的層疊上下文。在列印的文件中,該元素會放置在每一頁的相同位置。

sticky

該元素根據文件的常規流進行定位,然後根據 toprightbottomleft 的值,相對於其最近的滾動祖先包含塊(最近的塊級祖先,包括與表格相關的元素)進行偏移。該偏移不會影響任何其他元素的位置。

該值總是會建立一個新的層疊上下文。請注意,粘性元素會“粘”在其最近的具有“滾動機制”(當 overflowhiddenscrollautooverlay 時建立)的祖先上,即使該祖先不是最近的實際滾動祖先。

備註: 對於需要粘性定位的軸,至少需要將一個inset 屬性(topinset-block-startrightinset-inline-end 等)設定為非 auto 的值。如果某個軸的兩個 inset 屬性都設定為 auto,那麼在該軸上,sticky 的行為將與 relative 相同。

描述

定位的型別

  • 已定位元素(positioned element)是指其計算後position 值為 relativeabsolutefixedsticky 的元素。(換句話說,就是除了 static 之外的任何值。)
  • 相對定位元素(relatively positioned element)是指其計算後position 值為 relative 的元素。topbottom 屬性指定了其相對於常規位置的垂直偏移;leftright 屬性指定了水平偏移。
  • 絕對定位元素(absolutely positioned element)是指其計算後position 值為 absolutefixed 的元素。toprightbottomleft 屬性指定了其相對於元素包含塊邊緣的偏移。(包含塊是該元素定位所參照的祖先。)如果元素有外邊距,它們會加到偏移量上。該元素會為其內容建立一個新的塊格式化上下文(BFC)。
  • 粘性定位元素(stickily positioned element)是指其計算後position 值為 sticky 的元素。它被視為相對定位,直到其包含塊在其流根(或其滾動的容器)內越過指定的閾值(例如將 top 設定為非 auto 的值),此時它被視為“粘住”,直到遇到其包含塊的對邊。

大多數情況下,將 heightwidth 設定為 auto 的絕對定位元素會根據其內容調整大小。然而,非替換的絕對定位元素可以透過同時指定 topbottom 並將 height 留空(即 auto)來填充可用的垂直空間。同樣,它們也可以透過同時指定 leftright 並將 width 留為 auto 來填充可用的水平空間。

除了剛才描述的情況(絕對定位元素填充可用空間)之外:

  • 如果同時指定了 topbottom(技術上講,都不是 auto),top 優先。
  • 如果同時指定了 leftright,當 directionltr(如英語、水平書寫的日語等)時,left 優先;當 directionrtl(如波斯語、阿拉伯語、希伯來語等)時,right 優先。

無障礙

確保使用 absolutefixed 定位的元素在頁面放大以增加文字大小時不會遮擋其他內容。

效能與可訪問性

滾動包含 fixedsticky 內容的元素可能會導致效能和可訪問性問題。當用戶滾動時,瀏覽器必須在新的位置重繪粘性或固定內容。根據需要重繪的內容、瀏覽器效能和裝置處理速度,瀏覽器可能無法以 60 幀/秒的速度管理重繪。這種情況可能導致卡頓,更重要的是,會給有敏感性問題的人帶來可訪問性方面的擔憂。一種解決方案是在定位的元素上新增 will-change: transform,以在其自己的圖層上渲染元素,從而提高重繪速度,進而改善效能和可訪問性。

正式定義

初始值static
應用於所有元素
繼承性
計算值同指定值
動畫型別離散
建立層疊上下文

正式語法

position = 
static |
relative |
absolute |
sticky |
fixed |
<running()>

<running()> =
running( <custom-ident> )

示例

相對定位

相對定位的元素會從其在文件中的常規位置偏移一定的量,但這個偏移不會影響其他元素。在下面的示例中,請注意其他元素的放置方式,就好像“Two”仍然佔據其常規位置的空間一樣。

HTML

html
<div class="box" id="one">One</div>
<div class="box" id="two">Two</div>
<div class="box" id="three">Three</div>
<div class="box" id="four">Four</div>

CSS

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(初始包含塊)進行定位,即文件根元素的包含塊。

HTML

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="https://mdn.github.io/shared-assets/images/examples/long.jpg" />
</p>

CSS

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;
  inset-block-start: 30px;
  inset-inline-start: 30px;
}

結果

固定定位

固定定位與絕對定位類似,不同之處在於元素的包含塊是由視口建立的初始包含塊,除非任何祖先的 transformperspectivefilter 屬性被設定為非 none 的值(請參閱固定定位包含塊),這會導致該祖先取代元素包含塊的位置。這可以用來建立一個“浮動”元素,無論如何滾動,它都保持在相同的位置。在下面的示例中,盒子“One”被固定在距離頁面頂部 80 畫素和左側 10 畫素的位置。即使在滾動之後,它相對於視口的位置也保持不變。此外,當 will-change 屬性設定為 transform 時,也會建立一個新的包含塊。

HTML

html
<div class="outer">
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam congue tortor
    eget pulvinar lobortis. Vestibulum ante ipsum primis in faucibus orci luctus
    et ultrices posuere cubilia Curae; Nam ac dolor augue. Pellentesque mi mi,
    laoreet et dolor sit amet, ultrices varius risus. Nam vitae iaculis elit.
    Aliquam mollis interdum libero. Sed sodales placerat egestas. Vestibulum ut
    arcu aliquam purus viverra dictum vel sit amet mi. Duis nisl mauris, aliquam
    sit amet luctus eget, dapibus in enim. Sed velit augue, pretium a sem
    aliquam, congue porttitor tortor. Sed tempor nisl a lorem consequat, id
    maximus erat aliquet. Sed sagittis porta libero sed condimentum. Aliquam
    finibus lectus nec ante congue rutrum. Curabitur quam quam, accumsan id
    ultrices ultrices, tempor et tellus.
  </p>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam congue tortor
    eget pulvinar lobortis. Vestibulum ante ipsum primis in faucibus orci luctus
    et ultrices posuere cubilia Curae; Nam ac dolor augue. Pellentesque mi mi,
    laoreet et dolor sit amet, ultrices varius risus. Nam vitae iaculis elit.
    Aliquam mollis interdum libero. Sed sodales placerat egestas. Vestibulum ut
    arcu aliquam purus viverra dictum vel sit amet mi. Duis nisl mauris, aliquam
    sit amet luctus eget, dapibus in enim. Sed velit augue, pretium a sem
    aliquam, congue porttitor tortor. Sed tempor nisl a lorem consequat, id
    maximus erat aliquet. Sed sagittis porta libero sed condimentum. Aliquam
    finibus lectus nec ante congue rutrum. Curabitur quam quam, accumsan id
    ultrices ultrices, tempor et tellus.
  </p>
  <div class="box" id="one">One</div>
</div>

CSS

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 畫素的位置。

css
#one {
  position: sticky;
  top: 10px;
}

帶有粘性標題的列表

粘性定位的一個常見用途是按字母順序排列的列表中的標題。標題“B”會出現在以“A”開頭的專案下方,直到它們被滾動出螢幕。標題“B”不會隨其他內容一起滑出螢幕,而是會固定在視口的頂部,直到所有“B”項都滾動出螢幕,此時它將被標題“C”覆蓋,依此類推。

你必須使用 toprightbottomleft 中的至少一個來指定一個閾值,才能使粘性定位按預期工作。否則,它將與相對定位無法區分。

HTML
html
<dl>
  <div>
    <dt>A</dt>
    <dd>Andrew W.K.</dd>
    <dd>Apparat</dd>
    <dd>Arcade Fire</dd>
    <dd>At The Drive-In</dd>
    <dd>Aziz Ansari</dd>
  </div>
  <div>
    <dt>C</dt>
    <dd>Chromeo</dd>
    <dd>Common</dd>
    <dd>Converge</dd>
    <dd>Crystal Castles</dd>
    <dd>Cursive</dd>
  </div>
  <div>
    <dt>E</dt>
    <dd>Explosions In The Sky</dd>
  </div>
  <div>
    <dt>T</dt>
    <dd>Ted Leo &amp; The Pharmacists</dd>
    <dd>T-Pain</dd>
    <dd>Thrice</dd>
    <dd>TV On The Radio</dd>
    <dd>Two Gallants</dd>
  </div>
</dl>
CSS
css
* {
  box-sizing: border-box;
}

dl > div {
  background: white;
  padding-top: 24px;
}

dt {
  background: #b8c1c8;
  border-bottom: 1px solid #989ea4;
  border-top: 1px solid #717d85;
  color: white;
  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-left: 12px;
  white-space: nowrap;
}

dd + dd {
  border-top: 1px solid #cccccc;
}
結果

設定了所有內邊距邊界的粘性定位

以下示例演示了當所有內邊距邊界都設定時元素的行為。在這裡,我們在一個段落中有兩個燈泡表情符號。燈泡使用粘性定位,內邊距邊界被指定為距離頂部 50 畫素,右側 100 畫素,底部 50 畫素,左側 50 畫素。父級 div 元素上的灰色背景標記了內邊距區域。

HTML
html
Use scrollbars to put the light bulbs(💡) in the right place in the following
text:
<div>
  <p>
    The representation of an idea by a light bulb(<span class="bulb">💡</span>)
    is a commonly used metaphor that symbolizes the moment of inspiration or the
    birth of a new idea. The association between a light bulb and an idea can be
    traced back to the invention of the incandescent light bulb(<span
      class="bulb"
      >💡</span
    >) by Thomas Edison in the late 19th century. The light bulb is a powerful
    symbol because it represents illumination, clarity, and the sudden
    brightening of one's thoughts or understanding. When someone has an idea, it
    is often described as a light bulb turning on in their mind, signifying a
    moment of insight or creativity. The image of a light bulb also suggests the
    idea of energy, power, and the potential for growth and development.
  </p>
</div>
CSS
css
.bulb {
  position: sticky;
  inset: 50px 100px;
}

div {
  /* mark area defined by the inset boundaries using gray color */
  background: linear-gradient(#99999999, #99999999) 100px 50px / 192px 100px
    no-repeat;
}
結果

當你將兩個燈泡都放在它們正確的位置時,你會注意到它們在內邊距區域內是相對定位的。當你將它們移出內邊距區域時,它們會被固定(粘性定位)到該方向的內邊距邊界。

規範

規範
CSS 定位佈局模組第 3 級
# position-property

瀏覽器相容性

另見