Scenario

Table editing in contenteditable is limited and inconsistent

Editing tables within contenteditable elements is limited and behaves inconsistently across browsers. Creating tables, editing cells, adding/removing rows and columns, and maintaining table structure all have browser-specific behaviors and limitations.

formatting
Scenario ID
scenario-table-editing

Details

Editing tables within contenteditable elements is limited and behaves inconsistently across browsers. Creating tables, editing cells, adding/removing rows and columns, and maintaining table structure all have browser-specific behaviors and limitations.

Observed Behavior

Scenario 1: Creating tables

  • Chrome/Edge: May support table creation via execCommand or manual insertion
  • Firefox: Limited table creation support
  • Safari: Table creation behavior varies

Scenario 2: Editing table cells

  • Chrome/Edge: Cell editing works but may break structure
  • Firefox: Similar issues with structure
  • Safari: Cell editing most likely to break structure

Scenario 3: Adding/removing rows

  • Chrome/Edge: May support via execCommand but behavior inconsistent
  • Firefox: Limited support
  • Safari: Row manipulation unreliable

Scenario 4: Tab navigation in tables

  • Chrome/Edge: Tab may move to next cell or insert tab character
  • Firefox: Similar inconsistent behavior
  • Safari: Tab handling varies

Impact

  • Difficulty implementing table editing features
  • Risk of breaking table structure
  • Inconsistent user experience
  • Need for custom table editing implementation

Browser Comparison

  • Chrome/Edge: Best table editing support but still limited
  • Firefox: More limited table support
  • Safari: Most inconsistent table behavior

Workaround

Implement custom table handling:

// Handle Tab key in table cells
element.addEventListener('keydown', (e) => {
  if (e.key === 'Tab') {
    const selection = window.getSelection();
    if (selection.rangeCount === 0) return;
    
    const range = selection.getRangeAt(0);
    const cell = range.startContainer.closest('td, th');
    
    if (cell) {
      e.preventDefault();
      
      const table = cell.closest('table');
      const row = cell.parentElement;
      const cells = Array.from(row.cells);
      const currentIndex = cells.indexOf(cell);
      
      if (e.shiftKey) {
        // Shift+Tab: previous cell
        if (currentIndex > 0) {
          focusCell(cells[currentIndex - 1]);
        } else {
          // Move to last cell of previous row
          const prevRow = row.previousElementSibling;
          if (prevRow) {
            focusCell(prevRow.cells[prevRow.cells.length - 1]);
          }
        }
      } else {
        // Tab: next cell
        if (currentIndex < cells.length - 1) {
          focusCell(cells[currentIndex + 1]);
        } else {
          // Move to first cell of next row
          const nextRow = row.nextElementSibling;
          if (nextRow) {
            focusCell(nextRow.cells[0]);
          } else {
            // Add new row
            const newRow = table.insertRow();
            const newCell = newRow.insertCell();
            newCell.contentEditable = 'true';
            focusCell(newCell);
          }
        }
      }
    }
  }
});

function focusCell(cell) {
  const range = document.createRange();
  range.selectNodeContents(cell);
  range.collapse(true);
  const selection = window.getSelection();
  selection.removeAllRanges();
  selection.addRange(range);
  cell.focus();
}

References

Scenario flow

Visual view of how this scenario connects to its concrete cases and environments. Nodes can be dragged and clicked.

React Flow mini map

Variants

Each row is a concrete case for this scenario, with a dedicated document and playground.

Case OS Device Browser Keyboard Status
ce-0115-table-tab-navigation Windows 11 Desktop or Laptop Any Chrome 120.0 US draft
ce-0126-table-cell-editing-breaks Windows 11 Desktop or Laptop Any Safari 17.0 US draft
ce-0148-table-paste-breaks-structure Windows 11 Desktop or Laptop Any Chrome 120.0 US draft
ce-0158-table-cell-selection-difficult Windows 11 Desktop or Laptop Any Chrome 120.0 US draft
ce-0171-table-row-deletion-difficult Windows 11 Desktop or Laptop Any Chrome 120.0 US draft

Browser compatibility

This matrix shows which browser and OS combinations have documented cases for this scenario. Click on a cell to view the specific case.

Confirmed
Draft
No case documented

Cases

Open a case to see the detailed description and its dedicated playground.

Related Scenarios

Other scenarios that share similar tags or category.

Category: formatting

Background color changes behave inconsistently

Changing background color (highlighting) in contenteditable elements behaves inconsistently across browsers. Background colors may be applied as inline styles, may not persist when typing, or may interfere with text selection. The behavior differs from text color changes.

3 cases
Category: formatting

Blockquote editing behavior varies across browsers

Editing text within blockquote elements in contenteditable behaves inconsistently across browsers. Pressing Enter, applying formatting, or pasting content may break the blockquote structure, create nested blockquotes, or behave unexpectedly.

4 cases
Category: formatting

Browser auto-formatting interferes with contenteditable editing

Browsers may automatically format text in contenteditable elements, such as converting URLs to links, capitalizing text, formatting numbers, or applying other transformations. This auto-formatting can interfere with editing, cause cursor positioning issues, and create unwanted markup or style changes.

0 cases
Category: formatting

Browser automatically converts URLs and emails to links in contenteditable

Browsers, especially Internet Explorer and legacy Edge, automatically detect URLs, email addresses, and phone numbers in contenteditable elements and convert them to clickable links. This auto-linking behavior can interfere with editing, cause cursor positioning issues, and create unwanted markup.

0 cases
Category: formatting

Code block editing behavior varies across browsers

Editing text within code blocks (<pre><code>) in contenteditable elements behaves inconsistently across browsers. Line breaks, indentation, whitespace preservation, and formatting may be handled differently, making it difficult to maintain code formatting.

4 cases

Comments & Discussion

Have questions, suggestions, or want to share your experience? Join the discussion below.