{"slug":"inline-editing","meta":{"title":"Inline Editing","slug":"inline-editing","kind":"pattern","summary":"Change a value where it is displayed, without leaving the screen or opening a form — the shortest possible distance between noticing something is wrong and fixing it.","problem":"Correcting one field costs a round trip: open the record, find the edit form, locate the field among thirty, change it, save, and come back to where you were. The correction takes two seconds and the journey takes twenty, so small errors do not get fixed.","family":["edit","scan"],"data_shape":["record","tabular","collection"],"principles":["friction","minimize-distance","consistency"],"interaction":["inline-editing","direct-manipulation"],"density":"high","complexity":"medium","status":"stable","visibility":"public","use_when":["Fields are independently valid, so changing one alone cannot corrupt the record.","People correct values while reviewing a list, rather than filling a record in one sitting.","The value's context — the row, the neighbours, the total — is part of judging what it should be."],"avoid_when":["Several fields must change together to stay consistent. That is a form and a transaction.","Changing the value fires a side effect someone should confirm first.","The field needs substantial guidance, examples or validation explanation to fill in correctly."],"alternatives":[{"slug":"autosave","when":"The whole record is composed in place over a long session, not corrected field by field."},{"slug":"master-detail-drawer","when":"People need the whole record to make the change, not just the one value."}],"ask_leo":"Make these values editable in place.\n\n- Show the value as text, and make it obviously editable on hover and on\n  keyboard focus — a subtle field outline. Do not render permanent input boxes\n  for every value; that turns a readable list into a form.\n- Clicking, or pressing Enter on a focused value, switches that one value into\n  an input with the text selected.\n- Commit on blur and on Enter. Escape cancels and restores the original value.\n- Keep the element exactly the same size in both states, so nothing on the\n  screen moves when editing starts or ends.\n- After committing, keep focus where the person put it. If the row re-renders,\n  restore focus to the same cell — losing focus mid-pass is what makes inline\n  editing feel broken.\n- Show a per-value save state, and on failure keep what they typed, show the\n  error next to that value, and leave it in edit mode.\n- Validate the single value only. Do not block the save because a different\n  field elsewhere on the record is incomplete.\n- Support Tab to move to the next editable value so a whole column can be\n  corrected without the mouse.\n","related":[{"title":"High-Quality Inline-Editable Table","url":"/cookbook/inline-editable-table","summary":"The Rails, Turbo and Stimulus implementation of this pattern."},{"title":"Focus Jumping in Inline-Editable Tables","url":"/cookbook/focus-restoration-after-row-replace","summary":"The specific bug this pattern lives or dies by, and how to fix it."},{"title":"One consistent pattern","url":"/patterns/consistency","summary":"Editing where the value lives removes the second mental model entirely."}]},"body":"## Anatomy\n\n```\n  read state          hover / focus        editing\n  ──────────          ─────────────        ───────\n  $8,400              ┌─────────┐          ┌─────────┐\n                      │ $8,400  │          │ 8400.00 │ ↵ commit\n                      └─────────┘          └─────────┘ esc cancel\n                       same size            same size\n```\n\nThe rules are unusually strict, because inline editing fails on small details:\n\n- **Same box in every state.** If the input is a different size from the text,\n  the whole row shifts when editing begins and the page flickers as someone tabs\n  across it.\n- **Enter commits, Escape cancels, blur commits.** These are the conventions\n  people already have. Deviating costs more than any gain.\n- **Focus survives the save.** This is the make-or-break detail. A row that\n  re-renders after commit and drops focus makes a keyboard pass through a column\n  impossible.\n- **Errors stay next to the value** and keep the typed text.\n\n## Why it works\n\nIt collapses the distance between noticing and fixing to nearly zero. That\nmatters more than the seconds saved: when correcting a value is expensive,\npeople batch corrections, then forget them, and the data quietly rots. Cheap\ncorrection is what keeps a dataset honest.\n\nIt also removes a whole mental model. With a separate edit form, one object has\ntwo representations and the person maintains a mapping between them. Editing in\nplace means the thing you are looking at *is* the thing you are changing —\nthe [consistency](/patterns/consistency) principle at its most literal.\n\nKeeping the surrounding context visible is the third gain. Judging whether an\namount is right often depends on the neighbouring rows, the total, or the last\ninvoice. A form throws all of that away at the moment you need it.\n\n## The focus problem\n\nAlmost every failed implementation fails the same way. The value is saved, the\nserver returns updated markup, the row is replaced, and the focused element no\nlonger exists — so focus falls back to the document body. The person tabs\nexpecting the next cell and lands at the top of the page.\n\nTreat focus restoration as part of the feature, not a polish item. If the\nimplementation replaces DOM nodes on save, it must find the equivalent node\nafterwards and restore focus and selection to it.\n\n## Getting it wrong\n\n- **A grid of permanent input boxes.** Technically inline, but it has turned a\n  scannable list into a form and destroyed its readability.\n- **No affordance.** If nothing indicates editability, only people who were told\n  will ever try clicking.\n- **Layout shift on edit.** Rows jump, and a keyboard pass becomes seasickness.\n- **Whole-record validation.** Blocking a name change because a phone number\n  elsewhere is malformed makes the fast path slower than the form.\n- **Silent failure.** The value snaps back to its old text with no message, and\n  the person believes they saved.\n- **Inline editing something with side effects**, where a mistyped keystroke\n  emails a customer.\n\n## Exemplars\n\n**Airtable** treats the grid as the primary editing surface and gets every\ndetail of keyboard traversal right — which is why it feels like a spreadsheet\nrather than a web form.\n\n**Linear** applies it selectively: title and properties are editable in place,\nwhile anything that notifies people stays an explicit action. That selectivity\nis the judgment worth copying.\n\n**Google Sheets** is the reference for the state machine — read, selected,\nediting are three distinct visual states, and every keyboard convention people\nalready have works exactly as expected.\n\nThe extractable rule: **inline editing is a keyboard feature that happens to be\nclickable.** If a person cannot correct a whole column without touching the\nmouse, it has not been finished.\n"}