Closed Bug 15405 Opened 25 years ago Closed 20 years ago

:root element stretches vertically to fit viewport [BG] (grows)

Categories

(Core :: Layout, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: ian, Unassigned)

References

(Blocks 1 open bug, )

Details

(Keywords: css1, testcase, Whiteboard: [Hixie-P1])

The root element is stretching to fit the viewport if its contents are smaller
than the height of the viewport. It should not.

According to CSS2, section 9.1.2:
# The height of the initial containing block may be specified with the
# 'height' property for the root element. If this property has the value
# 'auto', the containing block height will grow to accommodate the document's
# content.

The initial value is 'auto', and so the height of the root element should
shrinkwrap the contents. Currently we are using the maximum of either the
content height or the viewport height.

There is an HTML test page for this:
   http://www.bath.ac.uk/%7Epy8ieh/internet/projects/mozilla/background/17.html
...and an XML version:
   http://www.bath.ac.uk/%7Epy8ieh/internet/projects/mozilla/background/18.xml

[cc'ing David. David, I'm only 99% sure that about this; I found it by
accident. Section 14.2¶3 (see bug 7656, bug 13473) would tend to suggest that
this is indeed a bug, though. Do you agree?]
No, I don't agree. We used to do what you describe, but that broke backwards
compatibility for HTML documents because then the background wasn't
being displayed.

So the solution, which I don't think you agree with _how_ this was done, was to
make sure that the document element's frame is sized to cover the canvas
Right, but according to section 14.2 paragraph 3 of CSS2, the root
element's *background* (and not its *box*) covers the canvas anyway:

# The background of the box generated by the root element covers the
# entire canvas.

Note that it says _background_ not box! The box is sized as per 9.1.2, and then
the background -- in this special case -- is spilt straight out of the box and
covers the canvas. (Note that this does NOT mean that you just paint over the
margins of the root element as the bottom margin won't reach the bottom of the
viewport, and the margins won't cover anything sticking out of the left/right of
the viewport.)

So the spec-compliant solution is to follow both these rules -- section 9.1.2
and section 14.2 -- and then you get full backwards compatability to boot.
Status: NEW → RESOLVED
Closed: 25 years ago
Resolution: --- → WONTFIX
What you suggest may be more correct (although I'm dubious), but we're not doing
it. It's reasonable the way it is now, and it's way too late for version 1.0 to
be making changes to how the viewport model works
Status: RESOLVED → REOPENED
Summary: Root element is stretching to fit the viewport → {css1} Root element is stretching to fit the viewport
Ok. I'm going to mark this LATER, we can reargue it once 1.0 is out.

David: When the WaSP review Mozilla, this may have to be the one thing we
complain about... ;-)
Status: REOPENED → RESOLVED
Closed: 25 years ago25 years ago
Resolution: WONTFIX → LATER
I think that part of the CSS2 spec needs to be reconsidered. It's horrible to
have so many exceptions to the normal rules. We have to reverse propagate the
BODY's background up to the HTML element which is bad enough, and to to have to
special case the document element's background is even worse

It sure looks like the CSS authors spent all of about 5 seconds writing that
part of the spec...
Actually, we currently have as many special cases as we would if we changed to
the spec way -- currently, we special case the height of the root element, which
the spec way doesn't do (the root element acts as a simple block box). The only
special case in the spec is the fact that the root element bg spills into its
containing block, the canvas. So we would just be exchanging one special case
for another. A spec compliant one... :-)
The document element's box isn't necessarily a block. It could be an inline, a
table, a list item, or anything for that matter. At least I don't think the spec
precludes it

Yes, what we're doing today probably isn't what the spec wants, but it's easy
and clean to implement. All we do have the root frame (that corresponds to the
'canvas') make sure it's child frame covers the canvas

Then the rendering just works.

The problem with not doing it this way is that the document element's box is
small, and _somehow_ we need to make sure that when it renders it paints over
the entire canvas

I say _somehow_ because that certainly isn't the normal CSS behavior. Normally
a box paints the background over its content and padding areas only, and not
outside of its box.

Because the document element isn't necessarily a 'block' that means this quirky
behavior isn't limited to just one occurence, and each and every frame class
that could be used for the document element's box needs to be able to do this.

What about the case where the document element has a fixed height and 'overflow'
set to 'scroll' or 'auto'. How does the background render in that case? Does it
behave like a 'fixed' background attachment, or does the background change as
the document element is scrolled? If so, then does the background that's
splattered out onto the canvas need to repaint as well, or does it get out of
sync?

If they want it to cover the canvas then I think I would prefer if they said
that the 'canvas' should render the background. Much like they've done with the
BODY's background being moved to the HTML element and it renders it

And what if the document element is positioned? I think the spec currently
forbids that, but I seem to remember that you would like that. If it's
positioned should it still paint over the entire canvas? That seems kind of odd
as well

That's just the beginning of the woes with this approach. From an implementation
perspective we currently have all sorts of other issues:

- how does the document element's frame even know how much to paint? When we
paint we intersect the dirty rect with the frame's box and tell it that's what
it needs to paint. In this case that won't be true, because it needs to paint
the canvas as well

- if the document element's frame has a view, e.g., it has opacity, it's
positioned, ..., then the view code won't let it paint outside of its view. That
means we will need to size the view to be the same size as the canvas in order
for it to paint outside its view

There are all sort of issues that this quirk exposes.
> The document element's box isn't necessarily a block. It could be an
> inline, a table, a list item, or anything for that matter. At least
> I don't think the spec precludes it.

No, nothing does preclude it, AFAICT (David?). And we don't support
it. Oops. This issue is now covered by bug 15462.


> I say _somehow_ because that certainly isn't the normal CSS
> behavior. Normally a box paints the background over its content and
> padding areas only, and not outside of its box.

True. But then normally a CSS box does not size it self to the size of
the viewport either, and yet we are doing that.


> Because the document element isn't necessarily a 'block' that means
> this quirky behavior isn't limited to just one occurence, and each
> and every frame class that could be used for the document element's
> box needs to be able to do this.

Hmm. Surely (hah!) what you could do is just make the canvas paint
itself with the background offset so that its start position is the
same (in window coordinates) as the start of the root element's
position. That way the root element doesn't have to paint outside
itself, it only has to inform the canvas that it has changed.


> What about the case where the document element has a fixed height
> and 'overflow' set to 'scroll' or 'auto'. How does the background
> render in that case?

Interesting point. It is not covered by the spec. I would say that the
canvas would have to move its background too, to keep it in sync with
the root element's. That, though, is no bigger a deal than dynamically
changing the value of 'background-position' in the same scenario:
background of root is rerendered, so notify the canvas.


> If they want it to cover the canvas then I think I would prefer if
> they said that the 'canvas' should render the background. Much like
> they've done with the BODY's background being moved to the HTML
> element and it renders it.

That would have exactly the same effect, which is fine by me. So long
as in the BODY->HTML case, the _specified_ background values are
`inherited', while with the canvas the _actual_ values are
`inherited'. And making sure that the root element is not made
transparent, like the BODY element is. (Because otherwise you are open
to weirdness with 'z-index'.)


> And what if the document element is positioned? I think the spec
> currently forbids that, but I seem to remember that you would like
> that. If it's positioned should it still paint over the entire
> canvas? That seems kind of odd as well.

Well, if we implement it as the canvas drawing the background in sync
with the root element, then there is no big problem here. (And yes,
the canvas would still use the root element's background.)


> - how does the document element's frame even know how much to paint?
> When we paint we intersect the dirty rect with the frame's box and
> tell it that's what it needs to paint. In this case that won't be
> true, because it needs to paint the canvas as well.

Well, if you let the canvas paint itself in sync with the root
element, you could `just' trigger an event when the root element
paints it's background.


> - if the document element's frame has a view, e.g., it has opacity,
> it's positioned, ..., then the view code won't let it paint outside
> of its view. That means we will need to size the view to be the same
> size as the canvas in order for it to paint outside its view.

Not if you just get the canvas to paint in sync; then you just need to
make sure the canvas is notified.
My main point was to emphasize that the way the spec is defined now it seems
like they expect the document element's box to splat its background over the
cancas, and that opens up a whole can of worms
QA Contact: petersen → chrisd
QA Contact: chrisd → petersen
QA Contact: petersen → chrisd
I don't disagree, but I believe you can get exactly the same effect by simply
deferring the painting to the canvas itself, and just keeping the background
positions in sync. The effect is identical, but the implementation is a lot
easier (relatively speaking, anyway). Right?
Maybe. I would be more comfortable implementing this if the spec were clearer
and address cases like where the document element is scrollable.

Otherwise, these kind of changes tend to consume a lot of time and often require
several iterations to get it right
Agreed, that's why I marked it LATER.
Status: RESOLVED → VERIFIED
Verified bug LATER.
Keywords: css1
Migrating from {css1} to css1 keyword. The {css1}, {css2}, {css3} and {css-moz}
radars should now be considered deprecated in favour of keywords.
I am *really* sorry about the spam...
Reopening bug
Status: VERIFIED → REOPENED
Resolution: LATER → ---
Status: REOPENED → ASSIGNED
Part of the bug has been fixed. I changed the frame construction code to 
propagate the document element's backgroun to the canvas so that the background 
is rendered to cover the entire canvas
Eric, the remaining problem is that the document element is getting sized to 
large. The problem is because when the canvas frame is reflowed it is given a 
constrained computed width instead of NS_AUTOHEIGHT like it should get

What seems to be happening is that the gfx scrollbar code which does get 
reflowed with a constrained computed height is passing that constrained height 
along to the canvas frame instead of giving it NS_AUITOHEIGHT like it should 
get.
Assignee: troy → evaughan
Status: ASSIGNED → NEW
Is the CanvasFrame the same as the root element?  If you've just started
propagating the background color of the root element to the canvas, I'd think
not...  But if that's the case, what should happen is that the canvas should
fill the viewport, and the root element shouldn't.

If the only changes you (troy) made today were in the background-color
propogation, then I think the current behavior is 100% correct.  I'll have to
check tomorrow's build against
http://www.people.fas.harvard.edu/~dbaron/css/test/rootbox
Yes, RootFrame has now been renamed CanvasFrame. The old name made sense when it 
really was the root frame (i.e., the top-most frame that had no parent), but 
that hasn't been true for ages since we added the viewport and viewport scroller

And yes, now we reverse propagate the document element's background to the 
canvas. That way we can satisfy section 14.2 of the CSS2 spec that says that the 
document element's background should cover the entire canvas.

And yes again, I agree that the document element's box should not fill the 
entire canvas. That was what I had attempted to do a long time ago in order to 
have the document element's background cover the canvas

But you and Ian convinced me that was wrong. Unfortunately, the gfx scrollframe 
code is causing the document element's frame to be sized to the viewport size 
which is bad and that's why the bug is now assigned to Eric. So the remaining 
problemn can be fixed
Oops - never mind.  Somehow I was convinced that Mozilla displayed the test I
mentioned in my previous comment differently from the way it really does...

*** This bug has been marked as a duplicate of 35681 ***
Status: NEW → RESOLVED
Closed: 25 years ago24 years ago
Resolution: --- → DUPLICATE
Summary: {css1} Root element is stretching to fit the viewport → Root element is stretching to fit the viewport
Whiteboard: (py8ieh:verify when dup is fixed)
This one isn't fixed completely.  Reopening from duplicate.  Bug 35681 covered 
horizontal issues, which are now fixed.   I'm reopening this bug, which was 
really about vertical issues to begin with.
Status: RESOLVED → REOPENED
Resolution: DUPLICATE → ---
As per meeting with ChrisD today, taking QA.
QA Contact: chrisd → py8ieh=bugzilla
nsbeta3-, don't see dire need to hold ns6 for this bug.
Whiteboard: (py8ieh:verify when dup is fixed) → [nsbeta3-](py8ieh:verify when dup is fixed)
Target Milestone: --- → Future
Note: MacIE5 does this right.
Keywords: 4xp
Whiteboard: [nsbeta3-](py8ieh:verify when dup is fixed) → [nsbeta3-] hit during nsbeta2 standards compliance testing
Summary: Root element is stretching to fit the viewport → Root element is stretching to fit the viewport [BG]
Blocks: 54661
Summary: Root element is stretching to fit the viewport [BG] → Root element is stretching vertically to fit the viewport [BG]
Bug 57906 is now tracking the horizontal issues.
*** Bug 57682 has been marked as a duplicate of this bug. ***
Target Milestone: Future → mozilla0.9
Keywords: nsbeta3nsbeta1
Whiteboard: [nsbeta3-] hit during nsbeta2 standards compliance testing → hit during nsbeta2 standards compliance testing
->moz1.0
Target Milestone: mozilla0.9 → mozilla1.0
Whiteboard: hit during nsbeta2 standards compliance testing → [Hixie-P2] hit during nsbeta2 standards compliance testing
Blocks: 104166
Blocks: 103709
Bugs targeted at mozilla1.0 without the mozilla1.0 keyword moved to mozilla1.0.1 
(you can query for this string to delete spam or retrieve the list of bugs I've 
moved)
Target Milestone: mozilla1.0 → mozilla1.0.1
don't move bugs that are in the 1.0 dependency tree. sorry.

Target Milestone: mozilla1.0.1 → mozilla1.0
Blocks: 105286
The behavior Ian describes is also observed using FizzillaCFM/2002070913.
Setting All/All.
OS: Windows 98 → All
Hardware: PC → All
See bug 157698 for a somewhat interesting testcase (although quite confused by
other issues as well).
Severity: minor → normal
Summary: Root element is stretching vertically to fit the viewport [BG] → :root element stretches vertically to fit viewport [BG] (grows)
->boris for fun
Assignee: eric → bzbarsky
Status: REOPENED → NEW
Target Milestone: mozilla1.0 → Future
css1->css2, since CSS2 section 14.2 has been cited throughout the bug...
Keywords: css1css2
It's still a CSS1 bug, even if we refer to CSS2.
Keywords: css2css1
comment 7 The document element's box isn't necessarily a block.

Block level elements can't be contained by inline elements. That means body must
be inline, too. It is not something that really needs to be done. It does not
seem that it will be of any practical use.

It is conceiveable that html could be block-table, body could be table-row, and
a div inside the body could be table cell. Stupid idea, though.


In addition to background-color, all other background properties should be
propagated to the canvas.

background
 - background-color
 - background-image
 - background-repeat
 - background-attachment
 - background-position
 - background-positionX
 - background-positionY


comment 7
What about the case where the document element has a fixed height and 'overflow'
set to 'scroll' or 'auto'. How does the background render in that case? Does it
behave like a 'fixed' background attachment, or does the background change as
the document element is scrolled?

It is fixed to the canvas. The background of the box generated by the root
element covers the entire canvas. 

If the value of the 'background' property for the HTML element is different from
'transparent' then use it, else use the value of the 'background' property for
the BODY element.. Let body override this. See 14.2 The background:
http://www.w3.org/TR/REC-CSS2/colors.html#q2

Comment 8 "making sure that the root element is not made
transparent, like the BODY element is. (Because otherwise you are open
to weirdness with 'z-index'.)"

I don't see what could go wrong. body inherits stacking order from root. What's
the problem? 


> - if the document element's frame has a view, e.g., it has opacity,
> it's positioned, ..., then the view code won't let it paint outside
> of its view. That means we will need to size the view to be the same
> size as the canvas in order for it to paint outside its view.

The initial containing block cannot be positioned or floated (i.e., user agents
ignore the 'position' and 'float' properties for the root element).
http://www.w3.org/TR/REC-CSS2/visuren.html#q2

"initial containing block" is defined as the root. Given the fact that this
definition is incorrect, it is up to the mystics (David Baron, Ian Hickson, et
c.) to determine what the above statement means. It would be impossible to
position the initial containing block, but it would not be impossible to
position the root element, although this may be illegal. The question is: What
is meant by "initial containing block" in the above referenced statement?

Before getting too caught up in "all kinds of issues," lets get our terms
straight (as opposed to CSS 2 spec, which is not).

> Block level elements can't be contained by inline elements. 

This is a statement about HTML, not CSS.  The concepts of "block and inline" 
are subtly different in HTML and CSS; this is one of the really major 
differences.  A CSS inline can most certainly contain a CSS block.

> The background of the box generated by the root element covers the entire
> canvas. 

It should not.  That's precisely what this bug is about.

The positioning issue is a side issue; the root element can certainly have 
opacity set and that will lead to the same problem with painting...
14.2 The background

"The background of the box generated by the root element covers the entire canvas."
 
--------------------

Test:
1) go to: http://www.people.fas.harvard.edu/~dbaron/css/test/rootbox
2) maximize window
3) choose view -> Text Zoom -> 50%

Actual Result: html's height is stretched so that it's content area is expanded.
The border is always at the edge of the initial containing block.

Expected Result: html's height should be the distance from the top border-edge
of the body, to the bottom border-edge of the body. 
http://www.w3.org/TR/REC-CSS2/visudet.html#the-height-property

-----------------

From initial report 
"The initial value is 'auto', and so the height of the root element should
shrinkwrap the contents."

Correct.

-----------

comment 37
"A CSS inline can most certainly contain a CSS block."

"unless the element is absolutely positioned, the containing block is formed by
the content edge of the nearest block-level ancestor box."
 (10.1 http://www.w3.org/TR/REC-CSS2/visudet.html#containing-block-details )

body{display: block} 
html{background: #eee;display:inline }
body should appear outside of the HTML element. 
The canvas should have a background color of #eee;

Please don't confused "contained in" and "containing block".... The body would 
appear in between two of the line boxes of <html> in your example (and the 
canvas background would be #eee).  None of which addresses the original concern 
Troy expressed, as far as I can see (though the concern may have been specious).
The ICB is a box the size of the viewport anchored at the origin. The root
element is just a normal block box anchored at 0,0 in the ICB.

Anyway, this bug is still valid, and unambiguous, just as it was over three
years ago when I filed it...
Regarding Comment 40,
The root has a few other properties that make it special. The CSS 2 spec is very
ambiguous about this whole area. This is also evidenced in some of the comments
that were made. 

The bug is absolutely valid; no doubt about it. My additional comments and the 
replies they prompted are important because they show how much misunderstanding
there is about this. 


10.1
"If there is no such ancestor, the content edge of the root element's box
establishes the containing block."

So absolutely positioned elements that have no containing block will use the
root as a containing block. This is evidenced in
http://dbaron.org/css/test/sec090102
If the root were "just a box in normal flow," then the absolutely positioned
divs would have to use the ICB, unless the root had absolute positioning. It is
my opinion that the root should be in normal flow and that user agents should
allow such behavior. User-Agents should also use position: absolute in the
default stylesheet, so that stuff would work just like it does in the
aforementioned test case.

Regarding Comment 40,
The root has a few other properties that make it special. The CSS 2 spec is very
ambiguous about this whole area. This is also evidenced in some of the comments
that were made. 

The bug is absolutely valid; no doubt about it. My additional comments and the 
replies they prompted are important because they show how much misunderstanding
there is about this. 


10.1
"If there is no such ancestor, the content edge of the root element's box
establishes the containing block."

So absolutely positioned elements that have no containing block will use the
root as a containing block. This is evidenced in
http://dbaron.org/css/test/sec090102

If the root were "just a box in normal flow," then the absolutely positioned
divs would have to use the ICB, unless the root had absolute positioning. It is
my opinion that the root should be in normal flow and that user agents should
allow such behavior. User-Agents should also use html{position: absolute;} in
the default stylesheet, so that stuff would work just like it does in the
aforementioned test case.

You can try typing this into the location bar of the test case:
javascript:void(document.documentElement.style.position='static'); It has no effect.
Please refer to CSS2.1, not CSS2, when examining containing block issues.
Priority: P3 → P4
Whiteboard: [Hixie-P2] hit during nsbeta2 standards compliance testing → [Hixie-P1]
Blocks: 228942
No plans to work on this any time in the foreseeable future, so to default owner.
Assignee: bz-vacation → nobody
QA Contact: ian → core.layout
Priority: P4 → --
Target Milestone: Future → ---
*** Bug 234039 has been marked as a duplicate of this bug. ***
Depends on: 241694
Fixed by checkin for bug 241694.
Status: NEW → RESOLVED
Closed: 24 years ago20 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.