Re: Overflow and Margins

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.

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.

In the example above, the available width for div#foo is 200px, even
though the container can be scrolled over a 400px wide area.

If I put a shrink-to-fit container in:

    <div style="width: 200px; overflow: scroll">
        <div style="float: left">
            <div style="width: 400px"></div>
            <div style="width: auto" id="foo"></div>
        </div>
    </div>

The available width for div#foo is now 400px, and it will end up with a
used width of 400px.

> >think is what you're effectively suggesting, that would take away
> >flexibility.
> >
> >Take the example above. #foo might contain only a couple of words and
> >have text-align: center set on it. The author would probably prefer to
> >have that text centered within the visible 200px of the container than
> >have to scroll right to see half of it.
> 
> I wouldn't design it like that, but I can think of other reasons for  
> having some blocks narrower than others within the overflowed block,  
> and I assume your example is not tied to the behavior of centered text.

Of course not, it was just the first example that came into my head, not
a design recommendation for anyone's website!

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

> If I have non-breaking auto-width content that is  wider than the
> 200px, then its width (plus its padding, border, and  all margin other
> than right margin, apparently) is used to determine  the size of the
> scroll pane. If it is smaller than 200px, then the  corresponding
> properties of the 200px element are used.

Correct.

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

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

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

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

[...]
> >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?

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.

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

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 Sunday, 3 February 2008 21:59:50 UTC