The $0 Bridge
The most powerful concept in DevTools: turning a visual selection into behavioral access. Select something you can see, control it with code.
What is $0?
When you select any element in the Elements panel, DevTools automatically creates a reference to it called $0. This reference is available in the Console—type $0 and you're talking to that exact element.
This is the bridge between what you see and what you can do.
DevTools also keeps $1, $2, $3, and $4—your previous four selections. Useful when comparing elements, but $0 is what you'll use 99% of the time.
The Three-Step Workflow
This pattern will become second nature: Select → Reference → Interact
Select Visually
Right-click any element → Inspect. Or use Firefox's element picker: click the cursor icon in DevTools (top-left) or press Cmd+Shift+C.
Reference in Console
Press Esc to open the Console drawer. Type $0 — you now have code access to that element.
Interact or Inspect
Ask questions ($0.classList) or make changes ($0.classList.add('active')). Watch both panels update.
Asking Questions About Elements
Once you have $0, you can interrogate the element. These are the questions designers ask most:
| Question | Console Command | Returns |
|---|---|---|
| What classes does it have? | $0.classList |
List of all classes |
| Does it have a specific class? | $0.classList.contains('active') |
true or false |
| What data attributes? | $0.dataset |
Object with all data-* values |
| What's the text content? | $0.textContent |
The text inside |
| What's the computed width? | getComputedStyle($0).width |
Actual rendered width |
| Is it visible? | getComputedStyle($0).display |
none if hidden |
Open the Console Playground and try this:
- Use the element picker (Cmd+Shift+C) to select the color box
- Open Console with Esc
- Type
$0.classList— you should see["color-box"] - Type
getComputedStyle($0).backgroundColor— what color is it? - Try:
$0.style.backgroundColor = 'coral'— watch it change!
Making Changes
The real power: you can change elements through $0, and watch the page update in real-time.
// Add a class
$0.classList.add('highlighted')
// Remove a class
$0.classList.remove('hidden')
// Toggle a class (add if missing, remove if present)
$0.classList.toggle('active')
// Change inline style
$0.style.backgroundColor = 'coral'
// Change text
$0.textContent = 'New text!'
// Set a data attribute
$0.dataset.state = 'open'
Changes made through the Console (or Elements panel) don't modify your actual files. Refresh the page and they're gone. This is for testing and exploring, not permanent editing.
Testing Predictions
Here's where $0 becomes a design tool. Before you write code, you can test whether your idea will work.
When you build your theme toggle, you'll use exactly this workflow: select the <html> element, check its dataset.theme, then toggle it with $0.dataset.theme = 'dark'. Test it in the Console first, then write the code.
Scenario: "Will adding .active change the appearance?"
// 1. Check current state
$0.classList
→ DOMTokenList ["card", "featured"]
// 2. Add the class
$0.classList.add('active')
// 3. See the page update (or not!)
// If nothing changed, .active has no CSS rules
// 4. Check the Elements panel — see the class appear
// 5. Remove it to reset
$0.classList.remove('active')
Scenario: "What's the current state of this dropdown?"
// Check its classes
$0.classList
→ DOMTokenList ["dropdown", "is-open"]
// Aha! It uses "is-open" for state
// Close it
$0.classList.remove('is-open')
// Open it again
$0.classList.add('is-open')
Select → Question → Test → Verify. This is how you explore behavior without writing code. Once you understand what works, then write the JavaScript.
Watching Both Panels
The magic happens when you watch both panels at once:
- Position your Elements panel to show the selected element
- Open the Console drawer with Esc
- Type
$0.classList.add('test') - Watch the class appear instantly in the Elements panel
- Watch any CSS rules for
.testapply to the page
This bidirectional view is why DevTools is a design tool, not just a debugging tool. You can see structure AND behavior responding together.
Quick Reference
// === READING ===
$0.classList // All classes
$0.className // Classes as string
$0.id // Element ID
$0.dataset // All data-* attributes
$0.textContent // Text inside
$0.innerHTML // HTML inside
$0.style // Inline styles
getComputedStyle($0) // All computed CSS
// === CHANGING CLASSES ===
$0.classList.add('name')
$0.classList.remove('name')
$0.classList.toggle('name')
$0.classList.contains('name') // → true/false
// === CHANGING DATA ATTRIBUTES ===
$0.dataset.state = 'open' // Sets data-state="open"
$0.dataset.state // Reads data-state
// === CHANGING STYLE ===
$0.style.color = 'red'
$0.style.display = 'none'
$0.style.backgroundColor = '#f0f'