| UI or UX | UI + UX - Row-owned inline detail disclosure inside a table or list | UI + UX - Semantic row-and-column data comparison surface | UI + UX - Persistent selected-object inspection panel | UI + UX - Grouped show-hide sections for related page content |
| UI guidance | Render an expandable row as a normal data row with a labelled expand control, visible expanded or collapsed state, stable row identity, and an adjacent detail region that visually and programmatically belongs to that row. | Render a table with a specific caption or heading, visible column headers, optional row headers, aligned values, consistent row actions, and enough spacing for scanability. | Render a details panel as a persistent side or adjacent region that names the currently selected object, shows high-value metadata, status, and local secondary actions, and keeps the object selection visible in the source list, table, map, board, or feed. | Render each section title as a real button inside an appropriate heading, expose expanded or collapsed state, and connect the button to the panel it controls. |
| UX guidance | Use expandable row when users mostly need the compact row list but occasionally need row-local detail to explain, verify, triage, or act on one record in context. | Use tables when aligned columns help users compare records, find exceptions, audit values, or triage work faster than opening each item. | Use a details panel when users need to select and compare nearby objects while keeping a durable inspection area visible, such as reviewing records, tickets, assets, alerts, comments, files, or map locations. | Use an accordion when a page has several related sections that users may inspect selectively while still needing an overview of all section labels. |
| Good UI | An invoice table shows an expand button labelled Show details for INV-2048; the expanded row reveals line items, exception reason, approval history, and a View invoice link below the owning row. | A payment review table has the caption June vendor payments, headers Vendor, Status, Due date, Amount, and Action, right-aligned amounts, and row actions labelled by vendor. | A ticket queue keeps TCK-2048 selected in the list and shows a right details panel with requester, severity, SLA, owner, activity, and Open full ticket. | A product policy page shows Shipping, Returns, Warranty, and Contact sections as heading buttons with clear expanded states and one open panel. |
| Bad UI | Every table row has a chevron, but some rows open nothing and others reveal unrelated page help. | A div layout looks like columns but has no caption, table semantics, or header associations. | A panel titled Details shows metrics from the previously selected record after the list selection changes. | A page hides every required instruction behind plus icons with no headings, state, or expand-all route. |
| Good UX | A reviewer expands a flagged invoice, reads the mismatch reason, copies the audit ID, sorts by amount, and the same invoice remains expanded because state is keyed by invoice ID. | A user sorts by Amount descending, filters to Pending, moves to page 2, and the table keeps its caption, active sort, active filter, row count, and selected payment context. | A keyboard user moves down a ticket list, the highlighted row and details panel update together, and focus remains in the list until the user chooses Open full ticket. | A user opens Returns, then Warranty, scans both sections, collapses Returns, and the page keeps focus and open-state feedback stable. |
| Bad UX | Filtering a queue keeps the third visual row open after the data changes, exposing details for a different customer. | Filtering the table removes selected rows without explaining why or offering a clear-filter path. | Sorting the list silently clears the highlighted row while the panel continues to show an old ticket. | A user misses eligibility requirements because the only required step is hidden inside a collapsed section by default. |
| Best fit | A row has supplemental detail that is useful for some records but would make the default table or list too dense. | Records share comparable attributes that users need to scan in aligned columns. | Users repeatedly inspect selected records, tickets, alerts, files, assets, tasks, comments, or locations while staying in a work surface. | A page has several related sections and users do not need all details visible at once. |
| Avoid when | The hidden data is a core column users must compare across rows. | The content is layout, not data. | The content is just a short temporary preview before navigation. | There is only one revealable section and a simpler details disclosure is enough. |
| Required state | Collapsed row with row identity, key values, and a labelled expand control. | Default table state with caption, visible headers, row values, and result count or context. | No selection state with a clear prompt or preserved last-selection rule. | All collapsed state with every section title visible. |
| Accessibility burden | Use a real button or native disclosure control for expansion and expose expanded or collapsed state. | Use native table semantics for tabular data rather than div-only rows. | Name the panel region from the selected object's title or a heading that includes the object identity. | Use native buttons for section controls and expose expanded or collapsed state. |
| Common misuse | Hiding primary columns or required decision data inside collapsed detail. | Using table markup to create page columns or layout spacing. | Showing a details panel with no selected-object identity. | Using divs or links as section toggles without button semantics or expanded state. |