Closed Bug 170011 Opened 22 years ago Closed 20 years ago

Adding overflow: style to <body> with position:fixed causes some <div>s to disappear

Categories

(Core :: Web Painting, defect)

defect
Not set
normal

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: psheerin, Assigned: roc)

References

()

Details

(Whiteboard: [csswg])

Attachments

(1 file)

The page described modifies a hybrid fixed/absolute layout by changing the
positioning of the <body> from absolute to fixed, by overriding three lines of
the linked style sheet. This causes all content in two (the top logo bar and the
square ad) of the four positioned divs (all of which are outside the <body>
coordinates) to disappear.

The override css code is shown below, and I've narrowed the problem down to one
line:

body	{
	position: fixed;
	bottom: 0px;
	overflow: auto;
	}

Removing the overflow: property or setting it to inherit restores the missing
content, with the unfortunate side-effect of making the content unscrollable
(and thus all but the first screen invisible).

The only thing I can find that differentiates these two divs from the others is
that all of their content is <img> elements. Experiments with changing the
z-index on these divs have prooved fruitless.
Oops; forgot to mention the build#: 2002091808 on Win/XP
Can you tell me what you expect to see here? Making BODY overflow:auto means
that any contents which fall outside the body will have to be scrolled to. That
INCLUDES position:fixed children of the BODY. But of course no amount of
scrolling will bring position:fixed children into view, because they're fixed.
So it's not at all clear what should happen in a case like this.
I guess the fundamental issue is this: setting 'overflow' on the BODY affects
the visibility of all of BODY's children, even if they're 'position:fixed'.
The bug I see is the inconsistency--two of the divs (the navigation bar and the
bibliography) remain visible and fixed, exactly the behavior I expected. But the
other two disappear, for no reason I can discern.

"...will have to be scrolled to. That INCLUDES position:fixed children of the BODY."

When I first made this change, I was afraid of that being the case, as it would
invalidate my concept. But reading the CSS spec again, it says that
position:fixed is relative to the viewport, not the body. The only admonition
against positioning containers is that the _root_ element ignores position and
float, but the root element is HTML, not BODY. So I see nothing that says this
shouldn't work.

In setting body to position:fixed instead of :absoloute, I'm trying to overcome
the problem of page up/down scrolling not matching the actual height of the
visible content because of that hidden by the top div, while retaining the
linkage of the keyboard navigation to the main content area (which doesn't
happen, and is marked as a separate bug), and avoiding any other side-effects
that might occur.
the fixed position of the body is irrelevant, except that by positioning the
body you've made it not cover the entire canvas, which is fine.

The fact is that fixed children of an overflow:auto element (in this case, the
body) which do not intersect their parent will never be visible.

We seem not to be doing this consistently, but that's the way it should work IMHO.
Robert, can you cite anything in the css2 spec to back up your opinion? I just
looked again (under sections 9 & 11), and can't find anything to back up your
statement. 

All I can see is that absolutely positioned elements are relative to their
containing block (in the case of body, this would be the HTML element), and that
fixed positioned elements are relative to the viewport, not HTML or BODY.

Since there seems to be no way to set the default focus to a specific div,
setting the position of the body to fixed seems to be the logical method of
positioning the main content window so that it avoids other fixed position elements.
http://www.w3.org/TR/CSS21/visufx.html#overflow

> This property specifies whether the content of a block-level element is
> clipped when it overflows the element's box (which is acting as a containing
> block for the content).
...
> auto
> The behavior of the 'auto' value is user agent-dependent, but should cause a
> scrolling mechanism to be provided for overflowing boxes.

OK, now we have a block-level element (the BODY) containing a child element (a
DIV). In this case the BODY block is NOT the containing block for the DIV (since
the DIV is fixed, its containing block is the viewport) but as far as I can tell
this parenthetical remark in the spec is in error. (Ian and David may wish to
comment here.) There is no other indication anywhere else that the 'overflow'
property should apply only to those children for which the element is the
containing block.

Anyway, assuming you accept that, we have a DIV which lies outside the bounds of
the BODY element. 'overflow:auto' says we should clip to the bounds of the BODY
element, but provide a scrolling mechanism on BODY to allow the DIV to be
scrolled into view. This is an odd situation because there is no way to provide
a scrolling mechanism in BODY that will bring the DIV into view. So we basically
give up on that part of the request but we honor the first part, which is to
clip the contents of BODY to the BODY element's box.
Members only. Can you summarize for us?
Yeah, I know.  So far it's a thread with only one message, and that's a message
I wrote a few hours ago asking roughly the questions that you were asking above.
If it is decided that 'overflow' should only apply to descendants for which the
element is the containing block, then you should also do a careful analysis of
related properties to see if they should be changed the same way. 'z-index' and
'clip' spring to mind. I suggest it would be better if we keep it simple and
apply 'overflow' to all children.
ah, dbaron is way ahead of me :-)
I now have a test-case where the disappearing divs lie within the bounds of <body>:

http://www.cadenceweb.com:8080/newsletter/sheerin/webstandards/NewDesign.html

Robert,
Can you find anything wrong with my coding in this version that would explain
the behavior, or does this make you think it is a bug?
That's not a testcase, that's a web page! Do you have a less-than-1kb example?
Sorry Ian! I should have simplified that testcase before posting it. I stripped
as much as I could out of it without changing the essence, embedding the style
sheet and taking out all but the barest content. It's now 3K (instead of 10K +
8K of css), but shows the same behavior.
This bug would seem to stem from the incorrect application of overflow in the
case of any absolutely positioned element inside a non-positioned element.
Mozilla (and IE5.5, which displays the bug in general, but not the BODY variant
generally quoted) consideres absolutely positioned div elements to be overflow
of a non-positioned parent div if the absolutely positioned div falls outside
the containing box of the parent div. This is in clear violation of the spec:

Quote: "If we position "div1":

#div1 { position: absolute; left: 50px; top: 50px }

its containing block is no longer "body"; it becomes the initial containing
block (since there are no other positioned ancestor boxes)."

( source: http://www.w3.org/TR/CSS21/visudet.html#containing-block-details )

An extremely simple example of this is:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>

<head>
<title>Test</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
</head>

<body>

<div style="width: 10px; height: 10px; overflow: hidden;">
  <div style="position: absolute; top: 200px; left: 20px;">
  This text should be visible.
  </div>
</div>

</body>

</html>

Sincerely,

Krister
Addendum:

The bug, as I described it above, was *not* present in Moz1.1 and is no longer
present in the latest nightly build. I reinstalled 1.2beta (build 2002101612)
and confirmed that the bug *is* present there, as described in my previous comment.

However, when applying the 'overflow:hidden' to the BODY element, the bug is
still present. The simple test case thus becomes:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>

<head>
<title>Test</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
</head>

<body style="overflow: hidden;">

  <div style="position: absolute; top: 200px; left: 20px;">
  This text should be visible.
  </div>

</body>

</html>

Sincerely,

Krister
I think we should revert our handling of overflow:hidden to only clip content
for which the current element is the containing block. Even though it's not what
WinIE does for non-BODY elements, I do think that ultimately overflow should
only apply to content for which the current element is a containing block
ancestor (consider 'overflow:scroll', which simply doesn't make sense for
overflowing content for which the current element is not a containing block
ancestor). We definitely don't want behavior in 1.2 that's different from 1.1
and ultimately different from 1.3, if the WG decides to endorse my opinion. So
let's just put it back to 1.1's behavior. I will attach a patch.
Assignee: attinasi → roc+moz
Status: UNCONFIRMED → NEW
Ever confirmed: true
Attached patch The fixSplinter Review
Here we go. This just disables the code that walks the content parent chain if
its different from the containing block chain. It reverts us to old behavior.
This should be very safe.
Attachment #105272 - Flags: review+
Comment on attachment 105272 [details] [diff] [review]
The fix

r=bzbarsky
Comment on attachment 105272 [details] [diff] [review]
The fix

a=asa for checkin to the 1.2 branch (on behalf of drivers)
Attachment #105272 - Flags: approval+
Checked in.
Status: NEW → RESOLVED
Closed: 22 years ago
Resolution: --- → FIXED
This was also checked into the 1.2 branch.
I'm reopening this bug since there's still some uncertainty about what the WG
wants for this case.
Blocks: 183495
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
*** Bug 170040 has been marked as a duplicate of this bug. ***
.
Status: REOPENED → NEW
Component: Layout → Layout: View Rendering
OS: Windows XP → All
QA Contact: cpetersen0953 → ian
Hardware: PC → All
Bug 212538 looks like it's essentially a duplicate of this one, albeit with
position:absolute.
Blocks: 212538
Depends on: 225811
Has the WG made up its mind here yet?
2.1 says "This property specifies whether content of a block-level element is 
clipped when it overflows the element's box. It affects the clipping of all of 
the element's content except any descendant elements (and their respective 
content and descendants) whose containing block is the viewport or an ancestor 
of the element." and "HTML UAs may apply the overflow property from the BODY or 
HTML elements to the viewport.", is that what you mean?
This looks like it was fixed by bug 225811.... Is anyone still seeing this?
I can't connect to cadenceweb for the testcase and I believe that this has been
fixed by various checkins ... at least, I know a lot of code involved here has
been changed, hopefully for the better :-)
Status: NEW → RESOLVED
Closed: 22 years ago20 years ago
Resolution: --- → WORKSFORME
Component: Layout: View Rendering → Layout: Web Painting
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: