---
title: "提示框被切掉了？用 @position-try 讓瀏覽器自己找位置 - Neil 的作品集"
description: "tooltip、選單靠近畫面邊緣就被切掉，以前要靠 JavaScript 計算翻面。position-try-fallbacks 和 @position-try 讓 CSS 自己處理：空間不夠就換位置。這篇用可以拖動錨點的互動範例，整理三種寫法、margin 會跟著翻、瀏覽器會記住位置、position-try-order，以及都放不下時會怎樣。"
canonical_url: "https://neillin.com/blog/position-try/"
last_updated: 2026-10-09
meta:
  author: Neil
  keywords: "無障礙網頁, 設計管理, 資料視覺化, UI, UX, 切版"
  "og:description": "tooltip、選單靠近畫面邊緣就被切掉，以前要靠 JavaScript 計算翻面。position-try-fallbacks 和 @position-try 讓 CSS 自己處理：空間不夠就換位置。這篇用可以拖動錨點的互動範例，整理三種寫法、margin 會跟著翻、瀏覽器會記住位置、position-try-order，以及都放不下時會怎樣。"
  "og:image": "https://neillin.com/_og/s/o_c5fb4cf672211168.png"
  "og:image:height": "600"
  "og:image:type": image/png
  "og:image:width": "1200"
  "og:title": "提示框被切掉了？用 @position-try 讓瀏覽器自己找位置 - Neil 的作品集"
  "twitter:image": "https://neillin.com/_og/s/o_c5fb4cf672211168.png"
---

> Index of every page on this site: [llms.txt](https://neillin.com/llms.txt)

:::

# 提示框被切掉了？用 @position-try 讓瀏覽器自己找位置

2026年10月9日  

[前端技術](https://neillin.com/blog?category=frontend "查看「前端技術」分類的所有文章")CSS前端開發無障礙瀏覽器支援

  

> 話說在前頭：文中的行為我都在 Chromium 上實測過，其他瀏覽器的細節可能不同，有講錯的地方歡迎指正。

## 前言

在 [popover 那篇](https://neillin.com/blog/popover-auto-manual-hint/)裡，tooltip 和選單是用錨點定位（Anchor Positioning）貼在按鈕旁邊的。當時我順手加了一行 `position-try-fallbacks: flip-block`，但沒有多解釋。

這一行解決的是一個老問題：提示框、下拉選單一靠近畫面邊緣，就會被切掉一半。以前的做法是用 JavaScript 量位置、算空間，不夠就翻到另一邊，Floating UI 這類套件的 `flip` 就是在做這件事。

這件事對無障礙也很重要。使用者把畫面放大到 200%、400% 的時候，可用的空間變得很小，提示框被切掉的機率也跟著變高。

`@position-try` 是 [CSS 與 HTML 技巧清單](https://neillin.com/blog/css-techniques-checklist)裡錨點定位的下一步，這次把它拆開來好好看。

先看一下你的瀏覽器支援度：

你的瀏覽器支援度

- `Anchor Positioning`偵測中（需要 JavaScript）
- `position-try-fallbacks`偵測中（需要 JavaScript）

## 一、動手試試

下面的虛線框就是畫面範圍。用滑桿移動「錨點」，提示框預設在錨點上方：

互動範例：用滑桿移動錨點，看提示框空間不夠時會怎麼做

錨點提示框

提示框位置偵測中（需要 JavaScript）

錨點水平位置錨點垂直位置

`position-try-order: most-height`（上下哪邊空間大就放哪邊）

目前套用的 CSS

```
.tip {
  position-anchor: --anchor;
  position-area: top;
  margin-bottom: 8px;
  position-try-fallbacks: flip-block;
}
```

此處為互動範例，請在網頁上操作。

可以這樣玩：

1. 先選「不設定」，把錨點拉到最上面：上方放不下，又沒有備案可以換。Chromium 141 會把提示框留在上方、直接被切掉；Chromium 153 則會把它推回範圍內，結果蓋住錨點。兩種都不是我們要的。
2. 換成 `flip-block`，再把錨點拉到最上面：提示框翻到下方了。
3. 接著把錨點拉回中間：提示框**還是留在下方**，沒有翻回去。再按「重新顯示提示框」，它才回到上方。這不是 bug，第四節會解釋。
4. 換成自訂 `@position-try`，把錨點拉到最上面：這次提示框會先跑到右邊。
5. 換回 `flip-block`，勾選 `position-try-order`，把錨點放在中間偏上一點（垂直位置大約 35）：上方明明放得下，提示框卻跑到下方。第五節會解釋。

## 二、三種寫法

`position-try-fallbacks` 是一個清單，瀏覽器會先用原本的位置，放不下就依序往後試，用第一個放得下的。清單裡可以放三種東西。

**1. flip 關鍵字：把原本的位置翻過去**

```
.tip {
  position-area: top;
  position-try-fallbacks: flip-block;
}
```

| 關鍵字 | 效果 | 實測（原本 → 翻面後） |
| --- | --- | --- |
| `flip-block` | 上下翻 | 上方 → 下方 |
| `flip-inline` | 左右翻 | 右邊 → 左邊 |
| `flip-start` | 沿對角線翻，上下和左右對調 | 上方 → 左邊 |

也可以組合，例如 `flip-block flip-inline` 代表上下、左右一起翻，適合放在角落的選單。

**2. 直接寫 `position-area` 的值**

```
.tip {
  position-area: top;
  position-try-fallbacks: bottom, right;
}
```

上方放不下就試下方，再不行就試右邊。簡單的情況這樣寫最直覺。

**3. 用 `@position-try` 自訂**

需要連 margin、尺寸一起換的時候，就用 `@position-try` 定義一組備案：

```
@position-try --right {
  position-area: right;
  margin: 0 0 0 8px;
  width: 12rem;
}

.tip {
  position-area: top;
  margin-bottom: 8px;
  position-try-fallbacks: --right, flip-block;
}
```

`@position-try` 裡只能寫跟位置有關的屬性：

| 可以寫的屬性 | 例子 |
| --- | --- |
| 錨點 | `position-anchor`、`position-area` |
| 定位 | `top`、`left`、`inset` 這類 |
| 外距 | `margin` 系列 |
| 尺寸 | `width`、`height`、`min-*`、`max-*` |
| 對齊 | `align-self`、`justify-self` |

我實測在 `@position-try` 裡寫 `background`，會直接被忽略，不會報錯，也不會套用。所以「翻到下方時換個顏色」這種需求，`@position-try` 做不到。

## 三、margin 會跟著翻

用 `flip-block` 的時候，不用擔心間距。我實測原本寫 `margin-bottom: 8px` 的提示框，翻到下方之後，瀏覽器會自動變成 `margin-top: 8px`，提示框和錨點之間一樣保持 8px，不會黏在一起。

所以 margin 只要寫在「面對錨點的那一邊」就好，翻面的時候會一起處理。自訂 `@position-try` 就不會自動翻了，要像上面的範例一樣自己寫 margin。

## 四、瀏覽器會記住上一次的位置

這是我實測時最意外的地方，也就是範例第 3 步看到的狀況。

提示框翻到下方之後，就算錨點移回中間、上方又放得下了，提示框**還是會留在下方**。要等到下方也放不下（例如把錨點拉到最下面），才會再翻回上方。

規格裡把這叫做記住「上一次成功的位置」。這樣設計是有道理的：如果使用者正在捲動頁面，提示框一下在上、一下在下來回跳，會很難閱讀，對認知障礙或容易分心的使用者更是困擾。

這個記憶什麼時候會清掉？我實測，元素被隱藏再顯示（`display: none` 再改回來）就會清掉，重新挑一次位置。popover 也一樣：關掉再打開，就會依當下的空間重新決定。範例裡的「重新顯示提示框」按鈕就是在模擬這件事。

所以對 popover 來說，每次打開都是重新開始；會用到這個記憶的，是打開之後還會跟著捲動、拖動的情況。知道有這回事，測試時才不會以為是 bug。

## 五、position-try-order：挑空間最大的

預設的規則是「原本的位置放得下就用」。但有時候你想要的是「哪邊空間大就放哪邊」，例如很長的下拉選單：

```
.menu {
  position-area: top;
  position-try-fallbacks: flip-block;
  position-try-order: most-height;
}
```

我實測，錨點在中間偏上、上方其實放得下的時候，加了 `most-height` 的選單會選擇空間比較大的下方。可以用的值有 `most-height`、`most-width`、`most-block-size`、`most-inline-size`。

要注意的是，它只在「重新挑位置」的時候才排序。我實測對一個已經顯示在上方、而且上方還放得下的元素加上 `most-height`，它不會動，要隱藏再顯示才會換到下方。這跟上一節的記憶是同一件事：已經放好的位置，只要還放得下就不會換。

也可以用簡寫 `position-try` 一次寫完：

```
.menu {
  position-try: most-height flip-block;
}
```

## 六、全部都放不下時

如果原本的位置和所有備案都放不下，瀏覽器會用**上一次成功的位置**；沒有記住的位置時（例如剛顯示、或重新顯示之後），才用原本的位置。

我另外做了一個很矮的範圍來測：先讓提示框翻到下方，再把範圍縮小到上下都放不下，提示框就留在下方被切掉。重新顯示之後，才回到原本的上方：Chromium 141 會超出範圍被切掉，Chromium 153 則會推回範圍內、蓋住錨點。

所以原本的位置，要設成「最常見、最合理」的那個。備案只是備案，不保證一定有地方放。

## 七、跟 popover 搭配

實務上最常用的組合，就是 popover 加上錨點定位。popover 開啟時會進入 top layer，這時候判斷「放不放得下」的範圍是整個視窗，正好就是我們要的：

```
<button popovertarget="menu" style="anchor-name: --menu-btn">更多</button>
<div id="menu" popover>…</div>
```

```
#menu {
  position-anchor: --menu-btn;
  position-area: bottom span-right;
  margin: 8px 0 0;
  position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
}
```

往下放不下就往上，往右放不下就往左，角落就兩個一起翻。這幾行就取代了以前整段的 JavaScript 定位邏輯。

不支援的瀏覽器怎麼辦？我的做法是用 `@supports (position-area: bottom)` 包起來，不支援時再用 JavaScript 定位， [popover 那篇](https://neillin.com/blog/popover-auto-manual-hint/)的範例就是這樣做的。

## 無障礙上要注意的事

- **只換畫面上的位置**：翻面不會改變 DOM 順序，報讀軟體唸的順序、鍵盤 Tab 的順序都不受影響。
- **提示框本身的規則還是要顧**：WCAG 1.4.13「滑鼠移入或聚焦時出現的內容」要求提示框可以關閉、滑鼠移上去不會消失、不會自己突然不見。位置放對了，這些還是要自己處理。
- **放大時更需要它**：畫面放大後空間變小，有沒有備案，差別會比平常更明顯。測試時記得把畫面放大到 200%、400% 看看。

## 結論

整理成幾句話：

- `position-try-fallbacks` 讓錨點定位的元素在空間不夠時，依序嘗試備案位置。
- 備案可以用 flip 關鍵字、 `position-area` 的值，或是 `@position-try` 自訂。
- `flip-block` 會連 margin 一起翻； `@position-try` 只能寫位置相關的屬性。
- 翻過去之後會記住位置，不會來回跳；隱藏再顯示（例如 popover 重新打開）才會重新挑。
- 想要「哪邊空間大放哪邊」，加上 `position-try-order: most-height`。
- 全部放不下時，會用上一次成功的位置；沒有的話才用原本的位置。

以前要引入一個套件、寫一堆事件監聽才做得到的事，現在幾行 CSS 就解決了。而且這件事對放大畫面的使用者特別有感，算是很實在的無障礙改善。

你的專案裡，提示框和選單還是用 JavaScript 定位的嗎？歡迎一起討論！

## 延伸閱讀

- [Popover 的 auto、manual、hint 到底差在哪？做個可以玩的範例來看看](https://neillin.com/blog/popover-auto-manual-hint/)
- [現在的 dialog 要怎麼寫？從 showModal() 到 command、closedby 一次整理](https://neillin.com/blog/dialog-modern-guide/)
- [現代 CSS 與 HTML 技巧整理清單：115 個特性、支援度與實驗優先序](https://neillin.com/blog/css-techniques-checklist/)

## 相關連結

- [MDN — position-try-fallbacks](https://developer.mozilla.org/en-US/docs/Web/CSS/position-try-fallbacks "另開新視窗")
- [MDN — @position-try](https://developer.mozilla.org/en-US/docs/Web/CSS/@position-try "另開新視窗")
- [MDN — 錨點定位的備案與條件隱藏](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_anchor_positioning/Try_options_hiding "另開新視窗")
- [WCAG 2.2 — 1.4.13 滑鼠移入或聚焦時出現的內容](https://www.w3.org/WAI/WCAG22/Understanding/content-on-hover-or-focus "另開新視窗")
- [Can I use（瀏覽器支援度查詢）](https://caniuse.com "另開新視窗")

```json
{"@context":"https://schema.org","@graph":[{"@id":"https://neillin.com/#website","@type":"WebSite","inLanguage":"zh-Hant-TW","name":"Neil 的作品集","url":"https://neillin.com/","workTranslation":{"@id":"https://neillin.com/en/#website"}},{"@id":"https://neillin.com/blog/position-try/#webpage","@type":"WebPage","description":"tooltip、選單靠近畫面邊緣就被切掉，以前要靠 JavaScript 計算翻面。position-try-fallbacks 和 @position-try 讓 CSS 自己處理：空間不夠就換位置。這篇用可以拖動錨點的互動範例，整理三種寫法、margin 會跟著翻、瀏覽器會記住位置、position-try-order，以及都放不下時會怎樣。","name":"提示框被切掉了？用 @position-try 讓瀏覽器自己找位置","url":"https://neillin.com/blog/position-try/","isPartOf":{"@id":"https://neillin.com/#website"},"potentialAction":[{"@type":"ReadAction","target":["https://neillin.com/blog/position-try/"]}]},{"@id":"https://neillin.com/#person","@type":"Person","jobTitle":"UI/UX 設計師","name":"Neil Lin","url":"https://neillin.com/","sameAs":["https://github.com/Neil-Lin"]},{"@id":"https://neillin.com/blog/position-try/#/schema/blog-posting/1","@type":"BlogPosting","dateModified":"2026-10-09","datePublished":"2026-10-09","description":"tooltip、選單靠近畫面邊緣就被切掉，以前要靠 JavaScript 計算翻面。position-try-fallbacks 和 @position-try 讓 CSS 自己處理：空間不夠就換位置。這篇用可以拖動錨點的互動範例，整理三種寫法、margin 會跟著翻、瀏覽器會記住位置、position-try-order，以及都放不下時會怎樣。","headline":"提示框被切掉了？用 @position-try 讓瀏覽器自己找位置","inLanguage":"zh-Hant-TW","keywords":"CSS, 前端開發, 無障礙, 瀏覽器支援","url":"https://neillin.com/blog/position-try/","author":{"@id":"https://neillin.com/#person"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://neillin.com/blog/position-try/"},"publisher":{"@id":"https://neillin.com/#person"}},{"@id":"https://neillin.com/blog/position-try/#/schema/breadcrumb-list/1","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"回首頁","item":"https://neillin.com/"},{"@type":"ListItem","position":2,"name":"部落格","item":"https://neillin.com/blog/"},{"@type":"ListItem","position":3,"name":"提示框被切掉了？用 @position-try 讓瀏覽器自己找位置","item":"https://neillin.com/blog/position-try/"}]}]}
```

## Sitemap

See the full [sitemap](https://neillin.com/sitemap.md) for all pages.
