DEV Community

Weather Clock Dash
Weather Clock Dash

Posted on

Firefox DOM Inspector: Live Editing, Mutation Breakpoints, Console Shortcuts, and Shadow DOM

Firefox DevTools' Inspector gives you a live DOM editor — you can modify, add, and delete HTML elements directly in the browser, see changes instantly, and use the Console for powerful DOM manipulation. Here's what's possible.

The Elements/Inspector Panel

Open: F12 → Inspector tab (or Ctrl+Shift+I → Inspector)

The Inspector shows the live DOM tree. It's not the source HTML — it's the current state after JavaScript has run.

Select an element: Click the crosshair (select element) icon → click anything on the page → Inspector jumps to that element.

Hover elements: Hover over elements in the Inspector → they highlight on the page with box model overlay (margin, border, padding, content).

Editing HTML Directly

Double-click any element's tag, attribute, or text to edit it in-place.

Edit outer HTML: Right-click an element → "Edit As HTML" → opens a full HTML editor for that element and its children.

Example: Want to see how a button looks with different text? Double-click the text node, type new text, press Enter. The page updates instantly.

Edit attributes: Click on attribute values in the Inspector. Click once to see, click again to edit.

Change element type: Double-click the tag name (e.g., h1) → change to h2 → Enter. The tag changes on the page.

Right-Click Context Menu

In the Inspector, right-click any element:

  • Edit As HTML: Full HTML editor
  • Duplicate Node: Adds a copy right after
  • Delete Node: Removes from DOM
  • Scroll Into View: Scrolls page to make element visible
  • Copy: Copy outer HTML, inner HTML, attribute, XPath, CSS selector
  • Expand All: Expands entire subtree
  • Break On: Add DOM mutation breakpoint (breaks when element is modified)

DOM Mutation Breakpoints

This is powerful for debugging JavaScript that modifies the DOM unexpectedly.

  1. Right-click an element in Inspector → "Break On":

    • Subtree modifications (any change inside this element)
    • Attribute modifications
    • Node removal
  2. When JavaScript modifies the element, the Debugger pauses

  3. Check the call stack to see EXACTLY which JavaScript code made the change

Use case: An element's class is changing unexpectedly. Add a "attribute modification" breakpoint on it. When the class changes, the debugger pauses and shows you what called the change.

Console DOM Manipulation

The Console is a powerful live DOM editor:

$() and $$():

// Firefox console shortcuts
$('.my-class')           // Shorthand for document.querySelector
$$('.my-class')          // Shorthand for document.querySelectorAll
                          // (returns array, unlike querySelectorAll which returns NodeList)

// Select element, return it
$0                        // Currently selected element in Inspector
$1, $2                    // Previously selected elements
Enter fullscreen mode Exit fullscreen mode

Creating elements:

const div = document.createElement('div');
div.className = 'test-box';
div.textContent = 'Inserted element';
div.style.cssText = 'background: red; padding: 20px;';
document.body.prepend(div);
Enter fullscreen mode Exit fullscreen mode

Manipulating existing elements:

// Change all button colors
$$('button').forEach(btn => btn.style.backgroundColor = 'red');

// Add a CSS class to all links
$$('a').forEach(a => a.classList.add('highlighted'));

// Remove elements
$$('.ad').forEach(ad => ad.remove());

// Move elements
const main = document.querySelector('main');
document.body.insertBefore(main, document.body.firstChild);
// Now main is the first element in body
Enter fullscreen mode Exit fullscreen mode

Find elements by text content:

// Find all elements containing specific text
function findByText(text) {
  return [...document.querySelectorAll('*')].filter(el => 
    el.childNodes.length === 1 && 
    el.firstChild.nodeType === Node.TEXT_NODE &&
    el.textContent.includes(text)
  );
}
findByText('Error')
Enter fullscreen mode Exit fullscreen mode

Inspecting Computed vs Applied Styles

Styles panel (right side of Inspector when element is selected):

  • Rules: CSS rules as written, in cascade order (most specific first)
  • Computed: Final computed values after all CSS is applied

Toggle styles: Click the checkbox next to any CSS rule to disable/enable it.

Add new styles: Click empty space in the Styles panel → type a property/value. Or click "+" to add a new rule.

Find where a style is overridden: In the Computed tab, click any property → "Select all occurrences" shows where this property is defined in all rules.

Styling Elements via Console

// Add inline style
document.querySelector('.hero').style.border = '5px solid red';

// Add a class
document.querySelector('.hero').classList.add('test-variant');

// Insert a style tag
const style = document.createElement('style');
style.textContent = `
  .test-override { 
    background: yellow !important; 
    color: black !important;
  }
`;
document.head.appendChild(style);
document.querySelectorAll('button').forEach(el => 
  el.classList.add('test-override')
);
Enter fullscreen mode Exit fullscreen mode

Debugging Form Behavior

Forms are often complex to debug. In the Inspector:

Viewing form data:

// Serialize a form's data
const form = document.querySelector('form');
const data = Object.fromEntries(new FormData(form).entries());
console.log(data);
Enter fullscreen mode Exit fullscreen mode

Submit a form programmatically:

document.querySelector('form').submit();
// Or use requestSubmit() which fires the submit event:
document.querySelector('form').requestSubmit();
Enter fullscreen mode Exit fullscreen mode

Disable validation temporarily:

document.querySelector('form').noValidate = true;
Enter fullscreen mode Exit fullscreen mode

Fill form with test data:

document.querySelector('#email').value = 'test@example.com';
document.querySelector('#password').value = 'password123';
// Trigger input events (some frameworks need this):
document.querySelector('#email').dispatchEvent(new Event('input', { bubbles: true }));
Enter fullscreen mode Exit fullscreen mode

Shadow DOM

Web components use Shadow DOM — encapsulated DOM trees not accessible via regular querySelector.

In Inspector: Shadow DOM subtrees show with a #shadow-root (open) label. Click to expand.

In Console:

// Access shadow DOM
const host = document.querySelector('my-custom-element');
const shadow = host.shadowRoot;  // Only works for open shadow roots

// Query inside shadow DOM
const inner = shadow.querySelector('.inner-element');
Enter fullscreen mode Exit fullscreen mode

Closed shadow DOM: shadowRoot is null for closed shadows. They're intentionally inaccessible from outside the component.

Drag and Drop in Inspector

You can drag elements in the Inspector to reorder them:

  • Drag an element to a new position in the tree
  • Drop it before/after/inside other elements
  • The page updates immediately

Useful for testing layout changes without writing CSS.

DOM Snapshot for Testing

Taking a snapshot of the current DOM state:

// Save DOM state as HTML string
const snapshot = document.documentElement.outerHTML;
console.log(snapshot);

// Or copy to clipboard via DevTools console shortcut:
copy(document.documentElement.outerHTML);
Enter fullscreen mode Exit fullscreen mode

This gives you the fully-rendered DOM (after JavaScript has run), not the original source HTML. Useful for debugging server-rendered vs client-rendered differences.

Inspector Performance Tips

For large DOMs (1000+ elements), the Inspector can be slow to load/scroll.

Collapse complex subtrees: Right-click → "Collapse All" to minimize visible nodes.

Search with Ctrl+F: In the Inspector, Ctrl+F opens a search. Searches can use:

  • Element text content
  • Attribute names/values
  • CSS selectors
  • XPath expressions (switch to XPath mode in the search bar)

This is much faster than scrolling through a large tree.

Top comments (0)