安安~我是ChiYu~
昨天把資料值和命令分開後,我從 Command Palette 執行「檢視專案結構」。AI 很快交出一張有箭頭、有縮排,點下去也會展開的畫面。
昨天結尾先停在這個錯誤現場。這張圖是依照第一版問題重建的畫面,不含真實資料:

圖 1:和昨天結尾是同一張畫面。元件盤點計畫、專案備註與附件共用相同箭頭和縮排,全被算成設計系統組的孩子。
乍看就是一棵樹。
再看仔細一點,子專案、附件、檢核紀錄和備註全部都住在下一層。只要往右縮排兩格,任何資料突然都能變成孩子。
原始需求確實留了很大的發揮空間:
「請把部門、專案和任務做成樹狀,點開後可以看細節。」
部門底下有專案,這是父子關係;任務底下顯示一段備註,卻只是同一筆資料的補充。兩者都能使用箭頭展開,操作意義完全不同。Vibe Coding 若只說「做成樹狀」,AI 多半會先完成箭頭和縮排,至於展開後到底是下一層還是更多明細,就看畫面怎麼塞得下。
今天要把 Tree View、Nested List、Treegrid 與 Expandable Row 分開。它們都能表達某種層次,選型依據不是箭頭長什麼樣,而是資料之間到底有沒有父子關係。
我把四種做法放進 Vibe UI Atlas 的階層資料比較頁。先看同樣的縮排和展開動作,在不同資料關係下會變成什麼元件。

圖 2:箭頭只說「這裡可以展開」,沒有回答展開的是孩子資料,還是目前這列的補充。
這一題沒有先講清楚,後面不管叫 AI 做 Tree View 還是 Treegrid,都只是在替錯的資料關係挑造型。
我會先拿 LumenDesk 的「產品與設計中心」做測試。它底下有產品策略組、設計系統組,每個組別再包含各自的專案。展開設計系統組後,才看得到「元件盤點計畫」。這些資料有真正的父子關係,適合 Tree View。
另一邊,專案任務表裡有一筆「活動頁無障礙檢查」。按下「檢核明細」後出現完成項目、備註與附件。那些內容無法離開這筆任務獨立存在,它們只是同一列的更多資訊,Expandable Row 會比較直白。
判斷時,我不再只問「刪掉目前這列後,展開內容還在不在」。有些系統會連孩子一起刪除,光靠刪除結果,很容易把真正的父子資料也誤判成明細。
我會改問兩件事:展開項目有沒有自己的識別、狀態與生命週期?它能不能在其他流程中被搜尋、選取或移動?如果答案是可以,而且確實隸屬於目前節點,通常是父子資料。若內容只用來解釋這筆任務,離開目前列就沒有獨立意義,多半是明細。
刪除測試仍可當輔助證據,只是不再一題定生死。資料模型如果本來就設定串聯刪除,它可不會好心提醒我「孩子其實有身分」。
再加上「需不需要比較多欄資料」,四種元件就能排回自己的位置:
| 資料關係 | 使用者真正要做的事 | 適合的元件 |
|---|---|---|
| 部門底下有小組,小組底下有專案 | 逐層走進真正的孩子資料 | Tree View |
| 文件有章節、子章節與條列內容 | 順著閱讀順序理解內容層次 | Nested List |
| 專案有子任務,也要比較負責人、狀態與截止日 | 展開階層,同時對齊多欄資料 | Treegrid |
| 任務列下面顯示附件、備註與檢核紀錄 | 暫時查看同一筆資料的補充 | Expandable Row |
如果習慣看流程圖,也可以從這張選型地圖開始:

圖 3:先判斷是不是父子資料,再問要不要對齊多欄;沒有互動需求時,Nested List 已經夠用。
箭頭放左邊還是右邊可以晚點決定。先把這張關係卡交給 AI,畫面才不會把備註硬認成子專案。
Tree View 元件頁示範部門、群組與專案的父子關係。父節點可以展開,葉節點則沒有下一層。

圖 4:焦點表示鍵盤目前會操作哪裡,選取表示已保存的節點,展開則控制孩子是否可見。
Tree View 適合資料夾、組織、分類與專案群組。它真正麻煩的地方不是縮排,而是焦點、選取和展開很容易被 AI 合成同一個藍色底。
焦點是鍵盤下一步會作用的位置;選取是使用者已經選定的資料;展開只表示孩子目前看不看得到。W3C 的 Tree View Pattern 把焦點與選取視為不同概念,但也允許部分單選 Tree 使用「焦點跟著選取」;多選 Tree 則必須把兩者分開。W3C WAI-ARIA APG:Tree View Pattern
LumenDesk 這次刻意選擇分離模式,因為管理員要先用方向鍵查看其他節點,再決定是否改變目前專案。方向鍵只移動焦點,Enter 才執行目前節點的預設動作;在這個單選 Demo 裡,葉節點的預設動作是選取,父節點則交給左右方向鍵展開或收合。這是本案例的互動合約,不是所有 Tree View 都必須照抄。
你可以直接到 Tree View 操作 Demo先選一個專案,再按方向鍵。焦點移走後,原本選取的專案應該留下;收合父節點時,焦點也不能掉在已經看不見的孩子身上。
2026 年 7 月 24 日,網站初始選取「LumenCore 平台」。我把焦點放到這個節點,再按 Arrow Down,焦點移到下一筆「行動應用程式」,aria-selected 仍留在 LumenCore。
這一段符合預期:焦點只是準備操作的位置,選取才是已保存的結果。
但頁面下方的摘要從「目前選取:LumenCore 平台」變成「目前選取:◇」。它抓到的是圖示文字,不是節點名稱;瀏覽器 Console 同時出現三筆 SVG viewBox 格式錯誤。
所以第一輪只能拆開判斷:
| 檢查項目 | 2026 年 7 月 24 日結果 | 當時判斷 |
|---|---|---|
| Arrow Down 移動焦點 | 焦點移到下一個可見節點。 | 通過。 |
| 選取是否跟著焦點改變 | LumenCore 仍維持選取。 | 通過。 |
| 選取摘要 | 顯示成「◇」。 | 未通過,節點名稱取值錯誤。 |
| Console | 出現三筆 SVG viewBox 錯誤。 |
未通過,圖示輸出需要修正。 |
如果我只看箭頭有沒有開合,這兩個 bug 都會被放過。寫 Prompt 時除了鍵盤規則,還要交代選取資料從哪個欄位取得、摘要顯示哪個名稱,最後再打開 Console 看一眼。畫面會動,只代表它真的會動。
後續修正把摘要改成讀取真正的節點名稱,也替五個展開圖示補上 viewBox="0 0 24 24"。
2026 年 7 月 27 日重新載入後,選取摘要會顯示節點名稱,Console 不再出現 SVG 格式錯誤;用方向鍵移動焦點時,原本的選取狀態也會保留。
目前已通過節點名稱、焦點/選取分離與 Console 複測。正式螢幕閱讀器實聽仍未完成,所以文章不會把「鍵盤操作正常」直接寫成所有輔助科技都通過。摘要顯示「◇」和三筆 Console 錯誤是歷史上曾失敗的結果,並不是目前仍存在的問題。
層級如果深到使用者一直展開、展開、再展開,也別急著繼續美化 Tree View。那可能是資訊架構需要搜尋、篩選、Breadcrumb 或獨立詳細頁,不是再多縮排兩格就能救回來。
文件目錄、條款清單與靜態分類說明也有層次,但讀者通常只想順著內容往下讀。Nested List 元件頁保留標題與縮排,不另外加入展開控制。

圖 5:整個內容結構一次呈現,沒有目前選取、展開狀態與方向鍵走訪。
原生巢狀 <ul> 已經能表達未排序內容的階層關係。沒有「逐層操作資料」的需求時,清單語意與視覺縮排就足夠。MDN:<ul> HTML element
你可以在 Nested List 操作區看到它幾乎沒有什麼好操作。這反而是它的優點:少一個展開按鈕,就少一組狀態、焦點和例外狀況。
當 AI 自動替每個章節加上箭頭時,先問使用者是否真的需要收合。若目的只是讓段落看得出層級,Nested List 已經完成工作,不用強迫一份靜態目錄學會走路。
如果使用者除了專案名稱,還要比較負責人、狀態與截止日,單純的 Tree View 就不夠用了。Treegrid 元件頁把階層放在第一欄,其餘欄位維持對齊。

圖 6:第一欄展開專案與子任務,負責人、狀態和截止日仍能沿欄位比較。
Treegrid 的功能很完整,維護成本也最高。它同時處理表格、焦點移動、列選取、展開收合與手機欄位策略。W3C 將 Treegrid 定義為具有階層關係的資料格狀介面,鍵盤焦點可能停在列或儲存格上,互動規則得先決定清楚。W3C WAI-ARIA APG:Treegrid Pattern
若需求只是找到某個資料夾,我不會因為 Treegrid 看起來很像企業系統就選它。反過來,真的需要比較多欄時,也不要把狀態和日期全塞進 Tree View 的節點名稱。
在 Treegrid 操作 Demo裡,只有第一欄縮排。窄螢幕時,表格可以在自己的容器內橫向閱讀,整張頁面卻不能跟著左右漂移;若欄位真的太多,摘要或獨立詳細頁往往比把字壓碎更實用。
平面資料表裡,使用者有時只想多看一點目前任務的資訊。Expandable Row 元件頁用「活動頁無障礙檢查」示範檢核進度、備註和下一步。

圖 7:展開後仍是「活動頁無障礙檢查」這筆任務的內容,沒有憑空長出三個子任務。
Tree View 的箭頭表示往下一層走;Expandable Row 的按鈕則是把這筆資料說得更完整。按鈕名稱、展開狀態與被控制的明細區塊都要能對得起來。Expandable Row 操作 Demo裡的控制項因此會直接說明是在查看這一列的明細。
資料表本身仍要保留表格語意。HTML <table> 用於有列與欄的資料,<caption> 也能幫助使用者理解這張表的用途。MDN:<table> HTML element
收合之後,任務沒有失去孩子,因為它從頭到尾都沒有孩子。它只是把備註收回去了。
這份 Prompt 一次列出 Tree View、Treegrid 與 Expandable Row 的分界,是為了讓 AI 先理解關係。實際畫面只需要其中一種時,就刪掉其餘段落:
請為 LumenDesk 製作「產品與設計中心」的階層資料畫面。
資料關係:部門底下有專案,專案是部門的孩子,不是同一列的補充明細。
元件:使用 Tree View。父節點顯示可展開箭頭,沒有孩子的葉節點不要顯示假箭頭。
狀態:展開/收合、鍵盤焦點、已選取節點必須分開呈現;不要只靠顏色區分。
鍵盤:這個單選 Demo 採焦點與選取分離。Up/Down 只在可見節點間移動焦點;Right 展開或進入第一個孩子;Left 收合或回到父節點;Enter 執行目前節點的預設動作,葉節點的預設動作是選取。不要讓方向鍵經過每一筆時就改寫目前選取。
資料:設計系統組可展開,底下有「元件盤點計畫」;所有人名、日期、專案皆為虛構資料。
如果使用者還要比較負責人、狀態、截止日,請改用 Treegrid:只有第一欄縮排,其他欄保持對齊;手機版可讓表格容器局部橫向捲動,但整個頁面不可水平溢出。
如果只是展開同一筆任務的備註和檢核項目,請改用 Expandable Row,不要把明細偽裝成子節點。
Prompt 裡先寫「專案是部門的孩子」,比寫「箭頭使用 16px 灰色圖示」更能決定畫面會不會走偏。視覺可以再調,資料關係一開始寫錯,後面每一次展開都會繼續錯下去。
交付前,我會沿著資料關係和鍵盤狀態逐一檢查:
這份清單沒有檢查箭頭轉得夠不夠滑順。關係、狀態和焦點都正確後,動畫才輪得到上場。
現在,真正的部門、專案與任務父子關係進入 Tree View;需要同時比較多欄時才升級 Treegrid;同一筆任務的備註與檢核紀錄則回到 Expandable Row。Nested List 也不用為了看起來有功能,硬背一整套方向鍵操作。
這幾天,我們讓使用者找得到頁面、看得懂位置、切得開內容、執行得到命令,也能閱讀真正的資料階層。下一步,我按下成員列上的「停用帳號」,只留下另一句很熟悉的需求:
「按停用時跳出一個漂亮的彈窗。」
下面這張圖,是我依照第一版問題在網站上重建的錯誤現場,不含真實帳號與個人資料:

圖 8:彈窗只問「確定要停用嗎」,沒有說停用誰;初始焦點已經落在「確定」,背景卻仍然能點。外觀完成了,安全退出的規則還沒進場。
白色卡片、灰色遮罩和紅色提示全都到齊,看起來的確很像完成品。問題是,使用者不知道要停用誰、會失去什麼;按下 Escape 會不會取消、關閉後焦點回到哪裡,也沒有答案。更尷尬的是,危險操作先取得了焦點,背景卻還能繼續操作。
明天,我們就從這個彈窗開始,拆開 Dialog、Modal Dialog、Alert Dialog 與 Confirmation Dialog,也看看紅色按鈕出現以前,取消路徑到底有沒有先準備好。
<ul> HTML element,查閱於 2026-08-07。<table> HTML element,查閱於 2026-08-07。