What's the Meaning of "Propagated to the Viewport" in the CSS Spec

What's the meaning of propagated to the viewport in the CSS spec?

As the quote states, the overflow property is capable of being propagated from body to html, and from html to the viewport:

UAs must apply the 'overflow' property set on the root element to the viewport. When the root element is an HTML "HTML" element or an XHTML "html" element, and that element has an HTML "BODY" element or an XHTML "body" element as a child, user agents must instead apply the 'overflow' property from the first such child element to the viewport, if the value on the root element is 'visible'. The 'visible' value when used for the viewport must be interpreted as 'auto'. The element from which the value is propagated must have a used value for 'overflow' of 'visible'.

The other property that can be propagated in this manner is background:

Since no element corresponds to the canvas, in order to allow styling of the canvas CSS propagates the background of the root element (or, in the case of HTML, the <body> element) as described below.

3.11.1. The Canvas Background and the Root Element

The background of the root element becomes the background of the canvas and its background painting area extends to cover the entire canvas. However, 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.) The root element does not paint this background again, i.e., the used value of its background is transparent.

3.11.2. The Canvas Background and the HTML <body> Element

For documents whose root element is an HTML HTML element [HTML401] or an XHTML html element [XHTML11]: 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.

This propagating behavior is specified for historical reasons (<body background="..." bgcolor="...">) as well as to enable authors to style the entire page background, something that cannot normally be done solely through the html or body elements without first removing their default margins and forcing them to fill the page.

Authors not aware of this behavior who try to apply these two properties to body and html may be surprised by the results, especially when comparing the behavior with other elements. On the other hand, authors have also exploited this behavior to create interesting workarounds for browser bugs dating back over 15 years.

This behavior does not conflict with inheritance because it works in the opposite direction. Inheritance "propagates" property values from a parent element to a child element; this behavior propagates property values from a child box to a parent box (body to html, and html to the viewport respectively).

What exactly is a formatting context?

A formatting context is not really an area. It's more a state of a box that defines the set of layout rules that apply to itself and its participant boxes.

Why doesn't the html element take up the whole browser viewport?

Despite being the root element, html has no special attributes in terms of CSS; it is a regular block box in the normal flow, and block boxes by default don't have an intrinsic height. The default height is auto; the specific details of how auto is calculated are described in the spec, but basically for in-flow block boxes this means as tall as their contents require, and no more. The same applies to the body element.

Note that if you specify a background color for html, that background color will propagate or "bleed" onto the entire viewport, although the height of html does not change. This behavior is intentional (the background can also be propagated from body to html in a similar manner); see my answers to these related questions for an explanation:

  • <html> width is less than its background
  • Applying a background to <html> and/or <body>

Note, also, that the behavior you expect, i.e.,

Isn't html supposed to default to fit the entire screen in a browser?

does apply in quirks mode and to very old versions of IE (older than 6); mostly a consequence of poor adherence to poorly defined web standards (this was a time when the original CSS2 recommendation was published, and CSS itself was still in its infancy). That is, the html and body elements are indeed both 100% of the viewport height in quirks mode, and the aforementioned behavior of html and body defaulting to content height only applies in standards mode.

html width is less than its background

html is a proper block-level element, just like body, p, div, etc — it therefore observes all the same overflow rules as other block elements do.

However, the reason why the background of html bleeds past its border when content overflows its width (or when its width is less than 100% of the browser window, or viewport), is because the background color is propagated to the viewport, which is the canvas containing html and all its contents that are rendered. The border remains part of the html element, however, so the element doesn't expand when the content overflows. This behavior is very similar to how applying a background to body, but not html, causes the body background to propagate to the root element anyway, as described in this answer which cites this section of the spec.

As Alohci notes in a comment under the answer, the same applies to html with respect to the viewport:

Note that html behaves with respect to the viewport in much the same way as body behaves with respect to html, with the background escaping beyond the confines of the html element. See http://jsfiddle.net/GmAL4/4/ to see what I mean.

Who is responsible for establishing formatting context for `body` element?

the body element acts as block container box.

No, it doesn't. We can easily proove it by using a float element:

.float {
height:50px;
width:50px;
background:red;
float:left;
}

body {
border:2px solid blue;
}

html {
border:2px solid green
}
<div class="float"></div> some text here

Difference in applying CSS to html, body, and the universal selector *?

  1. html {
    color: black;
    background-color: white;
    }

    This rule applies the colors to the html element. All descendants of the html element inherit its color (but not background-color), including body. The body element has no default background color, meaning it's transparent, so html's background will show through until and unless you set a background for body.

    Although the background of html is painted over the entire viewport, the html element itself does not span the entire height of the viewport automatically; the background is simply propagated to the viewport. See this answer for details.

  2. body {
    color: black;
    background-color: white;
    }

    This rule applies the colors to the body element. All descendants of the body element inherit its color.

    Similarly to how the background of html is propagated to the viewport automatically, the background of body will be propagated to html automatically, until and unless you set a background for html as well. See this answer for an explanation. Because of this, if you only need one background (in usual circumstances), whether you use the first rule or the second rule won't make any real difference.

    You can, however, combine background styles for html and body with other tricks to get some nifty background effects, like I've done here. See the above linked answer for how.

  3. * {
    color: black;
    background-color: white;
    }

    This rule applies the colors to every element, so neither of the two properties is implicitly inherited. But you can easily override this rule with anything else, including either of the above two rules, as * has literally no significance in selector specificity.

    Because this breaks the inheritance chain completely for any property that is normally inherited such as color, setting those properties in a * rule is considered bad practice unless you have a very good reason to break inheritance this way (most use cases that involve breaking inheritance require you to do it for just one element, not all of them).

Why does styling the background of the body element affect the entire screen?

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).



Related Topics



Leave a reply



Submit