You are encountering the float bug (though I'm not sure if it's technically a bug due to how many browsers exhibit this behaviour). Here is what is happening:
Under normal circumstances, assuming that no explicit height has been set, a block level element such as a div will set its height based on its content. The bottom of the parent div will extend beyond the last element. Unfortunately, floating an element stops the parent from taking the floated element into account when determining its height. This means that if your last element is floated, it will not "stretch" the parent in the same way a normal element would.
Clearing
There are two common ways to fix this. The first is to add a "clearing" element; that is, another element below the floated one that will force the parent to stretch. So add the following html as the last child:
<div style="clear:both"></div>
It shouldn't be visible, and by using clear:both, you make sure that it won't sit next to the floated element, but after it.
Overflow:
The second method, which is preferred by most people (I think) is to change the CSS of the parent element so that the overflow is anything but "visible". So setting the overflow to "hidden" will force the parent to stretch beyond the bottom of the floated child. This is only true if you haven't set a height on the parent, of course.
Like I said, the second method is preferred as it doesn't require you to go and add semantically meaningless elements to your markup, but there are times when you need the overflow
to be visible, in which case adding a clearing element is more than acceptable.