Back to compare picker

Expandable row vs Table vs Details panel vs Accordion

Choose expandable row when each visible row already identifies a record and users need occasional row-owned details, history, exceptions, nested attributes, or secondary actions without leaving the data surface.

Decision dimensions

Dimension Expandable rowTableDetails panelAccordion
UI or UX UI + UX - Row-owned inline detail disclosure inside a table or listUI + UX - Semantic row-and-column data comparison surfaceUI + UX - Persistent selected-object inspection panelUI + 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.

Expandable row

UI or UX
UI + UX - Row-owned inline detail disclosure inside a table or list
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.
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.
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.
Bad UI
Every table row has a chevron, but some rows open nothing and others reveal unrelated page help.
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.
Bad UX
Filtering a queue keeps the third visual row open after the data changes, exposing details for a different customer.
Best fit
A row has supplemental detail that is useful for some records but would make the default table or list too dense.
Avoid when
The hidden data is a core column users must compare across rows.
Required state
Collapsed row with row identity, key values, and a labelled expand control.
Accessibility burden
Use a real button or native disclosure control for expansion and expose expanded or collapsed state.
Common misuse
Hiding primary columns or required decision data inside collapsed detail.

Table

UI or UX
UI + UX - Semantic row-and-column data comparison surface
UI guidance
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.
UX guidance
Use tables when aligned columns help users compare records, find exceptions, audit values, or triage work faster than opening each item.
Good UI
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.
Bad UI
A div layout looks like columns but has no caption, table semantics, or header associations.
Good UX
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.
Bad UX
Filtering the table removes selected rows without explaining why or offering a clear-filter path.
Best fit
Records share comparable attributes that users need to scan in aligned columns.
Avoid when
The content is layout, not data.
Required state
Default table state with caption, visible headers, row values, and result count or context.
Accessibility burden
Use native table semantics for tabular data rather than div-only rows.
Common misuse
Using table markup to create page columns or layout spacing.

Details panel

UI or UX
UI + UX - Persistent selected-object inspection panel
UI guidance
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.
UX guidance
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.
Good UI
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.
Bad UI
A panel titled Details shows metrics from the previously selected record after the list selection changes.
Good UX
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.
Bad UX
Sorting the list silently clears the highlighted row while the panel continues to show an old ticket.
Best fit
Users repeatedly inspect selected records, tickets, alerts, files, assets, tasks, comments, or locations while staying in a work surface.
Avoid when
The content is just a short temporary preview before navigation.
Required state
No selection state with a clear prompt or preserved last-selection rule.
Accessibility burden
Name the panel region from the selected object's title or a heading that includes the object identity.
Common misuse
Showing a details panel with no selected-object identity.

Accordion

UI or UX
UI + UX - Grouped show-hide sections for related page content
UI guidance
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 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
A product policy page shows Shipping, Returns, Warranty, and Contact sections as heading buttons with clear expanded states and one open panel.
Bad UI
A page hides every required instruction behind plus icons with no headings, state, or expand-all route.
Good UX
A user opens Returns, then Warranty, scans both sections, collapses Returns, and the page keeps focus and open-state feedback stable.
Bad UX
A user misses eligibility requirements because the only required step is hidden inside a collapsed section by default.
Best fit
A page has several related sections and users do not need all details visible at once.
Avoid when
There is only one revealable section and a simpler details disclosure is enough.
Required state
All collapsed state with every section title visible.
Accessibility burden
Use native buttons for section controls and expose expanded or collapsed state.
Common misuse
Using divs or links as section toggles without button semantics or expanded state.
Decision rules
  • Choose expandable row when each visible row already identifies a record and users need occasional row-owned details, history, exceptions, nested attributes, or secondary actions without leaving the data surface.
  • Choose table when the values are important enough to compare across many records and should remain visible as columns rather than hidden under each row.
  • Choose details panel when users repeatedly move through records and need a persistent inspector that stays visible beside the source rows instead of expanding one row at a time.
  • Choose accordion when the content is page-level sections or form groups, not detail owned by a specific table, list, or activity row.
  • Use expandable row for compact supplemental content; route to details panel, drawer, or full page when the expanded area needs long reading, deep editing, comments, history, or several unrelated panels.
  • Keep row expansion state keyed by stable record ID so sorting, filtering, pagination, refresh, or virtual loading does not open detail under the wrong row.
  • Expose a labelled row expand control with expanded state, affected row identity, and a content region that follows the owning row in reading order.
  • Do not put the only critical decision value, required error, destructive confirmation, or primary action inside a collapsed row unless the collapsed row summarizes it visibly.
  • When rows have no extra detail, omit or disable the expand control with a visible reason rather than showing a dead chevron.
  • On mobile, use stacked expanded detail, row-level disclosure, or a full-detail route instead of forcing a wide nested table that loses row-header meaning.
Inspect live examples
Failure modes
  • A collapsed row hides the only status reason, so users think every row is equivalent until they manually expand each one.
  • Sorting the table leaves the second visual row expanded even though the detail belongs to a different record after the sort.
  • Every row has an expand chevron, including rows with no extra detail, causing dead controls and false affordances.
  • Expanded content contains a long form, nested table, comments, attachments, and destructive actions that no longer fit a row-local disclosure.
  • A page-level FAQ or settings section is implemented as expandable table rows even though no row owns the content.
  • The expand button only says More, has no expanded state, and does not identify which record will be opened.