Re: block box inside inline box ?

[Fri, 14 Jun 2002 13:19:47 -0700] Etan Wexler:
>CSS has no tree transformation capabilities, so naturally my example, taken literally, 
>has no basis in CSS specifications.  I agree that it is wrong in a sense, but I argue that it 
>is a useful lie in that it helps to visualize the box layout.  I was demonstrating the 
>creation of boxes, not the workings of inheritance or contextual selection.  If the example 
>is wrong about the boxes created (and please tell us if so), then it is badly wrong.

My problem was that it seemed to me the method of constructing boxes
pre-supposed a conclusion it purported to derive.  I can't point to any
section of the standard that says your method is *wrong*... but I don't see
any that says it's *right*, either.  Your reconstruction is not neutral: it
implies additional (unstated) rules which no one so far has shown to be
present in the standard.

As I'll explain in detail below, after further consideration I now think
your resolution is closer than mine to what must have been intended, though
I don't really like either result. [1]  What I believe led me astray is
that I tried to use HTML (being more familiar with that than X[HT]ML) and
came across the OBJECT element as a test case --- I now think that element
is simply mis-specified in the CSS2 sample style sheet for HTML 4.01.


>> The problem, it seems, is that [...]
>> there appears to be no corresponding section that explains what happens
>> when an inline element contains a block box --- though as far as I can
>> tell, that is not explicitly forbidden, either.
>
>Some people have been explicit that blocks within inlines are allowed.  Nobody has 
>countered that.  A note of permission in the specifications sure would help, though.

It's not just the problem of permission: it's that nothing clearly explains
what happens.  [2]

I would *guess* that --- since CSS tries not to presuppose more than
necessary about the document languages to which it might be apply --- it is
probably intentional that this isn't forbidden.

Suppose, for example, that some document language allowed you to create a
list of pictures with centered captions, like this:

     +----------+     +----------+     +----------+
     |          |     |          |     |          |
     +----------+     +----------+     +----------+
      John Bates      Marie Cordon        George
                                          Dorian

     +----------+     +----------+
     |          |     |          |
     +----------+     +----------+
      Rick Elias       Lisa Fodor     

in which the pictures are stacked across until the containing block runs
out of space, then a new line is started.  Somewhere in the actual
construction, the captions must be enclosed in a block element (in order
that "text-align: center" can apply); yet the boxes that enclose the
picture/caption combinations are being placed side-to-side in what is
essentially an inline formatting context.  If this type of layout is to be
possible in a language that can be styled with CSS, then block elements
within inline elements cannot be forbidden. [3]


>> Intuitively, I would expect this:
>> 
>> 1. The <block> content must be formatted as a block.  In the absence of a
>> "width" property or (for a replaced element) an intrinsic width, it would
>> fill the width of containing block (which I presume would be the width of
>> the content area of the <#anonymous-block>).
>
>I would simply say that the containing block for the block box is identical to the 
>containing block for its inline-level parent.
>
>> 2. This rectangular <block> element would be placed within a line box in
>> the same way as any other indivisible element (like a word or an IMG).
>
>This is a useful model.  The line box containing the block box extends from the margin 
>before edge to the margin after edge, regardless of line stacking strategy, right?

Having given this some more thought, I now think my previous model has
serious problems of its own.  For example, given the rule:
     OBJECT {display: block}
which the "sample style sheet for HTML 4.0" given here:
     http://www.w3.org/TR/REC-CSS2/sample.html
includes), under my assumption these two examples:

     <P>
      Some text
     <OBJECT...></OBJECT>
     and more text.
     </P>

     <P><SPAN>
      Some text
     <OBJECT...></OBJECT>
     and more text.
     </SPAN></P>

would be rendered differently (since the standard requires that anonymous
block boxes be created for the text in the first example).  That would be
bizarre.


I think the *immediate* problem with this is that the sample style sheet is
in error; HTML 4.01 defines OBJECT as an *inline* element, and it probably
should be considered that way in CSS2 also.

(However, what happens when the OBJECT cannot be presented, so that the
content is rendered instead, remains unclear to me.  Does the OBJECT drop
out of the document tree entirely?  IE 6 acts as if it does.  Does the
OBJECT lose any formatting effect --- background-color, borders, etc. ---
but still convey inheritable properties to its children?  Opera 6 seems to
think so.  Should the content of the OBJECT be valid in the context in
which it would appear were the OBJECT tags removed?  Neither the HTML 4.01
standard nor http://validator.w3.org/ calls:
     <EM>
        text
        <OBJECT ...>
           <DIV>text</DIV>
        </OBJECT>
        text
     </EM>
invalid... but neither does the standard explain what it *means*.)


I believe there's a bigger problem hiding behind the OBJECT case.  One
could simply accept that the HTML OBJECT element is peculiar --- certainly
elements of a document language can have presentational characteristics
that cannot be represented in CSS2, and OBJECT is somewhat odd in being an
inline HTML element that permits block content.  But the "inline list of
pictures" illustration I gave above suggests to me that the problem is not
really so unique: CSS2 lacks any clear presentation of a direct way (if
there is one) to generate blocks including non-replaced content that should
"hang together" in a rectangle --- and be subject to all the standard
"block" considerations, like independent text-alignment, width, etc. ---
but are placed side-to-side with inline formatting logic.

The same problem with the <P><OBJECT> / <P><SPAN><OBJECT> example would
apply (in other document languages) to any block element that could be
included in an inline element, were my original solution adopted: that
seems to me completely unnatural, so I have to reject my own earlier
solution.  Etan's original interpretation is at least consistent (though
difficult to describe clearly in "anonymous box" terms [4]); but it seems
to restrict the range of possible formatting behavior undesirably.  The
standard itself appears to leave everything up for grabs.




[1] I *think* what's at the root of why I don't like either result is that
the "block/inline" distinction is doing two jobs with one property: 
     1. determining whether to form a "block";
     2. determining whether to participate in inline formatting.
For individual, replaced items, like an <IMG> element standing alone, this
presents no problem.  However, it seems to me there are times when one
would want to fashion a "block" out of text and/or multiple replaced
elements, yet have that "block" be placed according to some form of
"inline" formatting.  Floats, tables and various other mechanisms capture
*some* properties of inline formatting (along with additional, unique
characteristics) and apply them to block content; but they don't let blocks
be directly absorbed into true, ordinary inline formatting.  Etan's
solution rules out doing so at all; my earlier solution produces anomalies
that are unacceptably confusing.

At this time I don't have a suggestion that solves all the problems raised.


[2] I've realized that it could be argued that this section:
     http://www.w3.org/TR/REC-CSS2/visuren.html#anonymous-block-level
(which I noted before) *does* specify what happens.  It states:
     [I]f a block box [...] has another block box inside it [...],
     then we force it to have only block boxes inside it, by wrapping
     any inline boxes in an anonymous block box.
but, though no example shows this, it doesn't say the contained block box
must be *immediately* inside the containing block box.  Under this
interpretation, the example Etan gave would be essentially correct, and
there would be no way to avoid the creation of anonymous block boxes that
overlap, rather than nest among, some inline boxes.  Having elements (even
anonymous, "fictional" ones) that don't nest seemed so contrary to the rest
of the model I presumed this couldn't be intended; but perhaps it was.

I'll have to think further about what happens to the statement:
     The properties of anonymous boxes are inherited from the enclosing
     non-anonymous box
when the anonymous box begins inside one non-anonymous box and ends inside
another (or, alternatively, one restructures the document tree to avoid
that, as per Etan's example).  Perhaps in practice there are no applicable
properties that could lead to confusion.


[3] As I was finishing this message, I realized the *effect* I described
can be achieved with CSS2 using floats... except that it would be difficult
to get space between horizontally adjacent items while still allowing the
outer edges of the first and last items in each row to be flush with the
containing block: one would have to create a "fake" containing block to
absorb the excess margins.  If the problem were to have each line of
pictures *centered*, it couldn't be solved with floats at all.  In any
case, using floats would be a contrivance: were the behavior intrinsic to
some set of elements in a document language, it is unlikely that it could
be represented successfully with a user agent default style sheet.


[4] I would suggest that a better way to describe the same result would be
to say that when a block element (in normal flow) appears within an inline
element, its containing block is formed by the content edge of the nearest
block-level ancestor box (the standard:
     http://www.w3.org/TR/REC-CSS2/visudet.html#containing-block-details
requires that); its left outer edge coincides with the left edge of the
containing block (for left-to-right formatting; this matches the definition
in this section:
     http://www.w3.org/TR/REC-CSS2/visuren.html#block-formatting
for boxes in a block formatting context); and the top outer edge is placed
against the bottom of the last block box or line box generated by a
previous element in normal flow.  This avoids the need to either
restructure the document tree or create anonymous boxes that don't nest.
-- 
Randall Joseph Fellmy aka Randy@Coises.com

Received on Sunday, 16 June 2002 20:40:10 UTC