CSS 2.1 spec: pathological case: html root element margin color - margin

I have been investigating the way in which the html root element and the body child element
interact in an HTML document. The following excerpt in the CSS 2.1 specification states
that in the box model margins are transparent, which we all know.
http://www.w3.org/TR/CSS21/box.html#mpb-examples
The margins of the LI boxes are transparent — margins are always
transparent — so the background color (yellow) of the UL padding and
content areas shines through them.
However, what has made me curious is, if margins are transparent, then if I give
the root element, namely the html element, a margin, this margin should show through
the default browser user agent canvas color. However, this is not the case as shown by
the snippet below. The margin of the top-level html element seems to make use of the
same color as the one specified in its background property. Here is the code:
<!doctype html>
<html style="margin: 40px; border: 1px solid black; background: green;">
<head>
<meta charset="utf-8">
<title>Test</title>
<style type="text/css">
* { margin: 0; border: 0; padding: 0; }
</style>
</head>
<body style="margin: 40px; width: 400px; height: 300px; background: pink;">
</body>
</html>
Here we can see the green margin pertaining to the html root element, containing the
black border pertaining to the html root element, containing the green margin pertaining
to the body element, containing the pink content pertaining to the body element.
Is this behavior specified anywhere in the CSS 2.1 specification?
If so, then where? I can't seem to find it anywhere.
Thanks.
EDIT:
As BoltClock pointed out below, this behavior is mentioned in section 14.2 of the CSS 2.1
specification (and is carried on to the CSS3 spec's Background and Borders module). That
is, unlike for other CSS elements, the background of the html element also covers the
margins area.
However, as BoltClock also pointed out below, that section also specifies that it is
considered more appropriate to set the background color on the body element rather
than on the html element. Here is the relevant excerpt from the CSS 2.1 spec:
For HTML documents, however, we recommend that authors specify the
background for the BODY element rather than the HTML element. For
documents whose root element is an HTML "HTML" element or an XHTML
"html" element that has computed values of 'transparent' for
'background-color' and 'none' for 'background-image', user agents must
instead use the computed value of the background properties from that
element's first HTML "BODY" element or XHTML "body" element child when
painting backgrounds for the canvas, and must not paint a background
for that child element. Such backgrounds must also be anchored at the
same point as they would be if they were painted only for the root
element.
So let us try and see what happens if in our original HTML we comment
out the background CSS property from the html element's style attribute
as follows:
<!doctype html>
<html style="margin: 40px; border: 1px solid black; /* background: green; */">
<head>
<meta charset="utf-8">
<title>Test</title>
<style type="text/css">
* { margin: 0; border: 0; padding: 0; }
</style>
</head>
<body style="margin: 40px; width: 400px; height: 300px; background: pink;">
</body>
</html>
Here is the result:
As we can see, the pink background from the body element is propagated to the
entire html element's box, thus covering the html element's margin, the html
element's border (which is not pink but black because for the html element
the border we specified is solid and black), and the body's margin element
and the body's content area which appear as a single pink area (although
we could assign a background to the body element and it would cover the
content area of course).
In any case, this investigation has been carried out because of pure interest.
For all practical purposes you normally wouldn't set anything for the html
element and would just allow the rule "* { margin: 0; border: 0; padding: 0; }"
to be fall through to the html and body elements and apply a background on the
body element or within a wrapper div contained within the body element.
Regards.

Yes, it's in section 14.2:
The background of the root element becomes the background of the canvas and covers the entire canvas, anchored (for 'background-position') at the same point as it would be if it was painted only for the root element itself. The root element does not paint this background again.
It's mentioned again in section 3.11 of the Backgrounds and Borders module, which supercedes this section of CSS2.1, so this specific behavior remains unchanged.
Since you mention interactions between the html and body elements, note that both links also contain details on how the body background should be propagated to the root element in certain circumstances when rendering an HTML document. And for those curious, all browsers follow this to the letter; it's based on the traditional behavior of painting the entire canvas with the background when you set the background and bgcolor attributes on the body element, so it's basically traditional HTML behavior specified in terms of CSS (to maintain backward compatibility with legacy sites if nothing else).

Related

why body background sat on 100 percent default what to do? [duplicate]

When you style the background of the body element, why does the styling affect the entire screen and not just the body element itself? Let's say I create the following rule:
body {
width: 700px;
height:200px;
border: 5px dotted red;
background-color: blue;
}
I find that the border shows up as 700px wide as I would expect, but the background color occupies the entire browser viewport. Why?
Quote from http://www.w3.org/TR/CSS21/colors.html
The background of the root element becomes the background of the canvas and covers the entire canvas, anchored (for 'background-position') at the same point as it would be if it was painted only for the root element itself. The root element does not paint this background again.
The body element is the root-element, and thus, as required by the CSS rules it loses its background style and the background style is applied to the containing canvas (the webpage area in the browser), therefor the entire screen is blue. The other properties stay with the element (e.g. the border).
From CSS: The Definitive Guide by Eric Meyer
In CSS values are never propagated
upward; that is, an element never
passes values up to its ancestors.
There is an exception to the upward
propagation rule in HTML: background
styles applied to the body element
can be passed to the html element,
which is the document's root element
and therefore defines its canvas.
So when you add the background-color: blue; declaration to the body element, this value is propagated to the html element (which is also the root element). Add this declartion to see it for yourself.
html {
background-color: grey;
}
When you set the background color of <body>, the browser interprets this as the background color for the entire window, even if you've forced the <body> to be smaller with CSS. Otherwise, what color would the outside of the <body> tag be?
This is why it's a good idea to use containers. Such as:
<body>
<div id="container">
</div>
</body>
Example here: http://jsfiddle.net/Shaz/2FqqV/
You cannot set a width on the <body> element itself, that's why the entire screen appears to be blue versus just a 700px area.
It must set the entire background, because you cannot define parts of the page that are "not" the body.
One of those mysteries of CSS, I guess.
A better idea is to place your content inside of a <div> element and style that instead of trying to style the whole <body> tag.

body background-color vs html background-color [duplicate]

$("#toggle").click(function(){
$("html").toggleClass("bg");
});
html.bg {
background: blue;
}
body {
background: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html class="bg">
<head>
</head>
<body>
Test
<br>
<button id="toggle">Toggle HTML background</button>
</body>
</html>
I found that if you apply a CSS background to body, it takes up the whole page (no matter what the actual height or width of body is).
However, if you apply a CSS background to both html and body, the background for body does not take up the whole page.
Is this discrepancy expected behavior?
How would I go about superimposing two fullscreen backgrounds (say, a background color and a semi-transparent image?)
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.
Suggest reading this:
https://css-tricks.com/just-one-of-those-weird-things-about-css-background-on-body/
Essentially, in the absence of a background on the html element, the body background will cover the page. If there is a background on the html element, the body background behaves just like any other element.

How to prevent background color of a body tag from spilling onto it's margin

I'm writing a very simple css code which is listed below:
body {
background-color:#616161;
margin-left: 20%;
}
Even though I've specified a 20% margin on the left side, the background color affects the margin area of the body tag as well. How do I ensure that the background color remains within the border?
Use a div to put the background color in
<html>
<body>
<div class="background">
<p>This is some text</p>
</div>
</body>
</html>
Then use this CSS to assign the color and the margin, you have to tweak the code to get the width and height where you want it
html{
height:100%;
}
body{
height:100%;
margin-top:0px;
margin-left: 20%;
}
.background{
min-height:100%;
height:auto;
background-color:#616161;
width:100%;
}
Or as miro pointed out:
html { background-color:#fff; }
body {
background-color:#616161;
margin:0% 0% 0% 20%;
}
Found nice description for this browser behaviour: "Background properties on the body element will propagate to the html element (the viewport), but only if the latter’s computed value for the background property is transparent." (link) + (testing fiddle).
The best solution here is to use the additional div just like user2067005 has suggested above.
W3C recommends:
For HTML documents, however, we recommend that authors specify the background for the BODY element rather than the HTML element. For documents whose root element is an HTML "HTML" element or an XHTML "html" element that has computed values of 'transparent' for 'background-color' and 'none' for 'background-image', user agents must instead use the computed value of the background properties from that element's first HTML "BODY" element or XHTML "body" element child when painting backgrounds for the canvas, and must not paint a background for that child element. Such backgrounds must also be anchored at the same point as they would be if they were painted only for the root element. (link)

<a> tags using CSS background images have no text

I have tags and submit buttons on a website that were built using background images that included the words Submit, Go, etc. If images are disabled then the buttons completely disappear. The specifications when building the website were quite detailed and strict.
They like a mouse-over effect when hovering over buttons. This is
accomplished with image sprites as background images and the hover
selector.
They purchased a special font to be used in the graphics that is not
a web standard font.
They like the drop shadow on the text in the graphics and all of the
buttons have white text.
They like rounded corners on their buttons so all background images
have transparent corners because some pages are white and some forms
have a yellow background.
One solution I thought of where they would not have to give up anything is to put a 1 pixel transparent gif in an img tag in the anchor tag and put the "Go" or "Submit" text in the alt attribute. Is that acceptable, especially for SEO purposes?
The other method just leads to a chain of changes I'd rather not do, but will if I have to.
Keep the background image but move the text to the anchor link and use a standard web font. But since this would still be white text on a white page and not visible, I'd have to assign a dark background color. But since this would appear behind the transparent corners of the images, I'll have to make up multiple versions of the same buttons with different background colors for the white and yellow page/forms.
Or is there something else that I haven't thought of?
From a general DOM spec, there is no mandatory requirements for <a> tags to have a text; they can have, for e.g., an image (<img> element) that may serve as a 'clickable' link.
Explain to your client that using images for buttons isn't best practice. Intsead, use CSS3 to generate the buttons- Better performance and easier to maintain. As for the custom font they use, check to see if there's an option to license use for #font-face. If not, I'm sure there's a similar font out there.
You can do this easily enough with "image replacement" techniques, where an image is placed over the original text. The original text shows in place of the images if images are disabled or if they don't load. It's a little tricky if the images are transparent, but it can be done. Here's a simple example with a button element, but it can be done on most elements:
http://pageaffairs.com/sp/so-16469524-sprite/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style media="all">
body {background: #e7e7e7;}
button {
position: relative;
width: 150px;
height:40px;
color: white;
border: 0;
text-align: center;
line-height: 30px;
background: #27485b;
cursor: pointer;
border-radius: 10px;
font-size: 1.4em;
}
button:hover {background: #bd9755;}
button span {
position: absolute;
top: 0;
left: 0;
width: 150px;
height: 40px;
background: url(http://pageaffairs.com/sp/so-16469524-sprite/bg.png) no-repeat 0 0;
}
button:hover span {background-position: 0 -40px;}
</style>
</head>
<body>
<button value="Send" name="submit" type="submit">Submit<span></span></button>
</body>
</html>

Is it bad or totally wrong to get a horizontally centered page by tuning CSS properties of html tag?

Is it bad or totally wrong to get a horizontally centered page by tuning CSS properties of html tag?
css code snippet:
<style type="text/css">
html
{
width: 1200px;
margin: 0px auto;
background-color: Gray;
}
body
{
background-color: red;
}
</style>
html code snippet:
<body>any contents go here...</body>
The html is the father of every element in the page. If it becomes centered, let's say you want to position something absolutely at the top left/right of your entire page. It will now become relative to the centered html element, most likely... and it would be a pain having to offset that effect, which is why I don't recommend doing so.
This is why it's better to center at least the body or a div wrapper.
EDIT: It seems like the AP'd element will be relative to the entire viewport in my actual test ( in Fx 3 ), but even so it could be inconsistent cross browser and inconsistent with IE.
You're guaranteed things will go right by centering the wrapper.

Resources