CSSpositionabsolutecenterplace-selfinsetIMCB前端佈局

三分鐘學會:絕對定位元素置中的新方法

CSS 絕對定位置中完整教學!place-self: center 配合 inset: 0、IMCB 概念攻略。三分鐘學會必看指南!

· 4 分鐘閱讀

如果你寫 CSS 超過五年,你可能已經習慣了這個 pattern:把絕對定位的元素置中,需要 top: 50%; left: 50%; transform: translate(-50%, -50%)。這是正確的,但瑣碎的——每個專案都會看到這個重複的 pattern。CSS 現在有一個更好的方法:place-self: center 配合 inset: 0。三行程式碼,不需要 transform,不需要計算。


傳統方法:瑣碎的瑣碎

你熟悉的 pattern

.overlay {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* 還需要寬高 */
  width: 300px;
  height: 200px;
}

這個方法的問題

  1. 瑣碎:每次都要記住三行
  2. 需要計算:transform 的 -50% 需要知道元素尺寸
  3. 不支持 dynamic sizing:當內容動態變化時,置中可能偏移
/* 當寬高不固定時,傳統方法會出問題 */
.modal {
  position: absolute;
  top: 50%;
  left: 50%;
  /* 如果沒有固定寬高,會導致偏移 */
  transform: translate(-50%, -50%);
  padding: 2rem; /* 動態內容改變了尺寸 */
}

新方法:三行程式碼

基本語法

.overlay {
  position: absolute;
  inset: 0;         /* 1. 建立 IMCB */
  place-self: center; /* 2. 置中 */
}

就是這樣。兩行就足夠了。

實際範例:Modal 對話框

.modal {
  position: absolute;
  inset: 0;
  place-self: center;
  max-width: 500px;
  max-height: 80vh;
  padding: 2rem;
  background: white;
  border-radius: 12px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
  overflow: auto;
}
<div class="modal-overlay">
  <div class="modal">
    <h2>Hello</h2>
    <p>This modal is perfectly centered with just 2 lines of CSS.</p>
  </div>
</div>
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: grid;
}

.modal {
  /* 只需要這兩行 */
  place-self: center;
  /* 父層的 inset: 0 讓這裡的 place-self 生效 */
}

Inset-Modified Containing Block(IMCB)

什麼是 Containing Block

預設情況下,一個絕對定位元素的 Containing Block,是離它最近的一個 positioned 祖先元素(即 position 不為 static 的元素)。

Inset 如何修改它

inset 屬性(在 CSS 2023 中穩定)允許你同時設定 toprightbottomleft

.element {
  inset: 10px;          /* 所有四邊 */
  inset: 10px 20px;     /* 上下、左右 */
  inset: 10px 20px 30px; /* 上、左右、下 */
  inset: 10px 20px 30px 40px; /* 上、右、下、左 */
}

Inset 對 Containing Block 的影響

當你在一個絕對定位元素上使用 inset: 0 時:

.parent {
  position: relative;
}

.child {
  position: absolute;
  inset: 0; /* 讓 Containing Block 擴展到父層的全部範圍 */
}

inset: 0 的效果:讓元素的 Containing Block 等於父層的完整範圍。這就是所謂的 Inset-Modified Containing Block(IMCB)。

為什麼這很重要

過去,要讓一個絕對定位元素撐滿父層,你需要:

/* 過去的方式 */
.element {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  /* 四行設定 */
}

現在,一行就夠了:

.element {
  position: absolute;
  inset: 0; /* 一行代替四行 */
}

place-self:align-self + justify-self

語法

place-selfalign-selfjustify-self 的簡寫:

.element {
  place-self: center;     /* align-self: center; justify-self: center; */
  place-self: start end;  /* align-self: start; justify-self: end; */
  place-self: stretch;    /* align-self: stretch; justify-self: stretch; */
}

place-self: center 的效果

當一個絕對定位元素的 Containing Block 被 inset: 0 撐滿父層時,place-self: center 的效果:

.child {
  position: absolute;
  inset: 0;           /* Containing Block = 父層全部範圍 */
  place-self: center; /* 在這個範圍內置中 */
}

結果:元素在自己的 Containing Block(等於父層)內完全置中。


與其他置中方法的比較

方法程式碼行數需要計算支持動態尺寸
傳統(top/left/transform)3 行需要不支持
Flexbox3-4 行不需要支持
Grid3 行不需要支持
新方法(inset + place-self)2 行不需要支持

Flexbox 方法對比

/* Flexbox 置中 */
.parent {
  display: flex;
  align-items: center;
  justify-content: center;
}

.child {
  /* 不需要 position: absolute */
}

Flexbox 的問題:父層需要設定 flex 屬性,有時候與其他佈局衝突。

新方法的優勢

  1. 不需要改變父層的 display
  2. 只影響目標元素
  3. 語義清晰:明確表達「絕對定位 + 置中」

實際應用場景

1. Loading Spinner

.spinner-container {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background: rgba(0, 0, 0, 0.3);
}

.spinner {
  width: 48px;
  height: 48px;
  border: 4px solid rgba(255, 255, 255, 0.3);
  border-top-color: white;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

2. Full-screen Overlay

.overlay {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background: rgba(0, 0, 0, 0.8);
}

.content {
  place-self: center;
  max-width: 90vw;
  max-height: 90vh;
}

3. Tooltip

.tooltip {
  position: absolute;
  place-self: center;
  /* 需要一個 positioned 祖先 */
}

.tooltip-wrapper {
  position: relative;
  /* 父層只需要這個 */
}

瀏覽器支援

insetplace-self 都已獲得所有主流瀏覽器的穩定支援:

屬性ChromeFirefoxSafariEdge
inset✅ 87+✅ 66+✅ 14.1+✅ 87+
place-self✅ 所有✅ 所有✅ 所有✅ 所有

不需要任何 polyfill 或 fallback。


結語:更 idiomatis 的 CSS

inset: 0; place-self: center; 代表了 CSS 近年來的一個趨勢:用更少、更語義化的程式碼,表達同樣的意思

過去的 top: 50%; left: 50%; transform: translate(-50%, -50%) 是功能性的,但不是直觀的。新的方法說的是:「把這個元素的Containing Block 設為父層範圍,然後在其中間置中」——這更接近你對瀏覽器說的話。

三行程式碼,解決十年的瑣碎。


延伸閱讀

本文是「2026 CSS 實用技術」系列文章之一。