W3C home > Mailing lists > Public > www-style@w3.org > February 2008

Re: Overflow and Margins

From: Brad Kemper <brkemper@comcast.net>
Date: Mon, 4 Feb 2008 10:00:17 -0800
Message-Id: <F9135E06-C2D8-47B4-97DA-F851357BFF05@comcast.net>
Cc: 'CSS Style' <www-style@w3.org>
To: Ben Cotterell <ben.cotterell@antplc.com>

On Feb 4, 2008, at 8:48 AM, Ben Cotterell wrote:

>
> On Mon, Feb 04, 2008 at 08:13:34AM -0800, Brad Kemper wrote:
>>
>> On Feb 3, 2008, at 1:59 PM, Ben Cotterell wrote:
>>
>>> On Sun, Feb 03, 2008 at 12:58:51PM -0800, Brad Kemper wrote:
>>>> On Feb 3, 2008, at 2:06 AM, Ben Cotterell wrote:
> [...]
>>> You should see the padding.
>>>
>>> If I do this:
>>>
>>>    <div style="overflow: scroll; width: 200px; padding: 50px">
>>>        <div style="width: 600px; border: 2px solid green">
>>>        </div>
>>>    </div>
>>>
>>> I can scroll to the right and keep scrolling and see the 50px gap.
>>> Works
>>> in Firefox and Opera.
>>
>> I do not see the gap in Webkit nightly (Version 3.0.4 (523.12.2)),
>> nor in FireFox 3.0b2. I do see it in Opera 9.25, but it actually
>> looks too wide there.
>
> See my later correction. I believe you should *not* see any right
> padding! I tested on Opera 9.25 and Firefox 2.something. Looks like
> they've fixed this in 3. See also Alan Gresley's tests.
>
> The padding is at the right of the 200px bit you can see.
>
> [...]
>>> But that's easily settled one way or the other.
>>>
>>> The second issue, much more tricky, is that even if the scroll pane
>>> does include margins, sometimes one of those margins is overridden
>>> and becomes negative to satisfy fitting a block into a much narrower
>>> containing width.
>>
>> I'm not sure what you mean. I tried something like this, in which the
>> innermost object was in an over-constrained box, and the extent box
>> for the outer container still contained it (but not its right  
>> margin).
>>
>> <div style="width:400px; overflow:auto">
>> 	<div style="width:800px; margin:50px;">
>> 		<div style="1000px;"></div>
>> 	</div>
>> </div>
>>
>> Even in this case, I would prefer to see room for the margin in the
>> extent box, as though that were a separate viewport. Even if the
>> current rules don't allow it, I think most designers would expect to
>> see their specified margins and not understand why they are not
>> there. Even with all of your patient explanation, I am still having a
>> difficult time fully grasping why they are not all shown, although I
>> understand it has something to do with the interpretation of the
>> rules for over-constrained blocks.
>
> The difficulty here is what is the used value of the block's
> right margin? (This is the 800px wide box I'm talking about).
>
> The width available to it is 400px. Its own width is 800px. So it ends
> up with a used right margin of -450px, not of 50px.

By my figuring the used right margin would be -400px (the 50px is  
ignored, and refigured to allow its used width to be equal to its  
parent), but maybe I am missing something.

But the purpose of that huge negative margin is so that it will not  
impact items outside of the scrollbox. There is no practical reason  
why that negative margin should similarly impact the size of the  
extent box. And, it seems to me, it does not impact the size of the  
extent box. If it did, the extent box would only be 400px wide. In  
reality, in my testing, the extent box if big enough to fit even the  
1000px object.

Since the contents of the extent box are all self contained, the  
original value of the margin should be used in determining its size.

>
> Now when the browser comes to compute the extent box for scrolling the
> outermost div, it's got a -450px gap to work with at the right, not a
> 50px one. It's not obvious how to re-specify this to get the desired
> 50px margin. 10.3.* is all based firmly on the idea that you are  
> working
> to some containing width that you know in advance.

I would specify it as:

If all of the above have a computed value other than 'auto', the  
values are said to be "over-constrained" and one of the used values  
will have to be different from its computed value. If the 'direction'  
property of the containing block has the value 'ltr', the specified  
value of 'margin-right' is ignored and the value is calculated so as  
to make the equality true. If the value of 'direction' is 'rtl', this  
happens to 'margin-left' instead.

For the purposes of determining the width of the extent planes within  
a scrolling box, the equality restriction no longer applies, as the  
extent box has no restrictions on its width. In this case, the  
original value of the margin applies within (and only within) that  
extent box.

or something like that.

>
> If the 800px div were put inside a shrink-to-fit container, all  
> would be
> well (if it was also required that margins were included in extent
> boxes), because then it would still have a 50px right margin.
>
> [...]
>>> But how would you specify it? Take my example above:
>>>
>>>    <div style="width: 200px; overflow: scroll">
>>>        <div style="width: 400px;"></div>
>>>        <div style="width: auto" id="foo"></div>
>>>        <div style="width: auto" id="bar"></div>
>>>    </div>
>>>
>>> Now for the sake of argument, the author wants the containing width
>>> for
>>> #foo to be 400px, but for #bar to be the original containing  
>>> width (of
>>> 200px).
>>>
>>> Today, he could do this:
>>>
>>>    <div style="width: 200px; overflow: scroll">
>>>        <div style="float: left">
>>>            <div style="width: 400px;"></div>
>>>            <div style="width: auto" id="foo"></div>
>>>        </div>
>>>        <div style="width: auto" id="bar"></div>
>>>    </div>
>>>
>>> What extra properties would you need and what would they look  
>>> like to
>>> specify this in CSS without using the extra wrapper div?
>>
>> I tried to render that in a browser, and couldn't get it to work.
>> Without the float it seems to do what you are talking about though.
>
> You need to make #bar clear: left (I should have done that), and if  
> you
> give all the divs some borders and height you can see where they all
> are.
>
> The point is, foo is fitted to a 400px width. If it had a 50px right
> margin, and if browsers put extent boxes around margins, you would see
> that margin when you scrolled right.
>
> But if it were outside the float, where #bar is, its used right margin
> would be negative, and you still wouldn't see it when you scrolled
> right.

Negative for the purpose of the page outside of the scrollbox. It  
doesn't need to be that negative value in order to figure the width  
of the extent plane. For that you can use the value of the margin  
before it was changed to a negative value.

>
>> I would not propose that any of that change, but only that the extent
>> box be large enough to contain all the margins.
>>
>> In theory, since the extent box is part of a UA-specific scrolling
>> mechanism, it could be infinitely wide and infinitely high, with
>> scroll arrows but no scroll button (and the terms "scroll all the way
>> down" and "scroll all the way to the right" would have no meaning).
>> In practice, there usually is a limit to how far to the right or how
>> far down a person can scroll, and that limit is enough to contain the
>> final border edges but not the final margins.
>
> The problem is you need a width to work to in order to work out what
> those final margins are.

Yes. And that can be the width as it was immediately before the  
reduction that occurred due to the over-constraining rule.

>
> That width is currently the containing width, which often results in
> negative used right margins.
>
> One way of achieving the desired result is to make that width instead
> the shrink-to-fit width of the container. Currently that can be done
> with an extra wrapper (float, table-cell, inline-block could all be
> used), which I think is still a reasonably simple and desirable  
> solution
> all things considered.
>
Received on Monday, 4 February 2008 18:00:37 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Monday, 27 April 2009 13:55:01 GMT