Selecting Entire Rows and Columns from the Keyboard

Permalink to "Selecting Entire Rows and Columns from the Keyboard"

In spreadsheet-like grids, users often need whole rows or columns: copy a column of amounts, delete three rows, format a column. Mouse users click row numbers or column letters. Keyboard users need equivalents, and spreadsheet conventions provide them: Shift+Space selects the row, Ctrl+Space selects the column. These shortcuts conflict with little else inside a grid, but they need clear feedback — selecting a column of 5,000 cells must not be silent.

This guide belongs to grid cell selection & clipboard.

Spec reference

Permalink to "Spec reference"
  • aria-selected on gridcells (cell selection) or rows (row selection); aria-multiselectable="true" on the grid.
  • SC 2.1.1 (A) — selection without a pointer.
  • SC 4.1.3 (AA) — selection size as a status message.
  • SC 1.4.1 (A) — selected cells distinguished by more than colour.
  • Spreadsheet conventions — Shift+Space (row), Ctrl+Space (column), Ctrl+A (all).
A whole-column selection Grid mock with the Amount column selected in every row and the focused cell at row 2; other columns unselected. A whole-column selectionInvoiceCustomerAmountStatusINV-1041Mesa Foods310.50PaidINV-1042Lund & Co1,240.00OverdueINV-1043Arden Ltd88.00PaidCtrl+Space on any Amount cell selects the whole column: "Column Amount selected, 240 cells".
Selection extends down the whole column; focus stays on one cell.

When to use — and when not to

Permalink to "When to use — and when not to"

Support row and column selection in grids with cell-level selection (spreadsheets, data editors). In record-oriented grids with row checkboxes, row selection via Space on the checkbox is enough; column selection rarely makes sense.

Do not use Ctrl+Space if your grid sits in an environment where it switches input methods (some CJK setups) without offering an alternative (a header button). The misapplication: selecting a column with a single keystroke and no announcement, followed by Delete clearing 5,000 cells silently.

Silent selection versus announced selection Comparison: silent whole-column selection risks destructive mistakes; announced selection states size and range so users know what the next action affects. Silent selection versus announced selection✗ SilentColumn selected with no feedbackDelete clears 240 cells unexpectedlyVisual tint onlyNo way to check the range✓ Announced"Column Amount selected, 240 cells"Users know the scope firstTint plus outline; aria-selectedRange readable via status or Name Box

Annotated code example

Permalink to "Annotated code example"
grid.addEventListener('keydown', (e) => {
  const { row, col } = active();
  if (e.key === ' ' && e.shiftKey && !e.ctrlKey) {               // select row
    e.preventDefault(); selectRange({ rows: [row, row], cols: [0, colCount - 1] });
    status.textContent = `Row ${row + 1} selected, ${colCount} cells`;                  // SC 4.1.3
  }
  if (e.key === ' ' && (e.ctrlKey || e.metaKey) && !e.shiftKey) { // select column
    e.preventDefault(); selectRange({ rows: [0, rowCount - 1], cols: [col, col] });
    status.textContent = `Column ${headerName(col)} selected, ${rowCount} cells`;
  }
});

function selectRange({ rows, cols }) {
  selection = { rows, cols };
  for (const cell of renderedCells()) {
    const inRange = within(cell.row, rows) && within(cell.col, cols);
    cell.el.setAttribute('aria-selected', String(inRange));      // rendered cells only; virtual rows read from state
  }
}
[role="gridcell"][aria-selected="true"] { background: var(--selected-bg); box-shadow: inset 0 0 0 1px var(--brand-strong); }  /* not colour only */

Keyboard & AT behaviour

Permalink to "Keyboard & AT behaviour"
Key Action Expected announcement
Shift+Space Select row “Row 3 selected, 8 cells”
Ctrl+Space Select column “Column Amount selected, 240 cells”
Shift+Down after row selection Extend rows “Rows 3 to 5 selected”
Shift+Right after column selection Extend columns “Columns Amount to Status selected”
Ctrl+A Select all “All 1,920 cells selected”
Escape Clear selection “Selection cleared”
Selection shortcuts across tools Matrix of shortcuts — Shift+Space, Ctrl+Space, Ctrl+A, clicking headers — against Excel, Google Sheets and recommended web grid behaviour. Selection shortcuts across toolsExcelGoogle SheetsWeb gridShift+SpaceSelect rowSelect rowSelect rowCtrl+SpaceSelect columnSelect columnSelect columnCtrl+ASelect allSelect allSelect allClick headerSelect row or columnSelect row or columnButton in header
Following familiar conventions reduces learning.

Integration context

Permalink to "Integration context"

Range announcements follow announcing rectangular cell range selection; extending ranges in extending selection with Shift and arrow keys. Where to put aria-selected is covered in aria-selected on cells versus rows. Copying the selection uses keyboard copy and paste in data grids.

Gotchas

Permalink to "Gotchas"

Virtualized cells. Only rendered cells carry aria-selected; keep selection in state and render it consistently as rows scroll in.

Ctrl on macOS. Spreadsheets on macOS use Ctrl+Space too (Cmd+Space is Spotlight); test both.

Destructive follow-ups. After large selections, Delete or paste should confirm or offer undo.

Worked example

Permalink to "Worked example"

A budgeting grid supported cell selection only by mouse drag. Keyboard users could select single cells and Shift+arrow ranges but not whole columns; copying a 500-row column took minutes. Adding Shift+Space, Ctrl+Space, header buttons for row and column selection, selection announcements with sizes and undo for bulk clears let keyboard users copy columns in two keystrokes.

Common mistakes

Permalink to "Common mistakes"
  • No keyboard equivalent for header-click selection.
  • Silent large selections.
  • aria-selected not updated on virtualized rows.
  • Colour-only selection styling.

Testing checklist

Permalink to "Testing checklist"

Design system notes

Permalink to "Design system notes"

Document these shortcuts in the grid’s keyboard contract and expose a selectionMode that enables them for spreadsheet-style grids only.

Step-by-step implementation

Permalink to "Step-by-step implementation"
  1. Adopt spreadsheet conventions. Shift+Space selects the current row and Ctrl+Space selects the current column. Users who know Excel or Google Sheets expect these, and screen readers in application mode pass them through.
  2. Mark selected cells. Set aria-selected="true" on every selected cell (and on the row for row selection) and make sure aria-multiselectable="true" is on the grid.
  3. Announce the selection size. After selecting a column, announce “Column Amount selected, 240 cells”. Screen readers do not compute this for you, and without it users cannot confirm what they selected.
  4. Extend with Shift+Arrow. After a row selection, Shift+Down extends to the next row; after a column selection, Shift+Right extends to the next column. Announce the new range each time.
  5. Expose the selection to commands. Copy, delete and fill should operate on the selection and say what they did: “Copied 240 cells”.

Edge cases

Permalink to "Edge cases"
  • Virtualized grids. Selecting a whole column must select rows that are not rendered; keep the selection as a range, not a list of DOM nodes.
  • Conflicts with the screen reader. Shift+Space can be captured by some screen readers in browse mode; the grid must be in focus mode, which role="grid" normally triggers.
  • Header cells. Selecting a column from its header should select data cells, not the header itself.

Testing it with a screen reader

Permalink to "Testing it with a screen reader"

Start in NVDA with Firefox and make sure the grid is in focus mode. Move to a cell, press Shift+Space and listen for a row selection message with a cell count. Press Ctrl+Space and confirm the column selection message. Extend with Shift+Arrow and check that each step updates the announced range. Then press Ctrl+C and verify the “Copied” message and the clipboard content in a text editor. In JAWS, confirm that the keys are passed through to the grid; if JAWS intercepts them, document the pass-through key. In VoiceOver, check that aria-selected is announced as “selected” when moving onto selected cells, since that is how users verify the selection later.

FAQ

Permalink to "FAQ"
Should row selection select the row or its cells?

In cell-selection grids, select cells in the row; in row-selection grids, set aria-selected on the row.

How do I announce very large selections?

Give counts and ranges, not cell lists.

Can headers be buttons for selection?

Yes; a small “Select column” button in each header or row number cell works for pointer and keyboard.

What if Ctrl+Space conflicts with an IME?

Offer header buttons and an alternative shortcut documented in help.

Should Escape clear the selection?

Yes, in navigation mode; announce “Selection cleared”.

How does this interact with sorting?

Clear or remap selections when the order changes, and announce it.

Permalink to "Related"

← Back to Cell Selection & Clipboard in Data Grids