This is indeed confusing, but it is specified in the CSS 2.1 specification, clause 14.2 Background: if the computed value of background-color
is transparent
and the computed value of background-image
is none
for the html
element (as things are by default), browsers must instead use the computed value of the background properties for the body
element and must not render a background for body
(i.e. make it transparent). That is, body
background magically turns to html
background if html
lacks a background of its own – and this only affects background properties, not the true height of the body
element.
I haven’t seen any rationale for this odd rule, which prescribes a kind of “reverse inheritance”. But it’s clearly specified in CSS 2.1 and applied by browsers.
As explained in other answers, you can make your content have a background of specific height either by setting a background on html
(so that body
background is really applied to body
only) or by using wrapper element inside body
and setting height on it (since the special rule applies to body
only).
Thanks to Anne van Kesteren who pointed to the CSS spec when I asked about this in the WHATWG mailing list. (I thought I knew CSS 2.1 by heart but really didn’t. ☺)