📋 目錄
如果你寫 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;
}
這個方法的問題
- 瑣碎:每次都要記住三行
- 需要計算:transform 的 -50% 需要知道元素尺寸
- 不支持 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 中穩定)允許你同時設定 top、right、bottom、left:
.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-self 是 align-self 和 justify-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 行 | 需要 | 不支持 |
| Flexbox | 3-4 行 | 不需要 | 支持 |
| Grid | 3 行 | 不需要 | 支持 |
| 新方法(inset + place-self) | 2 行 | 不需要 | 支持 |
Flexbox 方法對比
/* Flexbox 置中 */
.parent {
display: flex;
align-items: center;
justify-content: center;
}
.child {
/* 不需要 position: absolute */
}
Flexbox 的問題:父層需要設定 flex 屬性,有時候與其他佈局衝突。
新方法的優勢
- 不需要改變父層的 display
- 只影響目標元素
- 語義清晰:明確表達「絕對定位 + 置中」
實際應用場景
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;
/* 父層只需要這個 */
}
瀏覽器支援
inset 和 place-self 都已獲得所有主流瀏覽器的穩定支援:
| 屬性 | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
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 設為父層範圍,然後在其中間置中」——這更接近你對瀏覽器說的話。
三行程式碼,解決十年的瑣碎。
延伸閱讀
- CSS 2026 進化論 — CSS 最新功能總覽
- Container Queries 元件級響應式 — 響應式設計新標準
本文是「2026 CSS 實用技術」系列文章之一。