Scenario

Image insertion behavior varies across browsers

When inserting images into contenteditable elements, the behavior varies significantly across browsers. Images may be inserted as <img> tags, as base64 data URLs, or may not be supported at all. The size, positioning, and editing behavior also differs.

formatting
Scenario ID
scenario-image-insertion

Details

When inserting images into contenteditable elements, the behavior varies significantly across browsers. Images may be inserted as <img> tags, as base64 data URLs, or may not be supported at all. The size, positioning, and editing behavior also differs.

Observed Behavior

Scenario 1: Pasting an image from clipboard

  • Chrome/Edge: Inserts image as <img> tag with base64 data URL or file reference
  • Firefox: May insert image or may not support pasting images
  • Safari: Behavior varies, may insert image or require different approach

Scenario 2: Drag and drop an image file

  • Chrome/Edge: Inserts image at drop location
  • Firefox: May insert image or open file
  • Safari: Behavior inconsistent

Scenario 3: Image size and dimensions

  • Chrome/Edge: May preserve original size or apply default dimensions
  • Firefox: May resize images automatically
  • Safari: Size handling varies

Scenario 4: Image editing after insertion

  • Chrome/Edge: Images can be selected and deleted, but resizing may be limited
  • Firefox: Similar behavior
  • Safari: May have different selection and editing behavior

Impact

  • Inconsistent image insertion experience
  • Large base64 data URLs can bloat HTML
  • Difficulty controlling image size and positioning
  • Some browsers may not support image insertion at all

Browser Comparison

  • Chrome/Edge: Best support for image insertion via paste and drag-drop
  • Firefox: Limited support, may require manual handling
  • Safari: Most inconsistent behavior

Workaround

Implement custom image handling:

element.addEventListener('paste', (e) => {
  const items = Array.from(e.clipboardData.items);
  const imageItem = items.find(item => item.type.startsWith('image/'));
  
  if (imageItem) {
    e.preventDefault();
    const file = imageItem.getAsFile();
    const reader = new FileReader();
    
    reader.onload = (event) => {
      const img = document.createElement('img');
      img.src = event.target.result;
      img.style.maxWidth = '100%';
      img.style.height = 'auto';
      
      const selection = window.getSelection();
      if (selection.rangeCount > 0) {
        const range = selection.getRangeAt(0);
        range.deleteContents();
        range.insertNode(img);
      }
    };
    
    reader.readAsDataURL(file);
  }
});

element.addEventListener('drop', (e) => {
  e.preventDefault();
  const files = Array.from(e.dataTransfer.files);
  const imageFiles = files.filter(file => file.type.startsWith('image/'));
  
  imageFiles.forEach(file => {
    const reader = new FileReader();
    reader.onload = (event) => {
      const img = document.createElement('img');
      img.src = event.target.result;
      img.style.maxWidth = '100%';
      img.style.height = 'auto';
      
      const range = document.caretRangeFromPoint?.(e.clientX, e.clientY) ||
                    document.createRange();
      range.insertNode(img);
    };
    reader.readAsDataURL(file);
  });
});

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-0103-image-paste-chrome Windows 11 Desktop or Laptop Any Chrome 120.0 US draft
ce-0154-image-drag-drop-position 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.

Tags: image

Image deletion behavior varies across browsers

Deleting images from contenteditable elements behaves differently across browsers. Some browsers delete the image cleanly, while others may leave empty elements, break the DOM structure, or require multiple delete operations.

3 cases
Tags: image

Image resizing in contenteditable is limited or inconsistent

Resizing images within contenteditable elements is limited or behaves inconsistently across browsers. Some browsers support native resize handles, while others require manual implementation. The resize behavior may also affect the DOM structure unexpectedly.

2 cases
Tags: paste

List formatting is lost when editing list items

When editing text within list items, formatting such as bold, italic, or links may be lost or behave unexpectedly. The list structure itself may also be lost when certain operations are performed, such as pasting content or applying formatting.

3 cases
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

Comments & Discussion

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