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 08:13:34 -0800
Message-Id: <D9987769-D006-4CC6-8AC7-BF3BE71E04B0@comcast.net>
Cc: 'CSS Style' <www-style@w3.org>
To: Ben Cotterell <ben.cotterell@antplc.com>


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:
>>> Suppose I have something like this:
>>>
>>>    <div style="width: 200px; overflow: scroll">
>>>        <div style="width: 400px"></div>
>>>        <div style="width: auto" id="foo"></div>
>>>    </div>
>>>
>>> How wide should div#foo be? Does the preceding div cause the  
>>> container
>>> to grow to 400px, making #foo's used width 400px?
>>>
>>> You can get that effect already by wrapping the contents in a
>>> shrink-to-fit container (as I think you said).
>>
>> Bruno Fassino said that, and L. David Baron said it wouldn't work (it
>> does seem to if I used padding on the wrapper, though, instead of
>> margin).
>
> I thought he was saying it wouldn't work for the same reasons I am--
> that in the example above, the used width of div#foo would be  
> 400px, not
> what the author wanted. But I may have misunderstood.

No, it was me. I know what I want, but I've had a tough time  
following the reasoning of why its not possible.

> He said, "it actually wouldn't produce the results desired, since it
> would make all the other widths that are relative to the containing
> block relative to its largest overflowing content instead."
>
> [...]
>>> If the specification were changed to make overflow: scroll  
>>> containers'
>>> contents implicitly always wrapped in shrink-to-fit containers,
>>
>> Well, grow-to-fit, if that makes any difference.
>
> Same thing really-- shrink-to-fit also grows-to-fit.
>
>> It is already sized  to the minimum needed width (excluding the
>> trailing margin, that is),  if you consider non-wrapping, auto-width
>> contents.
>
> No. The "extent box" is grown to include the contents, but the
> containing block width (or "available width") for the contents is  
> still
> what it was before.

OK, I suppose it it the extent box that I am mostly concerned with.  
With near infinite width available to it, I would like to see it  
large enough to include the margin I specified. I do not want to  
change the used width of the containing block and its scrollbars,  
just the width in practice of the scrollable area within it.

[...]

>>> In this case she could set width on #foo to 200px but of course in
>>> other
>>> cases the container itself will be width: auto, and so the exact  
>>> value
>>> to set #foo's width to wouldn't be known.
>>
>> Perhaps I am not understanding you correctly. Doesn't the UA have to
>> determine the width of something with width set to auto? Doesn't it
>> use that in order to determine how wide to make the scroll pane
>> within the scroll box (i.e., to determine how far the user can scroll
>> right and left)?
>
> Yes, but that's the width of the scroll pane (or what I call the  
> "extent
> box"), _not_ the width of the block itself.
>
> The width of the scroll pane has no effect at all on layout, or on the
> used widths of any box in the tree. It's just a way of visually  
> handling
> overflow.

I'm pretty sure I understand what you mean now. What I'd like to see  
then is a definition of the width and height of the "scroll pane" /  
"extent box", to fully include all the margins of the descendants and  
the padding of the container. If this is beyond the scope of what CSS  
is supposed to define, then I'd like the implementors agree to do the  
right thing and make their extent boxes big enough to contain the  
margins.

Because at the end of the day, I really just want to see the margin I  
specified, whether it fits without being over-constrained, or it is  
in a separate extent box that has no width/height constraints (where  
scrolling mechanisms allow one to see as much as they like regardless  
of container width).

[...]

>>> But how often do people want to continue scrolling to the side  
>>> just to
>>> see a margin?
>>
>> You might as well ask why have margins at all? In this case, it is
>> often easier to scroll all the way to the right than to scroll a few
>> pixels from all the way to the right. The margin aids in readability
>> when content is not all pressed together. The same problems happen
>> when padding is used on the container, by the way.
>
> 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.


>
> [...]
>> If the author wants to have margin inside the scroll box, why honor
>> that for the left, but not the right?
>
> Because the left margin defines the position of the child element
> relative to its parent.

... and the right margin defines how far away the author would like  
the right edge of his content away from other edges (such as a window  
edge, or the edge of some other scrollable viewport).

Think about the viewport of a browser. It may only be 600px tall, but  
I can put a 10,000px tall box inside it, and when you scroll down to  
the bottom, the margin I specified for that box will still keep it  
from touching the edge of the viewport by the specified distance. So  
I naturally think that I should be able to do the same in other boxes  
that scroll, just as I do in my viewport that scrolls.

<body style="padding:0; border:1px solid purple;">
	<div style="height:200em; width:10px; border:1px solid red; margin: 
40px;"></div>
	<div style="padding:0; border:1px solid pink; height:10em;  
overflow:auto; ">
		<div style="height:20em; width:10px; border:1px solid red; margin: 
40px;"></div>
	</div>
</body>


> If the scroll pane (or "extent box") is the bounding box of the
> overflowed box's padding edge and descendent contents (whether those
> include margins or not being debatable),

I think they should. If the spec says not, then I say change the  
spec. There may be reasons that it is the way it is, but as a  
designer, I find it counter-intuitive that one is missing, especially  
when the other three are present. It seems especially strange within  
a "CENTER" construct, where all the blocks are centered, and FireFox  
and Opera have the margin in the left of the extent box, but not the  
right, and the object are therefore not centered in that box.

If I'm moving, and I have a TV that is 3 feet wide, and I put 6" of  
styrofoam around it for packing (so that there is a MARGIN of safety  
between the TV and the packing box), and I can choose any box size I  
want for it, I'm going to want to put it in a cardboard box that is 4  
feet wide (not 3 1/2), so it can contain the TV and the styrofoam.  
Even if I am constrained to look at the packing box through a window  
that only lets me see 2 feet of it at a time.

> then the left margin is already
> within the parent box's padding edge, so it's guaranteed to be  
> included.
>
> [...]
>
> Note: there are two issues here. One is whether the scroll pane should
> include margins. As far as I can see the spec isn't all that clear on
> whether this is necessary or not.

Then lets make it clear, and say "yes" to this at least, in the spec.

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


> I don't see how this second issue can be solved so easily. Some
> descendents will want to work to the real containing width, others to
> the "grow-to-fit" width. The only way for the author to say which
> descendents should get which treatment at the moment is by adding  
> extra
> elements. I don't see any great harm in that.

The harm is in the non-obviousness of it (I don't suppose I am the  
only designer to be too obtuse to clearly see why a margin disappears  
once it is inside a scroll box), and (as L. David Baron pointed out)  
its effect on the used width of other objects in the box that do fit  
within the original dimensions using automatic width.

>
> [...]
>>> Better for authors to create extra shrink-to-fit wrappers where they
>>> need them to say what they want.
>>
>> Seriously? Create extra structures in the HTML in order to achieve
>> the styling that is already reasonably specified in the CSS?
>
> 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.

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. Since that runs  
contrary to how the designer set up the margins (i.e., so that they  
would be a certain distance from other edges), I would prefer that  
the extent box be large enough to show those margins.

>
> It could be done, but it would be quite confusing I think. You could
> have a new kind of width: auto which meant "use container's  
> hypothetical
> shrink-to-fit width as containing width", which you could set on #foo
> but not on #bar.

I don't see how that would be necessary. Maybe I am missing  
something, but (I believe) I am really only talking about the size of  
the extent box. If some of my wording confused the issue, then I  
apologize.

>> There  are so many reasons why this is not a reasonable solution, not
>> to  mention going against a central philosophy of CSS.
>
> Well, I don't want to get into the philosophy too much, but the  
> reality
> is that not all layouts are possible without adding an extra div here
> and there. Although slightly impure that's probably worth it  
> because it
> makes for an overall simpler solution-- and this issue is an  
> example of
> that.

True enough to the first part, but I find the explanations for the  
mysterious missing margin to be anything but simple.

>
> Sometimes the behaviour is easier to understand if you have a couple
> more boxes and simpler behaviour per box than more and more properties
> to fine-tune the behaviour of the bare minimum number of boxes.
>
Received on Monday, 4 February 2008 16:13:53 GMT

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