Re: Proposal for CSS 2.1 issue 153

On 23 Jun, 2010, L. David Baron <dbaron@dbaron.org> wrote:

> http://wiki.csswg.org/spec/css2.1#issue-153 reports that some of the
> definitions of "box" in the section on vertical alignment are
> ambiguous.  This was much clearer in CSS 2.0 before section 10.6.1
> was revised; the revisions made to 10.6.1 since then have made it
> ambiguous.
>
> The proposal previously in the issues list (from Elika, I think)
> was to add:
>   # In the following definitions, for replaced, inline-block, and
>   # inline-table elements, the box used for alignment is the margin
>   # box. For inline non-replaced elements, the box used for
>   # alignment is undefined.
>
> I would propose that instead, we add:
>   # In the following definitions, for inline non-replaced elements,
>   # the box used for alignment is the box whose height is the
>   # 'line-height' (containing the box's content area and the
>   # half-leading on each side).  For all other elements, the box used
>   # for alignment is the margin box.

After we made the half-leading unambiguous (issue 118[1]), it is clear 
that an inline box has a height of 'line-height' *or more* (viz., in 
certain cases where the inline box contains glyphs from fonts with 
different metrics, or when it contains other inline boxes from child 
elements). Nowhere do we have a box defined that is 
always 'line-height' high.

Thus, in David's proposed text above, "the box whose height is 
the 'line-height'" isn't a well-defined concept.

We do have a well-defined term "inline box" now. (Issue 120[2] added 
that to section 9.2.2, while issue 118 defined its height in section 
10.8.1). Unfortunately, that is not the box that 'vertical-align' acts 
on. E.g., the vertical position of "abc" in

    ... <span style="vertical-align: middle">abc<sup>2</sup></span>...
and
    ... <span style="vertical-align: middle">abc</span>...

should be the same, despite the fact that the first SPAN has a taller 
inline box than the second.

I can see two approaches: we can define a special kind of box just for 
the purposes of 'vertical-align', a box whose height does not depend on 
child elements; or we can change 9.2.2 and 10.8.1 so that "inline box" 
itself is defined as such a box.

In the original model for CSS (which was never very explicit), mark-up 
such as <EM>abc<STRONG>def</STRONG>ghi</EM> created three inline boxes, 
not one box with another one inside. The definition of 'vertical-align' 
was written with those boxes in mind.

If we take that approach, then David's proposed text to add 
to 'vertical-align' becomes:

  | In the following definitions, for inline non-replaced elements,
  | the box used for alignment is the inline box (containing the
  | box's content and the half-leading). For all other elements, the
  | box used for alignment is the margin box.

The definition of inline box in 9.2.2 (cf. issue 120[2]) could be 
rewritten as:

  | A non-replaced element with a 'display' value of 'inline'
  | generates one or more <dfn>inline boxes</dfn>. An element with
  | a 'display' value of 'run-in' can also generate inline boxes; see
  | _run-in boxes_. Inline boxes contain all text of the element that is
  | not in a child element. If the element has neither text nor child
  | elements, it generates one inline box containing a strut[ref to
  | 10.8.1]. 
  |
  | Example: <span>abc<em>def</em></span> generates two inline boxes,
  | one containing "abc", the other "def".
  |
  | Inline-level boxes that are not inline boxes (such as
  | replaced inline-level elements, inline-block elements, and
  | inline-table elements) are called <dfn>atomic inline-level
  | boxes</dfn> because they participate in their inline formatting
  | context as a single opaque box.

(This avoids to say how many inline boxes are generated exactly, because 
that is difficult, as it depends on line breaking, hyphenation and 
bidi-reordering...)

The definition of leading in 10.8.1, which defines the height of the 
inline box, could be modified as follows:

  | User agent must align the glyphs in a non-replaced inline box to
  | each other by their relevant baselines<del>, and to nested inline
  | boxes according to 'vertical-align'</del>.
  | ...
  | The height of the inline box is then the smallest such that it
  | encloses all glyphs and their leading<del>, as well as all nested
  | inline boxes</del>.

I think that defines 'vertical-align' correctly and doesn't harm the 
other places where "inline box" is used (some of which, such as 9.2.2.1 
and 9.4.2 in fact still use this model), except for two:

Section 10.1 says: "In the case that the ancestor is an inline box, the 
containing block depends on the 'direction' property of the ancestor 
[...]". But an inline box doesn't have children. Earlier text said: "In 
the case that the ancestor is inline-level, [...]" and what is actually 
meant is an ancestor that is 'inline' or 'run-in'.

Section 9.2.1.1 says:

  # When an inline box contains an in-flow block-level box, the inline
  # box (and its inline ancestors within the same line box) are broken
  # around the block-level box.

It should say:

  | When an inline element contains an in-flow block-level element, the
  | inline element (and its inline ancestors within the same line box)
  | are broken around the block-level box.


[1] http://wiki.csswg.org/spec/css2.1#issue-118
[2] http://wiki.csswg.org/spec/css2.1#issue-120



Bert
-- 
  Bert Bos                                ( W 3 C ) http://www.w3.org/
  http://www.w3.org/people/bos                               W3C/ERCIM
  bert@w3.org                             2004 Rt des Lucioles / BP 93
  +33 (0)4 92 38 76 92            06902 Sophia Antipolis Cedex, France

Received on Wednesday, 6 October 2010 17:14:04 UTC