Firebug: White to Black Belt


Firebug is a Firefox extension that will streamline your developing process: it offers a plethora of tools for working with HTML, CSS, Javascript, and more. In this tutorial, I'm going to take you to a black belt level of Firebug usage that will karate chop your website woes!

Firebug was originally created by Joe Hewitt, who is currently an engineer at Facebook; he created Firebug for two reasons: to monitor what happens while a page is loading, and what happens after the page loads. Now, Firebug development is led by a group of developers from a number of larger tech companies, and it's only been improving. Today, you're going to go from a kohai to sempai . . . and after you start putting what you've learned into practice, you'll probably be a sensei! So let's get to it.

White Belt


The first thing you'll need to do is install Firebug. The easiest way to do this is to go to the Firebug website and click the "Install Firebug 1.3 for Firefox" button. This will bring up a dialog box, asking if you trust the author of this plugin, and there's no reason why you shouldn't.

Note: If you're on Firefox 3.5, you won't be able to use version 1.3; you'll need to use a beta of Firebug 1.4. If you're using a 1.4 beta, things might be a bit different from what I'll show you here; generally, however, the core functionality will be the same. Don't worry, though: we'll discuss the highlights of what's coming in Firebug 1.4 a bit later on.

Of course, after installing the plugin, you'll need to restart Firefox. Once you're back, you should see a small bug icon on your status bar.


So, let's get familiar with the parts of Firebug; I'm going to be using the Google Home Page to get us up to speed, if you want to follow along.

You can open Firebug easily by either clicking the Firebug icon on the task bar, or by hitting the F12. Once you have Firebug open, you'll see something that looks like this.

This is the HTML tab; Firebug has six tabs, each of which gives you different information about your website. A quick rundown of the tabs is in order.

Console Tab:

   The console tab will let you know about any activity between the server and the page after the page finishes loading. The console is also the place to spit out any information you want to review. Think of it as alert() in overdrive.


 The HTML tab shows you exactly what you think it does: the HTML of your page. However, it's much better than choosing "view source." Why? Stay tuned to find out.

CSS Tab:

   Again, an aptly named tab. Here's where you'll come for fine control over the whole cascading facade of your page.

Script Tab:

   This is the tab that excels at Javascript tweaking and debugging.

DOM Tab:

   The DOM tab allows you to check out the various properties of whatever objects you desire.

Net Tab

   This has to be one of the most interesting tabs of them all; it shows you all the traffic between your browser and the server: every time something crosses the border, this tab will tell you what it was, how long it took, and more.

There are a few more things to notice before we start learning what firebug is and does. We won't look at anything tab-specific, since we'll cover those when we look at each tab. But there are a few more general options we'll look at now.

The Firebug icon in the top left corner of the window is actually a menu, with some hidden gems that you should really know.

Open with Editor - This option lets you edit whatever content you are looking at. First you have to set up your text editors, via the "Configure Editors" dialog. Just click "Add" and choose your editor. Then you can edit any webpage, stylesheet, or script you want. Note: unless the page your viewing is on your computer (and you're not using a server like WAMP), any changes you make are not saved (at least in a refresh-and-review way, although they will probably save in your cache).

Text Size - Pretty self-explanatory : If you need to, you can make the text in Firebug bigger or smaller.

Options - There are three options: Checking the first option will open Firebug in a separate window when you click its status bar icon (or hit F12). The second one, checked by default, controls Firebug tooltips (most noticeable in the Net tab). Then the last choice opts whether or not to shade the box model, which we'll see when we look at the HTML tab.

The rest of the options will bring you to different online info about Firebug: the official website, the documentation, the discussion group, the issue tracker, and a link to contribute to Firebug (it's open source). Finally, you can learn a bit more about the current version from the last option.

Immediately right of the dropdown menu is the "Inspect" button. Clicking this will flip you to the HTML tab; then, as you hover over HTML elements on the page, it will give them a blue border and highlight their code counterpart in the HTML tab. The neat part is that as you hover over different elements, the highlighting in the HTML tab will hop from element to element. Then, when you've found the one you want to see, just click it, and then go to Firebug for inspection. There is one exception to this behaviour: if you are on the DOM tab, you won't flip to the HTML tab; you'll see the DOM properties of whatever object you hover over in the DOM tab instead.

In the top right corner of the Firebug window, there are three controls. Farthest right, there's the close button; to the left, you can "Open Firebug in new window." And then there's the search bar. The search bar is pretty powerful, although there's a bit of a catch at first: CTRL (CMD) + F isn't the shortcut. Because Firefox takes that shortcut, it's CTRL + SHIFT + K. After you type a search term, Firebug immediately finds the first match. Then, you can use ENTER to go to the next result. But search can do more than that : When on the Script tab, you can enter "#" and follow it with a number, and Firebug will jump to that line number. Then, you can use it to filter results in the Console tab, which we'll look at a bit later.

Now that you know your way around Firebug, let's dive into a few tabs!

Yellow Belt


We'll start by looking at the HTML tab, which is definitely the easiest tab to use. Let's first play with the "Inspect" tool to find a certain element in the HTML. On the Nettuts Freebie Page, open Firebug and click "Inspect." Now, hover over the title of the latest freebie.

Notice the things we mentioned earlier: the blue border and highlighted element in the HTML in Firebug. Now we can see that the title is an anchor inside of an h1 tag. When you click on the anchor, you aren't directed to its link; instead, the "Inspect" tool is turned off and the clicked element is selected in the HTML tab. Interestingly, when you select an element, Firebug keeps that element selected even through page refreshes, so changes to it are easy to see. When you hover over the anchor in the HTML, it will over-shade the anchor in the page. Now hover over its h1 parent. It will be shaded on the page now . . . but differently.

(Before we get too much further, I should mention that there is another way—in my opinion, an easier way—to find the elements on your page : you can right-click the element on the page and click "Inspect Element," a context menu item Firebug added on installation.)

This shading is Firebug's Box Model feature. When you hover over the h1, you should see a light blue box around the h1 content, with purple shading to the right and bottom, and yellow shading on the bottom of that. The purple shading indicated padding, and the yellow, margin. We'll look at this in more detail when we get to the three "sub-tabs" on the right of the HTML tab.

But let's check out the view from the HTML panel a bit more. This is obviously a tree view of the HTML. If an element has children, you can expand it to see them. You can easily edit attribute names and values by clicking on them and editing their content. But what if you want to edit a larger chunk, like our h1 with its child anchor? Make sure the h1 is the currently selected element and click the "Edit" button up beside "Inspect."

Now you can edit the raw code for the selected element and everything within it. If your changes are visible ones, you should see the difference almost immediately on the page. I'll change 101 to 201 and wrap "Essential Tips" in em tags.

When you're done, click edit again to save the changes (obviously just until the next refresh); or hit escape to return unedited.

Another nice feature of the HTML tab is the "breadcrumb trail" at the top, which gives you the "family tree" of the currently selected element.

You should see an "options" menu above the top right corner of the HTML panel, right above the scrollbar.

These options, from top to bottom will let you a) show all the text inside elements (as opposed to an abbreviated version), which is on by default; b) show whitespace in the code; c) show HTML comments; d) highlight changes made to the HTML (e.g. from AJAX), which is on by default; e) expand changes; and f) scroll to changes.

Let's look at an example of highlighting changes in the HTML. At the top of the any Nettuts page, there's a "Tuts+ network" button that drops a menu when you click it.

Right click that button and choose "Inspect Element." That will select the element in the HTML tab in Firebug. We can see that it's an img inside an h6. The element next to that h6 is a div, which you will see is greyed out.

Greyed out elements in the HTML are elements that aren't visible. If you select that div, you'll see the in styles tab on the right that it has the CSS declaration "display : none." But now, watch the div in the html as you click the aforementioned button on the page.

You'll see that the changes to the HTML are highlighted in yellow. This is great when doing more advanced AJAX stuff, and even simpler things like using jQuery to add or remove classes.

When working in the HTML tab, a few juicy functions hide in the context menu. Most of these should be pretty self-explanatory, but let's run over them quickly.

  • No matter where you right-click, the top 4 items are "Copy" (which I couldn't get to work even over a reinstall of Firebug), "Copy HTML" (which copies the HTML including the element you clicked on), "Copy innerHTML" (which only copies elements inside the clicked one), and "Copy XPath" (which copies an XPath expression for the elements).
  • "Log Events" is a great feature that allows you to log every event the browser fires in relation to a specific object; we'll look at this more when we get to the Console tab.
  • "Scroll Into View" will scroll the page until that element is at the top of the page.
  • "New Attribute" will let you add an attribute to the element.
  • "Edit Attribute" and "Delete Attribute" will appear when you right-click on an attribute.
  • "Edit HTML" does the same thing as the edit button up top, letting you edit the element.
  • "Delete element" does just that.
  • "Inspect in DOM tab" brings you to the DOM tab, where you can dig around in the properties of the element.

Well, that covers the functionality of the HTML panel; let's move to the right side and check out the three "sub-tabs": Styles, Layout, and DOM.

Style Tab

The Style tab is selected by default. This tab shows the styles for the currently selected object. You may have noticed that as you rolled around the page with the Inspect tool the styling listed here changed accordingly. So, click on that h1 and let's look around a bit.

There's a lot of info in this little panel. Firstly, styles are arranged in a reverse cascade, so the top styling on the list was the last one applied to the element. You can see this with the crossed-out declaration for font-size, letter-spacing, and line-height in the second rule: these properties were overwritten by the ones in top rule. Then, we can see what selectors are used in both rules, which is helpful when determining specificity. To the right of the selector, you can see what stylesheet the rule is coming from, which will save you a lot of time if you have multiple sheets. You can click the name of the stylesheet and go directly to the styles tab, and see the rule in its stylesheet context. But now let's start playing with the styles!

Adjusting your styles in Firebug is a great way to see what effect each declaration has as you make it, which is especially useful when aligning elements. Begin by hovering over the declatations in the styles tab; you'll notice that as you do, a gray "remove" sign appears to the left of the declaration.

Clicking that icon will disable that style; if you disable the padding-right, you will immediately see the changes on the page. Now disable the font-size declaration. The font will get marginally larger, but notice that the font-size declaration in the second rule (for h1, h2, h3) is now being used. Now, turn off that font-size. Wow, that's smaller! If you scroll down a few rules, you'll find what appears to be a reset rule, where the font-size declaration is now being used.

Clicking those remove icons again will enable the disabled styles. Now, back at the first declaration, click the value for padding-bottom, which is 5px. Now you can edit it. You could type in whatever value you want, but chances are that if you're adjusting the styling here, you don't know exactly what you want. So instead, use the up- and down-arrow keys to adjust the value incrementally, in this case, by pixels. Now do the same with the padding-right property, but use the page-up and page-down keys; they'll jump the value in increments of 10. However, because of the way the text is wrapping, you won't see very much of a difference until you get to 120px. We'll adjust these values in a more visible way on the Layout tab, but let's look at a bit more here on the styles tab first.

You can adjust a rule's properties in the same way you can adjust the values. Again, just click the properties and change the names if you so desire. You can also use the up- and down-arrows to move to the next or previous property alphabetically (Page-up and -down will do the same). Double-clicking anywhere to the top, right, or bottom of a rule will let you add a new declaration to the rule. Firebug gives you nice autocompletion on the properties, and also on the values that have set options. Finally, when working with the properties and values, you can use TAB or ENTER to loop through them.

Another hidden gem in the Style tab has to do with background images and colors.  Use the Inspect tool to find the code for the search box (input#search_term) in the upper right corner of the page. Looking at the top CSS rule for this element, we can see that a few colors have been defined.

Hovering over these colors will bring up a small colour swatch!

The same feature works with images, both in the CSS and HTML; you'll see a thumbnail of the image, with its dimensions, when you hover over its link.

Before we move on to the Layout tab, notice the little options button to the right of the sub-tabs.

"Show User Agent CSS" will show default browser styles in the cascade. The other option, "Show Computed Style," gives you a static, final, uneditable view of the elements styling; it shows the value of every CSS property. The properties are divided into categories: text, background, box model, layout, and other.

Finally, many of the functions we've performed on the Style tab here are available through the right-click menu, as well as the ability to copy and refresh, and check out a CSS rule in the DOM tab. You can also use the right-click menu to apply inline styles to an element: just click "Edit Element Style."

Layout Tab

The Layout Tab gives you a great view of the box model of any element.

If you still have that h1 selected in the HTML, you should see the same values as above. The innermost box gives the dimensions of the element alone; then, you can see what padding, border, and margin add to the box. We can tell that this h1 has 10px of padding and a 5px margin on the bottom. But the neat part is hovering over this diagram: you get the same shading of the element that you do in the HTML view, with the addition of rulers and guide-lines similar to the ones in Photoshop. These rulers and guides can be turned off via the options menu.

I mentioned earlier that we could adjust some values on the Layout tab in a more visible way than on the Styles tab: click the "50" to the right side of the box model; as we can tell from the diagram, it's the padding-right value. Now you can edit it the same way you did in the styles tab: arrow-up and -down keys, page-up and -down keys, or just type a value. If you hit the page-up key a few times, you'll see the right padding growing, even though it doesn't change flow of the text until around 120px. Now go add some margin to the top, around 30px or so. You can hit TAB or ENTER to save your change (and move to the next field, spiraling inwards), or you can hit Escape and remove your changes.


The last tab within the HTML tab is the DOM tab. It's really just a miniature version of the full DOM tab, so I'll leave a full explanation until we get there; basically it shows you the properties of whatever object is selected in the HTML tree.


Now we move on to the CSS tab. For these images, I'm on the Mac Appstorm Home Page, but there's not much to learn at this tab: the CSS view we get here is very similar to what we saw in the Style tab, but it comes from a different perspective: the rules are arranged according to their stylesheets (or, style tags). To switch between stylesheets, click the name of the currently viewed stylesheet, beside the "Edit" button.

Firebug sorts the stylesheets by directory; as mentioned, it also includes internal styles (from <style> tags). The image above shows us 5 internal style tags, and 3 external stylesheets. Choose "style.css" from the list. Almost all the functionality of the Style tab is here (all the editing, disabling, and adding propeties features are the same), but the rules are ordered as they are in the original code, so you don't get the cascading view. Via the right-click menu, you can add, edit, disable, and delete properties, as well as refresh the CSS and inspect rules in the DOM tab. That context menu also has a few perks: if you right-click on a color value or image link, you'll have the option to copy just the value or link, or open the image in a new tab. (And, yes, those options are avaiable from the Styles tab . . . did I mention that these tabs were similar?)

The Edit button will allow you to edit the raw stylesheet; now you'll be able to see any comments and whitespace. This is really the main feature of the CSS tab: the mass editing capabilities and the live changing that goes with them. Imagine writing your CSS within Firebug, where you can easily see what's going on as you type, and then copying that code back to a text-editor. That's the type of scenario where the CSS tab will be most useful . . . and even more so when they add the ability to save the file right from Firebug!

Orange Belt

Now we'll turn our attention to the Console tab. Like I said earlier, the Console tab will replace every Javascript alert you use for debugging. While the HTML and CSS tabs are great resources for learning those technologies (i.e. from other websites), the Console tab is one that's mainly useful when you're developing, so we're going to get into a bit of code before too long; you can go ahead and make up a bare-bones HTML page. I've done so and opened it in Firefox. If you haven't used the Console panel before, you might see this when you open it.

If you want to use the Console, Script, and Net tabs on a website, you'll have to enable them; Firebug leaves them disabled by default, because they will slow your page down when they're working. I'm going to enable all three tabs for local files by checking the boxes and clicking "Apply settings for local files,"  and you can do the same. Once you do, you'll see this.

Pretty blank, eh? In the top left corner, beside the Inspect button, you have "Clear," which wipes the console clean, and "Profile," which we'll talk about in a bit. Before we get into filling up the console, we'll review the options.

The menu coming from the Console tab itself deals with enabling and disabling the panel; there's a similar menu for the Script and Net tabs. The Sites option at the bottom will let you define what sites you want these panels enabled for.

In the options menu at the other side of the panel, you can pick and choose which errors you want to show: Javascript, CSS, XML, XMLHTTPRequest, Chrome (XUL apps), and external errors (files linked to, but not on your domain). You can choose whether to show a stack trace with the errors, which will show you what called a given function. Finally, you can choose to enable stricter warnings. The last option is for a larger command line. Command line? Yes, that bar at the bottom of the tab is a command line for Javascript, and by choosing this option, it will move up beside the console panel (similar to the way the style tab within the HTML tab is); this makes it easier to write and execute multiple lines at once.

Alright, let's get to work. Start by adding some javascript to our skeleton page:


Refresh the page in Firefox; even if you don't have Firebug open, as long as the Console tab is enabled, Firebug will warn you of errors on the page.

The Console tab gives even more info.

There's a lot we can learn about this error; at the top, we can see the problem: "ourString is not defined." If you have the Script tab on, you can expand the error to see the stack trace, which shows you what called our code: the page itself. That's actually a link to the script tab; if this were a function, it would be linked to that function in the script. Underneath that, we can see the problematic line of code, which again, is a link to the line in the script tab. Finally, we can see the file and line number of the error on the right. If we add the variable to our code . . .

var ourString = "I love Firebug!";

. . . we can refresh the page and see that the error is gone and our code performs correctly!

A big part of using the Console tab is using the Console API to log messages from your code to the console. The Console API is a group of functions that are part of the object "console." The most commonly used function is proably console.log(). This is a great way to dump information, objects, variables, and so on into the console for inspection. The nice thing about this is that its syntax is quite flexible. For example, look at this code:

var num = 1; 
var str = "firebug for firefox"; 
var obj = document.getElementsByTagName('body')[0]; 
console.log("I think", str, "is great."); 
console.log("A very important element is the %o", obj); 
console.log("%s is %d-of-a-kind; and the", str, num, obj, "is important.");

This code produces this output.

As you can see, you can append items with commas, insert values with string substitution, or even combine those methods. For string substitution, there are a few different types available:

  • %s : String
  • %d, %i : Integer
  • %f : Floating Point
  • %o : Object hyperlink

Note: these types don't actually change your values in any way (e.g. a floating point will not be rounded if you use %i).

The next function is console.debug(). In many cases, this is similar to console.log(); it will log whatever you pass it to the console, with a hyperlink to the object in the code; it will also tell you the file and line number, in the same fashion an error would.

The next three functions are just variations of console.debug(), with some user-friendly prettifying. These are, console.warn(), and console.error(). Let's write a bit more code.

var val = prompt("What's your age?"), 
    age = parseInt(val);"The user wrote %i", val); 
	console.warn("This might not work!"); 
var nextAge = age+1; 
document.writeln("Next year you will be " + nextAge); 
	console.error("Our calculation did not work!");

We've used all three of these functions, and the output shows how they perform; from top to bottom, you can see an info message, warning message, and error message.

Next, we have console.assert(), which lets you write an assertion : you pass it a value, and if it evaluates false, it logs an error. You can give it a second value or object as a label.

var str = "An error occured"; 
var nil = null; 
(function() { 
         console.assert(nil, str); 

The first assert passed without issue, since a string will evaluate as true. However, null equates to false, and so the error is logged; str is passed as a label. When assert() logs an error, it also gives an expandable stack trace: this time, the error was in an anonymous, self-invoking function that was 'called' by the page itself. And of course, we have the file and line number on the right.

Console.dir() is specifically for logging objects. Why not just use console.log()? Well, firstly, console.log doens't print an object in the console: it just links to the DOM tab view of the object. Console.dir() prints that DOM view into the Console. But there's another reason to use console.dir(); check out this code and its results.

var obj = { 
    str : "This is a string", 
    num : 2009, 
    bln : true 
obj.str = "What's going on?"; 
obj.num = 2062; 
obj.bln = false;

When you view an object with console.log(), you are viewing the "latest version" of the object; however, console.dir() will output the object as it was when you called console.dir(). Both options are useful, depending on your scenario.

Console.dir() is just for objects, so there's console.dirxml() for HTML or XML nodes. Really, it just prints a view similar to that of the HTML tab.

var wrap = document.getElementById('container') 

To get more details on a certain element, just click it to be taken to the HTML tab.

Console.trace() is a great Javascript helper: it spits out a stack trace of the javascript functions up to the point it was called.

(function () 
	var wrap = document.getElementById('container'); 
	insertParagraphInto(wrap, "Hello, Joe Hewitt!") 
function insertParagraphInto(element, content) 
	var newNode = createParagraph(content); 
function createParagraph(content)        
	var ele = document.createElement('p'); 
	var txt = document.createTextNode(content); 
	return ele; 

The results that are put in the console show us a "breadcrumb trail" of functions.

The stack trace details the functions on the stack, as well as the values that were passed as arguments to each function. You can click each function to take you to its source in the Script tab, and click each argument value to inspect it in the DOM or HTML tabs.

Let's say you're debugging a rather large portion of Javascript, and you're using every one of the functions we've talked about so far. Your console it going to get pretty messy, and things might get confusing. That's when you'll want to use; this function will put every console message following it into a collapsable group, until it hits a console.endGroup(). You can pass a title parameter.

Groups are nestable, and if you want a group to be collapsed by default, use console.groupCollapsed() instead of group().

One of the obsessions of many coders is time: "how long does it take my code to execute?" Well, that's what console.time() and console.timeEnd() are for. Both functions require a name (which can really be any object). I added these functions to our paragraph-adding code . . .

(function () 
        console.time("create paragraph") 
        var wrap = document.getElementById('container'); 
        insertParagraphInto(wrap, "Hello, Joe Hewitt!") 
        console.timeEnd("create paragraph"); 

 . . .  and the result was this.

The next two functions are console.profile() and console.profileEnd(), which assist in javascript profiling. These functions are very similar in use to the time functions (just put them at the beginning and end of the code to profile and give profile() an optional name); so let's look at the ways to do profiling in Firebug and what results it returns. Firstly, you don't need to put the profiling code in. You can start and stop profiling from the console, using the "Profile" button in the corner. Hit it once to start, and again to end. One advantage to this is that you can start the profiler, refresh the page, stop the profiler, and get the results from a page load.

Let's profile that paragraph-adding code; I've put the lines outside the starting function so that the function will be included in the results; I've also added an array and looped through it, so we get a bit more info in our results. I've also taken the console.trace() line out of the last function.

console.profile('adding a paragraph'); 
(function () 
        var wrap = document.getElementById('container'); 
        var messages = ["Hello, Joe Hewitt!", "Hello, World!", "Hello, Firebug user!"]; 
        for (m in messages) 
                insertParagraphInto(wrap, messages[m]); 

When you refresh the page, you should see results similar to these in the console.

Firebug gives us a nice little table with the data. So, what do we have here? Well, at the top we can see how long all the profiled code took to run: in my case, 0.736 milleseconds; and how many function calls were made: 7. On the left side of the table we have the different functions that were called during the profiling. The next column tells us the number of times each function was called; these numbers look right, because our anonymous function was called once, and the other two were called three times, for the three items in our array.

Next, we learn how much time was spent on each function, as a percent; it looks like most of our time was spent in createParagraph(). The next two columns tell us how much time was spent on each function altogether, meaning the times for each function call added together. What's the difference between "Time" and "Own Time"? The "time" column is the amount of time a function took to run, including functions it had to call. The "own time" is the amount of time spent executing code in that function only. Therefore, insertParagraphInto() took 0.1952ms by itself (remember, that's all three times it ran added together). But if you include the time spent in createParagraph() (because it's called from within insertParagraphInto()), it took 0.488ms. And createParagraph() took 0.296ms in both Time and Own Time, because it doesn't call any other functions.

The next three columns are for the Average, Minimum, and Maximum time spent on each function, because there will obviously be variability. And the last column tells us the file these functions are located in, which we can, of course, click to view the files in the script tab.

The final function is console.count(). This is simply an easy way to count the number of times a function is called. You can pass it a name if you want.

Remember that option on the context menu in the HTML tab, the one that let us "Log Events" for an element? Put an h1 in your document, use the Inspect button to select it in the HTML tab, right-click it, and choose "Log Events." Then, flip back to the console tab. Now, roll your mouse around the h1, on it, off it, and don't forget to click and double-click it. Your console should be flooded with events. This gives us the opportunity to use the search functionality on the console tab: it will filter out any entries that don't match your search term. For example, I'll search "click"; these are my filtered results.

(I went back to the script and added some console messages to show that it searches the whole console)

There's one more thing that Firebug logs to the console (with the default options checked): XMLHttpRequests. This is one of those features that makes Firebug such an outstanding tool. To give this a try, you'll have to have a test page on a server; I've moved our test page to my WAMP server and I've added jQuery to the page. For Javascript, we'll just put something simple.

$.post('otherPage.php', {'fName' : 'John', 'lName' : 'Doe'} );

That means we'll need an "otherPage.php" with something simple in it.

echo "Hello, " . $_POST['fName'] . " " . $_POST['lName'] . '!';

When you load the page, you'll see this.

There's a lot of information available in this tiny packet. First, you can see URL of the page that the request was sent to. We can also see the status of the request and the time it took: ours executed fine (200) and it took 5ms. If you middle-click (CTRL + click) the URL, it will open that page in a new tab. Or, you can just click that link to expand the POST request.

Inside the request, there are three tabs: Headers, Post, and Response. As you can see, the respone tab content is what came back from the POST request. On the Post tab, we can see what data we sent to the other page. The nice formatting gets even nicer when you start sending a lot of data at once.

The Headers tab has a lot of delicious bits, more than I've pictured. It's all metadata about the "requester" and the "responder."

A last word about XMLHttpRequests in the console: they, too, have their own context menu with several obvious options.

Now you should be pretty familiar with the features and functions of the console and its API. But wait, there's more: we haven't even looked a the command line yet!

Green Belt

The command line will take any javascipt and execute it as though it were part of the page. Just type it in, hit enter, and you'll get the results back.

Unlike a regular command line, these results usually won't be plain text; they'll be hyperlinks to objects, elements, functions, etc. when applicable. Give this a try: type "document." in the command line and then press TAB. Autocomplete! You can tab through the objects and properties for almost any object. This works no matter how much you've typed in, so you can put "document.getElements" and then start tabbing through the 4 functions that match.

A lot of times, however, you want to execute more than one line at once . . . and Firebug is happy to accomodate. We mentioned the options menu item to increase the command line; you can also do it with the little arrow at the far right end of the line. But there's another way to do it: if you want to execute multiple lines at once, chances are you've already prepared them in your favourite text editor. Just paste them into the one-liner command line, and it will grow on its own.

Then, you can hit the "run" button (or CTRL + ENTER) to run your code. That "run" button is one of three at the bottom of the larger command line. The second one obviously clears the line, but the third does something not so obvious: yes, it copies the script, but it adds "javascript: " to the front, and it concatenates the lines. Yes, that's right, it turns it into a bookmarklet! If you're a bookmarklet fan, this should make writing them convenitently faster: you can write and test them dynamically, and then easily export them when you're done.

You might find yourself looking at an element in the HTML tab, but wanting to data mine it in the Console tab. That's not a problem. Firebug automatically assigns the last element you inspected to the variable "$1." (The second last inspected element gets the variable "$2.")

If you were inspecting elements in the DOM tab, use "$$1" and "$$2" respectively to get those ones.

But sometimes it's the other way around; you've got the element in the console and you want to inspect it in the HTML tab . . . or another appropriate tab. If that's the case, enter the element, object, or whatever it is and hit SHIFT + ENTER. Firebug will assess the object and take you to the appropriate tab.

But this marvellous command line will swallow more than just standard Javascript. Firebug has its own set of custom commands. The first is $(). Just like jQuery, you can pass it either an id or a css selector and get back an element or array of elements respectively.

If you prefer, you can collect elements with xpath expressions, using $x().

Hopefully you'll remember the console.dir() and console.dirxml(). These have command line counterparts that work the same way.

Next is cd(), which takes a frame as the parameter.

By default, command line expressions are relative to the top-level window of the page. cd() allows you to use the window of a frame in the page instead.

If my experience, this function has been a bit buggy; but really, should you be using frames in 2009?

The clear() function will clear the console. The inspect() function takes one or two parameters. You can pass it an object to inspect, and it will select the best tab, or you can add a second parameter to choose which tab yourself (Your options are "html", "css", "script", and "dom"). So, for example, you could do something like inspect(wrap, "dom").

Keys() and Values() are partners in crime: one returns the names of an objects properties and the other returns the values, respectively.

We'll look at this more when we get to the script tab, but debug() takes the name of a function, and will set a breakpoint at the first line of the function. Undebug() will remove the breakpoint from whatever function you pass it. We'll also look at the results of monitor() and unmonitor(), both of which take a function's name, on the script tab. But if your curious now, they control function call logging.

Next up is monitorEvents() and unmonitorEvents(); these are very similar to the event logging we got from the context menu the HTML tab. Both require an object parameter, the object you want to log events for. If you want to specify events from a certain source, like 'mouse' or 'key', give montiorEvents its second parameter. There are 14 event types you can specify, and their all listed in the command line documentation .

Finally, there are the profile() and profileEnd() functions, which work just like the profiling we've already seen. These are the last tools for your command line toolkit!

So now that we thoroughly know the console tab (although we will be back for a visit before too long), let's get aquainted with Script Tab

Script Tab

This is the script tab, our javascript debugging friend. It has two panels: one for viewing your scripts on the left and one for viewing debugging info on the right. Up beside the inspect button, you can choose what type of scripts you want to see.

You can change which file you want to view in the same way you did in the CSS tab; by the way, there's a keyboard shortcut for that: CTRL + SHIFT + SPACE. I should mention that once the menu is open, you can start typing the name of the file to select it.

Up beside the search bar, you have the controls to step around your code while debugging. And then you have the options: from top to bottom, you can have Firebug stop at every error, show chrome sources (which has to do with the browser itself), and track your throw/catch statements. And each of the tabs on the debugging panel have a few options as well, which you'll find pretty self-explanatory. These is the watch panel's options; you can choose what variables show up in the panel.

Well, let's begin debugging, shall we? I've set up a simple example page based loosely on this script . Here's our HTML.

<div id="container"> 
        <button id="add" type="button">Add Row</button> 
        <button id="del" type="button">Delete Row</button> 
        <table id="myExampleTable" width="100%"> 
            <td>Row 1 Cell 1</td> 
            <td>Row 1 Cell 2</td> 
            <td>Row 1 Cell 3</td> 
<script src="script.js" type="text/javascript" charset="utf-8"></script> 
<script type="text/javascript" charset="utf-8"> 
        document.getElementById('add').onclick = addRow; 
        document.getElementById('del').onclick = deleteRow; 

And here's our Javascript, in script.js.

function addRow() 
  	var table = document.getElementById('myExampleTable'); 
  	var numRows = table.rows.length;   
  	var newRow = table.insertRow(numRows); 
	for(var i = 0; i <= 2; i++) 
        var cell = newRow.insertCell(i); 
        var text = document.createTextNode('Row ' + (numRows + 1) + ' Cell ' + (i+1)); 
function prettify(cell) 
    style =; 
    style.color = '#ececec'; 
    style.fontWeight = 'bold'; 
    style.backgroundColor = '#474747'; 
function deleteRow() 
  	var table = document.getElementById('myExampleTable'); 
	if(table.rows.length > 1)   
    	table.deleteRow(table.rows.length - 1); 

There's bit of css, but that's not a big deal. Here's what the page looks like right after it loads.

Give it a try, and when you're ready to start, come on back here. The first thing we'll do is switch to the script.js page so we can see the javascript.

The tool that catapults us into the debugging is called a breakpoint; setting a breakpoint is just selecting a line that we want the code to freeze at. Then, while time is stopped, we can look at the values of different variables, and then advance through the code line by line, watching the execution. Let's set a breakpoint at the for statement: you can do this by simple clicking just to the left of the line number. A red circle will appear where you clicked.

Before we run the script again, click the "Breakpoints" Tab on the right.

This tab lists all of our breakpoints for us. We can toggle them on and off with the checkbox, or remove then altogether with the "X." Firebug tells us which file and line of code the breakpoint is on, which is helpful when you have many Javascript files with multiple breakpoints.

Now, move back to the watch tab and then click our "Add Row" button.  Here's what Firebug should look like now.

Notice a few things here: first, there's a yellow arrow at the line we set the breakpoint on (it's sitting on the red breakpoint circle). That arrow indicates the next line to be executed. Then, in the watch panel on the left, we have a list of current variables and their values. Notice that the values of a few variables are undefined; that's because we haven't got to the place in our current function where their values are set. Finally, notice the debugging controls up by the search box are no longer greyed out. From left to right, these buttons will do as follows.

  • "Continue" will run the code until it finishes; you can also use the F8 key.
  • "Step Into" will run the next line of code; keyboard shortcut: F11.
  • "Step Over" requires a bit more explaining. If the next line to execute is just a regular line of javascript, it will run it. If the imminent line is actually a call to another function, "step over" will not step into the function, but step over it. In other words, it will run that other function, but it won't debug it; it will just run it and bring you to the next line of the function. In contrast to this, if you use the "Step into" button, you will step through each line of the called function. The "Step Over" button can be invoked with F10.
  • "Step Out" will run the code until you are out of the current function. So it you decided to step into a function called from another function, this button will finish off the function you're in and bring you back to the original function.

If you're a bit confused, don't worry: we're going to use all these buttons right now. Go ahead and click "Step Into" (or hit F11). The arrow and highlighting jump to the next line, indicating that previously-highlighted line has been executed. And we can see that our variable "i" now has a value. Okay, click "Step Into" again; now notice that the highlighted line (the one to be executed next) is a call to a function. If you hit F11 again (do it), you'll step into that function. Click "Step Into" one more time, and let's pause to take in the view.

Firebug should look something like this now. There are several bits of data flying around right now, so let's catch and disect them one by one.

At the top of Firebug, you'll see a "breadcrumb trail" of functions: the stack trace. When you get deep into debugging, this will tell you where you are: right now, we know we're in the function "prettify" (it's bold). And how did we get here? This function was called from the "addRow" function. You can get a similar view in the Stack tab on right.

In Prettify(), we're decared the variable "looks," but it's not showing up in the watch panel. That's not a problem: there are two ways to add things to the watch panel. You can highlight the term in the script and choose "Add Watch" from the context menu.

If we do that, "looks" wil now be present and accounted for in the Watch tab. The other way to add things to the Watch tab is with the "New Watch Expression... " button at the top of the watch pane; when you click it, it becomes a text field for you to enter whatever object you want to watch . . . and you've even got autocomplete to help out. In our case, there isn't anything very useful we can add, but give it a try anyway.

You can easily remove added objects from the panel by clicking the "X" on the right (which appears when you hover over the object).

When you hover over variables and objects in the code, you can see their values in a "tooltip." (I know you can't see my cursor, but it's hovering on "looks".)

While we're here, let's look at the context menu; I've right clicked on the last line of prettify().

Based on what we've already talked about, most of these are self-explanetory, except for "Edit Breakpoint Condition . . ." and "Run to this Line." If you can't guess what "Run to this Line" does, click it. It will run the code to whatever line you right clicked on. You can also do this through middle-clicking (or CTRL + click). And we'll look at "Edit Breakpoint Condition..." in a moment.

Well, let's keep moving. Click "Step Out" to finish off the function and move back to the one we came from. Now hit F8 ("Continue") to finish the function. Finally, click our breakpoint to remove it.

If we left that breakpoint there, every time we clicked "Add Row," we would be stopped at that line. But let's say that for some reason, we're only interested in stopping when our table has ten or more rows. What we need is a conditional breakpoint. You can set a conditional breakpoint by right-clicking either to the left of the line number (as before), or on the line itself (where you'll have to choose "Edit Breakpoint Condition..."). For this breakpoint, let's set it on the first line within that for statement.

Remember, the numRows variable is the number of rows in our table. So with this conditional breakpoint we're saying that when numRows is greater than or equal to 10, pause the script. And if you give it a try, you'll find it does just that!

There were a few console functions that somewhat fall into the category of Javascript debugging: debug(), undebug, monitor(), and unmonitor(). The debug functions set or remove a breakpoint on the first line of the function you pass it. So we can set a breakpoint on deleteRow() with this command.

Now if you click our "Delete Row" button . . .

. . . we have a breakpoint on the first line of the function. You can hit F8 to run the function; then go back to the console and remove the breakpoint.

Now, if you click "Delete Row," it should run without interruption.

The monitor functions will log to the console every call of whatever function you give it. So if we wanted to log prettify(), we would just punch "monitor(prettify)" into the command line. Then, when you add a row to the table, you'll see this.

And of course, unmonitor() will stop logging.

Well, hopefully you're grokking the script tab by now, beacuse it's time to move on to the DOM tab.

Blue Belt

DOM tab

DOM stands for Document Object Model; according to Wikipedia, it's the convention for representing and interacting with objects in HTML, XHTML and XML documents. It's also used for representing Javascript objects and functions, as we'll see.

The first thing you'll notice is that several entries at the top of the DOM list are bold. Firebug distinguishes between standard objects and ones you created this way: it floats yours to the top and makes them bold. The green ones? Those are functions, as opposed to to objects, which are black. By default, Firebug shows all the variables and functions you've defined, as well as standard DOM properties. You can adjust what you see in the options menu.

If an object has a "+" before it, you click that to expand it. I've done that with an object I added to script.js.

Notice how Firebug displaying objects of different types appropriately: it knows what to do for strings or booleans or arrays or what-have-you. And I can do more than just look at these values. I can edit them.

Just double-click whatever value you want to edit (found on the right side), make your changes, and hit ENTER. And autocomplete works here, too, as you can hopefully infer from the image. To put the cherry on top, double-click a boolean: it changes to the opposite value!

We already expanded our object by clicking its "+"; but sometimes you want to focus on an object and give it a bit more room to breathe. When that's the case, click on its value (the value you see when the object is collapsed) , on the right.

Firebug gives your object the entire panel; and there's that breadcrumb trail at the top, ready to take you back to the whole list when you're ready.

Many times, you'll go the DOM tree to see if a variable or object is what it's supposed to be. If it's not, you'll go back to the code, tweak a bit, and refresh your page to see if things are looking good. Firebug will fall in line with this style of working: it will remember what objects you had expanded and where you had scrolled to in the list when you refresh the page. You can refresh in peace, knowing that ornery object will be right where you left it on the DOM tab.

The functions we've been using are there on the DOM tab, too. You can click the values of these functions (which are just the functions' signatures) to be whisked away to the appropriate spot within the script tab.

And then, of course, there's the context menu. Again, it's fairly obvious, allowing you to copy, edit, and delete values.

I'm showing you the context menu for a function because it has a few unique options. We can log calls to this function, as we did from the command line. And although you can copy the values for everything in the DOM tab, I'll draw attention to the fact that "copy function" really copies the entire function, which could be useful if you enjoy learning from others' code.

Net Tab

Our last tab is the Net tab, which is both fun and useful. It's role is site loading optimization. Want to know how long it takes your page to load and why? The Net tab will keep you in the know.

What you see on the Net tab is a graphical representation of your page as it loads. This particular page happens to be the Google Canada home page. Every entry in the main panel is a file request to the server. From left to right, an entry lists what HTTP method was used to request the file (in our case, all GETs), and the URL requested (hover to see the complete URL). Then, there's the the response status number and description. Next, we have the domain name that the response came back from. The size of the response is the last item, before the graphical part. You'll notice the summary at the bottom of the list: how many requests, the entire weight of the requests, and the time the whole procedure took.

Now let's look at that chart. If you hover over an entry in the chart, you should see a popup similar to this one:

What do these bits of data mean?

  • "Queuing" is the amount of time a request spent in the browser queue waiting for a chance to get on the network to find its file. This is represented by the light brown section of an entry's bar.
  • "Receiving Data" is the amount of time spent receiving a file from the server. This is represented by a grey bar. If the file is loaded from the browser cache, then the bar is light grey.
  • "DOMContentLoaded" is an event fired when all of the DOM content has finished loading. This doesn't include images (since they aren't part of the DOM). This is represented by a blue vertical line. In this case, the time given is the number of milleseconds the request began before or after the event. Therefore, this request began 318ms before the DOMContentLoaded event was fired. If the number was negative, it would mean the request started so many milleseconds after the event.
  • "Load" is an event fired when the entire page has finished loading. This is represented by a red vertical line. This statistic is measured the same way the DOMContentLoaded time is: so this request started 654ms before "load" fired.

Armed with this information, we can see things like what order the files are loading in, and which ones take longer to do so, as well as where files load in relation to those two events.

I mentioned that cached files have a light grey bar; the Net tab makes it quite clear what the browser takes from the cache, so you can get a better picture of how well your site is using cached content. As you can see here, reloading the same page as above uses several cached files and is almost 1.8 times faster.

Let's now look at the information we get in these entries.

Each entry has at least two tabs: a headers tab and a response tab. The headers tab tells us all about the HTTP headers of the request and the response. The response tab is whatever the server sent back to you: it could be HTML, CSS, Javascript, an image, you get the idea.

If a file comes from the cache, it will have a cache tab.

This tab lists the last time the cache was modified or opened, as well as how big the file is and how many times it's been fetched from the catch. Notice that cached entries have response status of "304 Not Modified."

If data is sent to the server when you request a file (in the form of URL parameters), Firebug adds a params tab with the prettified key/value pairs. (This example is from Gmail.)

And if the request sent data via POST, there's a post tab with the data

Once again, the context menu is a treasure trove of options: you can copy different parts of the entry, view parts in other tabs, or open the requested file in a new tab.

Before we leave this tab, there's one more thing to draw your attention to near the top.

If you have a lot of files being requested, it could get overwhelming, especially when you're only interested in, say, image loading. Firebug lets you filter the entries by type.

Brown Belt

So that's Firebug as it stands today. With so many great features, it's no wonder that hundreds (probably thousands) of web developers use it every day. But it only gets sweeter: many people have made extensions to Firebug (yes, add-ons for an add-on!), that only increase Firebug's amazing web development superpowers. Let's look at a few of the most popular ones now.


FirePHP brings the power of Firebug console logging to you server-side code. First, let's install it from the Firefox addon gallery.

Once you restart Firefox, you'll have to download the FirePHPCore library. Extract the zip and move the folder "FirePHPCore" (located within the lib folder) to your desired location. Obviously, this will have to be on a server, since we're working with PHP; if you're using WAMP or MAMP, it's probably a good idea to put it in the www or htdocs folder respectively. Then it's easily available to your projects.

Then, all that's left is to included it in your php. (I'm doing it the object-oriented way, but you can do it procedurally.)

require_once('../FirePHPCore/FirePHP.class.php'); //Or your path 
$firephp = FirePHP::getInstance(true);

Because the information is sent to Firebug in the HTTP Headers, you should activate the output buffering or you might get the "headers already sent error". It may sound complicated, but all you have to do is write ob_start() on the first line of your PHP script that you’re debugging.

For the most part, it you use it very similarly to Firebug's native console logging.

$firephp->log("a regular log"); 
$firephp->info("A message with information"); 
$firephp->group("a group"); 
$firephp->warn("Watch your step!"); 
$firephp->error("Hold it right there"); 

Of course, the results are similar too.

Sometimes, the results are extra sweet. For example, when you log an array or an object . . .

$myArray = array("site" => "nettuts", "topic" => "firebug"); 
$myObject = new stdClass(); 
$myObject->discipline = "karate"; 
$myObject->belts = 7; 
$firephp->log($myArray, "This is a small array"); 

. . . and hover over the console entries . . .

. . . you get a nice heads up display of the values.

There's a lot more you can do with FirePHP, but I'll just show you one more thing. You can pass a two-dimensional array to the table() function and have it print a table to the console.

$table   = array(); 
$table[] = array("Stats", "Nettuts", "PSDtuts"); 
$table[] = array("Twitter","13,834", "15,310"); 
$table[] = array("RSS", "40,187", "66,393"); 
$firephp->table("A few Envato Stats", $table);

(Click the entry to expand the table).

You want to be sure that you don't leave your FirePHP debugging code in when you put your site live; you don't want to be broadcasting sensitive information. Instead of taking it all out, it's easy to turn it all on or off with one line of code.



YSLow is a Firebug exetension created by a team at Yahoo! It's perfect for sleuthing out what's slowing that page down.

YSlow isn't quite as interactive as the other parts of Firebug. It adds a YSlow tab Firebug, from which you can choose from a number of rulesets to test the page against, or create your own ruleset.

After selecting the desired ruleset, click the "Run Test." YSlow will run the tests and give the page an overall grade. Then, it grades the page on each rule the page was tested against.

As you can hopefully see, the Yahoo! home page gets an overall grade of "A." The currently selected section, "Put Javascript at bottom," gets an A as well, because YSlow! only found one script in the head. Notice that YSlow tells you why this rule is helpful, and even gives a link to read more. Besides the "grade" sub-tab, there are a few others, the most interesting being "statistics," which gives graphs of the page's "weight."

Even if you don't run a test (and even if Firebug isn't open), YSlow will still sit in the status bar and tell you how long it took to load the page.


Firecookie bakes into Firebug the ability to view and work with cookies

It adds a Cookies tab, which lists all the cookies from the site. You can get all the info you need—name, value, domain, size, and more—just by browsing through the table.

Then, you can create and remove cookies, watch cookie events in the console, export cookies and more. You can read more about it on the FireCookie homepage .

And so many more

There are a lot of really great Firebug extension that you should check out. A few of them fill specific niches, like FireAtlas (for ASP.NET AJAX), ColdFire (for ColdFusion Debugging), and Firesymfony (for the Symfony PHP framework). However, many have broad spectrums and are sure to be useful in many situations: these include Pixel Perfect (for overlaying web compositions), FireFinder (for determining what elements match a CSS selector), and SenSEO (for search engine optimization analyzing).

Black Belt

Well, we're just about done. As we come to the end, let's discuss using Firebug in other browsers, as well as what's coming for Firebug.

Firebug Lite

Well, you can't really use Firebug in anything other than Firefox. But there is an alternative: Firebug Lite. It's certainly not everything Firebug is, but it's better than nothing. To get Firebug Lite, just paste this script in your page:

<script type='text/javascript' src=''></script>

There are alternative ways, including a bookmarklet, to put Firebug Lite on a page: see the link above.

 Firebug Lite supports the whole console API, and it does have most of the tabs in Firebug, albeit it's not quite as fleshed out. But when you need some help in another browser, Firebug Lite is a lifesaver.

The Future

So, what's on the horizon for Firebug?  The next version is Firebug 1.4 is imminent; currently, the add-on gallery has beta 7, but you can get beta 8 if you'd like. Firebug 1.4 sports a completely new user interface.

There's a much improved Net tab.

You'll be able to adjust the keyboard shortcuts.

And of course, there are scores of bugs fixed and other general performance improvements (specifically to the Script tab), and other new features.


Well, you made it to the end! Now you can wield Firebug like the most advanced users; put what you've learned into practice and soon you'll be a Shihan!

Related Posts