Applying a Background to ≪Html≫ And/Or ≪Body≫

Applying a background to html and/or body

This is correct behavior.1 In standards mode, body, as well as html, doesn't immediately take up the entire height of the viewport, even though it appears so when you only apply a background to the latter. In fact, the html element will take on the background of body if you don't give it its own background, and html will pass this on to the canvas:

The background of the root element becomes the background of the canvas and its background painting area extends to cover the entire canvas, although any images are sized and positioned relative to the root element as if they were painted for that element alone. (In other words, the background positioning area is determined as for the root element.) If the root's ‘background-color’ value is ‘transparent’, the canvas's background color is UA dependent. The root element does not paint this background again, i.e., the used value of its background is transparent.

For documents whose root element is an HTML HTML element or an XHTML html element: if the computed value of ‘background-image’ on the root element is ‘none’ and its ‘background-color’ is ‘transparent’, user agents must instead propagate the computed values of the background properties from that element's first HTML BODY or XHTML body child element. The used values of that BODY element's background properties are their initial values, and the propagated values are treated as if they were specified on the root element. It is recommended that authors of HTML documents specify the canvas background for the BODY element rather than the HTML element.

That said, however, you can superimpose any background image over a background color on a single element (either html or body), without having to rely on two elements — simply use background-color and background-image or combine them in the background shorthand property:

body {
background: #ddd url(background.png) center top no-repeat;
}

If you wish to combine two background images, you need to rely on multiple backgrounds. There are chiefly two days to do this:

  • In CSS2, this is where styling both elements comes in handy: simply set a background image to html and another image to body which you wish to superimpose over the first. To ensure the background image on body displays at full viewport height, you need to apply height and min-height respectively as well:

    html {
    height: 100%;
    background: #ddd url(background1.png) repeat;
    }

    body {
    min-height: 100%;
    background: transparent url(background2.png) center top no-repeat;
    }

    Incidentally, the reason why you have to specify height and min-height to html and body respectively is because neither element has any intrinsic height. Both are height: auto by default. It is the viewport that has 100% height, so height: 100% is taken from the viewport, then applied to body as a minimum to allow for scrolling of content.

  • In CSS3, the syntax has been extended so you can declare multiple background values in a single property, eliminating the need to apply backgrounds to multiple elements (or adjust height/min-height):

    body {
    background: url(background2.png) center top no-repeat,
    #ddd url(background1.png) repeat;
    }

    The only caveat is that in a single multi-layered background, only the bottommost layer may have a background color. You can see in this example that the transparent value is missing from the upper layer.

    And don't worry — the behavior specified above with propagating background values works exactly the same even if you use multi-layered backgrounds.

If you need to support older browsers, though, you'll need to go with the CSS2 method, which is supported all the way back to IE7.

My comments under this other answer explain, with an accompanying fiddle, how body is actually offset from html by default margins even though it looks like it's being padded out instead, again owing to this seemingly strange phenomenon.


1 This may have its roots in setting the HTML background and bgcolor attributes of body causing the background attribute to apply to the entire viewport. More on that here.

Set background in body or html

Here is a very interesting article.

https://css-tricks.com/html-vs-body-in-css/

Giving background-color to body applying whole page. Why?

The main reason is because the HTML takes the background-color of BODY since:

The background of the root element becomes the background of the
canvas and covers the entire canvas [...]

So since the default background-color of HTML is transparent it will take the one from BODY. However applying a color to both the HTML and BODY elements you will see that the BODY background doesn't cover the whole page anymore.

html {  background-color: blue;}
body { background-color: red;}
<html>
<body> <div>Hello World!</div></body>
</html>

Changing the background color and width of the body element

You're actually doing it, except when you don't declare a background color for the html element, it then takes the background color of the body element. Hence, you're not seeing the difference.

Simply give the html element a different background color, and also give body some height:

html {    background-color: red;     /* new */}
body { border: 1px solid black; width: 500px; height: 500px; /* new */ margin: 0 auto; background: black;}

best way to implement background image on HTML or body

body{
background-image:url('../images/background.jpg');
background-attachment:fixed;
background-repeat: no-repeat;
background-size: cover;
}

This would be the best way, you could apply it to the HTML, it really depends on what you prefer...

background-image:url('../images/background.jpg');

Assuming your css file is in a different map, you do ../ to go to the map in which your css folder is placed, then you go into the images file and select the image.

background-attachment:fixed;

When setting a background-image I personally like to use this, it makes it so that when a user scrolls, the background-image maintains it's current position.

background-repeat: no-repeat;

When using this setting, it makes it so that the image won't repeat, in case it is too small or just won't cover the whole background.

background-size: cover;

When you apply this you will set the background-size to cover, combined with no-repeat and attachment: fixed it makes for a good way to style your background image

why does background-color property fills the entire screen even body have 0 height?

body tag is always taking the whole document's body, so if you want to give background with limited height then put one DIV inside the body tag and then give specific height, then it will work fine.

so for the solution, please give background color to HTML div as well.

html {
background-color: #ffffff;
}

Body's background is overflowing

That is weird. That's not what I would have expected, but this seems to indicate it's a known behavior, that if the background color on <html> isn't set, but the background color on <body> is, the <body> background will flood the whole <html> area.

To quote the spec:

For documents whose root element is an HTML HTML element or an XHTML
html element [HTML]: if the computed value of background-image on the
root element is none and its background-color is transparent, user
agents must instead propagate the computed values of the background
properties from that element’s first HTML BODY or XHTML body child
element. The used values of that BODY element’s background properties
are their initial values, and the propagated values are treated as if
they were specified on the root element.

You can also see an example at that spec link that is similar to yours.

UPDATE:

RE: your other question about <html> element's propagating to the viewport's background, I think that is also answered in a nearby section of the spec, though it is a little less clear to me:

The background of the root element becomes the canvas background and
its background painting area extends to cover the entire canvas.

Note canvas in this case refers to the infinite surface the page is rendered on, not the HTML5 canvas. This seems to me to describe the behavior you mentioned in a comment where the background of a <html> with a small width/height is propagated to the viewport, though why they need the additional section I quoted above, I'm not sure about. There is more info at that link if you are curious. There seems to be some overlap between sections AFAICT.

The Canvas Background and the HTML body Element

Prior to CSS, backgrounds were specified by adding the background and bgcolor attributes to the body element in HTML (along with the likes of text, link, alink, vlink, leftmargin, marginwidth, topmargin and marginheight).

CSS-compliant browsers convert these presentational attributes into the appropriate style rules, placed as author-level presentational hints with just less precedence than author-level * rules. More on this in css-cascade-3 and HTML. Namely, the background and bgcolor attributes are converted to background-image and background-color declarations respectively, for the body element.

So, the recommendation that authors specify the canvas background for the body element and not the html element was made to ease migration of legacy HTML documents from presentational attributes on the body element to CSS. Normally if you have control of both the markup and CSS the first thing you'd probably want to do is get rid of the presentational attributes. But you don't have to do so right off the bat; you can just add a background declaration specific to the body element, and it will seamlessly replace the entire page background (as described in the spec link in the question) as specified by the presentational attributes, with no further action necessary: