AI下拉選單生成器。

描述你的選項,MeDo即可生成完整選單 — 觸發器、面板、帶分隔線的分組區塊、子選單、方向鍵與首字母跳轉、Escape與點擊外部關閉,以及關閉時焦點返回觸發器。

下拉選單
下拉選單

選單只佔一個Tab停駐點,而這正是大家最常做錯的地方

直覺會讓人把每個選項都設為可聚焦,於是Tab會逐項走過去。ARIA menu模式恰恰相反:整個選單只是一個Tab停駐點,方向鍵在選項之間移動roving tabindex,而Tab會關閉選單並離開。正因如此,略過一個12項的帳戶選單只需按一次鍵,而不是十二次。這也解釋了選單為何需要明確的焦點還原:焦點是由程式移入面板的,若關閉時不把它送回觸發器,鍵盤用戶就會被丟在文件頂部。把觸發器與面板作為同一個元件生成,能保住這趟往返,因為兩半是依同一套焦點約定寫成的。

6 個模板

可以產生的 下拉選單 模板

每個模板都是真實的提示詞,而非截圖。複製到任何 AI 編輯器,或在 MeDo 中執行,直接取得 React + Tailwind 程式碼。

BasicAccount Menu

Avatar Trigger With Grouped Actions

The top-right menu every product has. Get the focus round trip right here and the rest of your menus inherit it — closing without returning focus drops keyboard users at the top of the document.

Create an account dropdown menu: a 32px avatar trigger with aria-haspopup="menu" and aria-expanded, and a 240px panel with role="menu" anchored 6px below it. Each row is role="menuitem", 32px tall, with a 16px leading icon. Use a roving tabindex so the whole menu is one tab stop — Tab closes it and leaves rather than walking the items. Enter, Space or Arrow Down opens the menu and focuses the first item; Arrow Up opens it focusing the last. Arrow Down and Up cycle with wrapping, Home and End jump to the ends, typing a letter jumps to the next item starting with it, Escape and outside pointerdown close it, and focus returns to the trigger on every close path. Group items with 1px dividers and style Sign out as a destructive red item in its own group.

在 MeDo 中試試
Table rowRow Overflow

Three-Dot Menu on a Table Row

Repeated once per row, which makes the trigger label the real problem: twenty buttons all called "More options" tell a screen reader user nothing about which record they are about to delete.

Create a row-level overflow menu for a data table: a 32px icon-only three-dot trigger with aria-haspopup="menu", aria-expanded, and an accessible name that names its record — "More actions for invoice 1042" — so repeated triggers are distinguishable. The panel is role="menu" with Edit, Duplicate and Export, then a divider and a destructive Delete that opens a confirmation dialog and moves focus into it rather than acting immediately. Roving tabindex, Arrow Up and Down with wrapping, Home and End, single-letter type-ahead, Escape and outside pointerdown to close, focus back to the trigger. Close the menu when its ancestor scroll container scrolls, since an anchored panel detaches from a row that has moved.

在 MeDo 中試試
NestedSubmenu

Parent Items With Nested Panels

One level of nesting, with a hover intent delay. Without the delay, dragging the pointer diagonally to the item you wanted opens and closes three submenus on the way there.

Create a dropdown menu with one level of submenus: the parent item carries aria-haspopup="menu", aria-expanded and a trailing chevron, and its child panel is a separate role="menu" anchored to the parent's right edge, flipping to the left when it would leave the viewport. Open the submenu on Arrow Right or Enter with focus on the first child, and on hover after a 150ms intent delay with a similar grace period before closing so a diagonal pointer path does not toggle three panels. Arrow Left closes the submenu and returns focus to the parent item; Escape closes the whole menu and focuses the trigger. Keep type-ahead scoped to the currently open panel, and do not nest a second level.

在 MeDo 中試試
TogglesCheckable Items

Menu With Checkbox and Radio Rows

View options and sort order inside a menu. The roles change with the semantics — menuitemcheckbox for independent toggles, menuitemradio in a group for one-of-many — and so does whether the panel closes on select.

Create a view-options dropdown mixing checkable rows: a group of role="menuitemcheckbox" rows with aria-checked for column visibility, and below a divider a group of role="menuitemradio" rows inside role="group" with aria-labelledby a Sort by heading, where exactly one is aria-checked. Keep the panel open when a checkbox row is toggled so several can be set in one pass, and close it after a radio selection since the choice is complete. Reserve the check indicator column at a fixed width so labels do not shift when a state changes. Roving tabindex, Arrow Up and Down with wrapping, Home and End, Space toggles without closing, Enter selects, Escape closes and returns focus to the trigger.

在 MeDo 中試試
NavigationNav Disclosure

Header Dropdown of Plain Links

Deliberately not a menu. A products dropdown holds links, so role="menu" would collapse them into one tab stop and stop cmd+click from opening a new tab.

Create a navigation dropdown for a marketing header that is a disclosure, not an ARIA menu: a trigger button with aria-expanded and aria-controls, and a panel containing a plain ul of anchor elements — no role="menu" or role="menuitem", so each link stays individually focusable and openable in a new tab with cmd+click or middle click. Tab moves through the links in order rather than a roving tabindex. Open on click and on Arrow Down, close on Escape with focus returning to the trigger, close on outside pointerdown, and close on focusout when focus leaves the panel entirely. Do not open on hover alone on touch devices. Mark the link matching the current route with aria-current="page".

在 MeDo 中試試
FilterableSearch Menu

Long Menu With a Filter Field

Past roughly fifteen items, single-letter type-ahead stops being enough. Adding a text field changes the contract: the field keeps focus and the highlight moves by aria-activedescendant.

Create a filterable dropdown for a long list: a trigger with aria-haspopup and aria-expanded, and a panel whose first element is a search input that receives focus on open. Because a text field now holds focus, switch from a roving tabindex to the combobox approach — role="listbox" on the list, role="option" on rows, and aria-activedescendant on the input so Arrow Up and Down move the highlight while typing keeps working. Filter as the user types with a 150ms debounce, bold the matched substring, cap the list at 280px with internal scroll, and scroll the active option into view with block nearest. Show a no-matches row rather than an empty panel. Escape clears a non-empty filter first, then closes on a second press with focus returning to the trigger.

在 MeDo 中試試

如何自訂你的 下拉選單

說明這是操作選單,而非<select>

role="menu"告訴輔助技術每一項都會執行一個指令。如果這些項目其實是設定表單值,就要求使用listbox或原生<select>。把選單當作表單欄位使用,會令螢幕閱讀器在用戶期待選項的地方讀出指令。

為子選單指定游標停留意圖延遲

要求子選單展開前約有150ms延遲,收起前有相近的寬限時間。缺少它,斜向拖動游標經過上層清單時,在到達目標之前會連續展開又收起三個子選單。

明確要求避免超出視窗的定位

說明面板在接近底部邊緣時應翻轉到觸發器上方,並水平位移以維持可見。選單錨定在右上角頭像上,是固定偏移導致一半選項渲染到畫面外的最常見情況。

把破壞性選項獨立分開

把登出、刪除、撤銷存取權等操作放在分隔線下方的獨立分組,並要求破壞性配色處理。真正防止誤觸的是與日常選項之間的物理距離,而不是紅色文字。

誰在使用 下拉選單 組件

SaaS產品

右上角的頭像選單,以帳戶電郵作為靜態標題列,下方是個人檔案與帳單連結、團隊子選單、主題切換,以及分隔線下獨立分開的登出。

儀表板或管理工具

三點圖示按鈕背後的列級溢出選單,包含編輯、複製、匯出以及破壞性的刪除,觸發器由所屬列來標註,讓螢幕閱讀器讀出正在操作哪一筆記錄。

內容編輯器

區塊插入選單,包含分組的項目類型、嵌入服務供應商的子選單,以及首字母跳轉,熟悉清單的人無需用方向鍵逐項翻找即可直達目標項目。

行銷網站導覽

導覽列中的產品下拉選單,用普通連結清單而非role="menu"建立,這樣面板的行為就與它本身的導覽性質一致,連結仍可單獨聚焦並在新分頁開啟。

不同網站的 下拉選單 方案

同一個 下拉選單 組件,針對它所在網站的類型作調整。

01 / 06

SaaS Account Menu

Avatar trigger, the account email as a static non-focusable header row, then profile and billing links, a team submenu and Sign out below a divider. Keep the email row out of the roving tabindex — a label that takes an arrow keypress to skip reads as a broken menu item.

下拉選單 的風格與變體

挑選與頁面其餘部分相襯的變體,然後產生它。

01 / 06

Grouped Action Menu

Rows split into two or three sections by 1px dividers, with the destructive action alone at the bottom. The physical gap is what prevents the misclick on Sign out or Delete — red text alone does not, because the pointer is already moving before the color registers.

在 React、Next.js、Vue 與 Svelte 中使用 下拉選單

React、Next.js、Vue 3、SvelteKit、Astro 或純 HTML —— 同一個 下拉選單,六種接入方式。

01 / 06

React Dropdown Menu

Hold the active index in state and derive tabIndex from it — that is the roving tabindex. Keep a ref to the trigger and focus it in the close handler, since the browser will not restore focus for you.

src/components/Menu.tsx

const [open, setOpen] = useState(false)
const [active, setActive] = useState(0)
const triggerRef = useRef(null)

function close() {
  setOpen(false)
  triggerRef.current?.focus()
}

<button ref={triggerRef} aria-haspopup="menu" aria-expanded={open}>
  Account
</button>

如何把 下拉選單 加入專案

四個步驟,從挑選 下拉選單 模板到推上生產環境。

01~30s

Pick a Menu Template

Answer one question first: do the items run commands or navigate? Actions get the menu templates and their roving tabindex; links get the navigation disclosure, where every anchor stays its own tab stop.

02~10s

Copy the Prompt

Take the prompt into MeDo, Lovable, Bolt, v0 or Cursor and list your real items with the dividers where you want them. Say which item is destructive and which opens a submenu, since both change the generated markup.

03~1min

Generate and Refine

You get React + Tailwind back with a live preview. Follow up in plain English — "add a filter field", "flip above the trigger near the bottom edge", "turn Sort into radio items" — instead of touching the keydown handler.

04~2min

Wire the Actions and Ship

Connect each item to its handler, then verify the focus round trip with the keyboard alone: open, arrow down, Escape, and confirm focus lands back on the trigger rather than the top of the page.

關於 下拉選單 的常見問題

如何用AI生成下拉選單?

列出你想要的選項,標明哪些會展開子選單,並說明分隔線的位置。MeDo會把觸發器、錨定面板、分組項目與鍵盤處理作為一個元件生成,因此在你首次開啟之前,方向鍵、Escape、點擊外部與焦點還原就已經接好了。

下拉選單與<select>有甚麼分別?

選單用於執行操作:選中一項會即刻做某件事,而且不會儲存任何內容。<select>持有表單值:選中一個選項會改變稍後隨表單提交的狀態。兩者使用不同的role與不同的鍵盤約定,把其中一個當成另一個使用,是自訂下拉元件中最常見的無障礙缺陷。

導覽下拉選單應該使用role="menu"嗎?

不應該。role="menu"是為應用程式式的指令選單而設,把它套在連結清單上會令每個連結被讀成menuitem,同時把它們壓縮成一個Tab停駐點。導覽下拉選單應該是一組普通錨點連結,放在由觸發器透過aria-expanded切換的展開區域內。告訴MeDo這個面板屬於導覽,它就會生成連結而非選單項目。

下拉選單的鍵盤導覽應該怎樣運作?

Enter、Space或Arrow Down開啟選單並聚焦首項。Arrow Up與Down在選項之間移動並在兩端循環,Home與End跳至首項與末項,輸入字母則移至以該字元開頭的下一項。Arrow Right展開子選單,Arrow Left收起它,Escape或Tab關閉整個選單並把焦點交還觸發器。

AI可以生成帶子選單的下拉選單嗎?

可以。描述巢狀結構,MeDo會生成帶aria-haspopup的父項目、子面板、游標停留意圖延遲,以及Arrow Right與Arrow Left的按鍵綁定。盡可能只保留一層巢狀,因為第二層用游標難以命中,也難以向螢幕閱讀器用戶描述。

下拉選單需要在點擊外部時關閉嗎?

需要,而且還應在按Escape、上層容器滾動以及再次點擊觸發器時關閉。把外部監聽綁在pointerdown而非click上,這樣從面板外開始的拖動也會關閉它;並且始終把焦點交還觸發器,避免鍵盤用戶被丟在頁面頂部。