Re: [CSS21] display:run-in clarifications

On Thursday 27 August 2009, Boris Zbarsky wrote:
> Bert Bos wrote:
> > A run-in element A behaves as follows:
> >
> >    1. If A has any children[1] that inhibit run-in behavior (see
> > below), or if it has any :before or :after pseudo-elements[4] that
> > inhibit run-in behavior, then A is rendered as if it had 'display:
> > block'.
> >
> >    2. Let B be the first of A's following siblings[2] that is
> > neither floating nor absolutely positioned[3] nor has 'display:
> > none'. If B exists and has a specified value for 'display' of
> > 'block' or 'list-item', then A is rendered as an 'inline' element
> > at the start of B's principal box[5]. Note: A is rendered before
> > B's ':before' pseudo-element, if any. See 12.1[4].
> >
> >    3. Otherwise, A is rendered as if it had 'display: block'.
>
> Bert, thank you for writing this up and testing the behavior in
> various browsers!
>
> These seem pretty reasonable to me, with two caveats.
>
> 1)  If in rule 2 B and A are expected to be elements, then this case:
>
> CSS:
>
>    #parent::after { display: block; content: "after"; }
>    #parent > div { display: run-in; }
>    #parent { display: block; }
>
> HTML:
>
>    <div><div>Does this run in?</div></div>
>
> won't run the child div into the ::after anonymous element.  Should
> it? If so, it might be worth explicitly calling that out (e.g. by
> saying that B might be an ::after pseudo-element), given that we call
> that out explicitly elsewhere in the algorithm.
>
> 2)  In rule 2, B needs to be non-replaced in addition to the other
> conditions on it.

Good points. B can be a pseudo-element, but so can A, in fact.

(I just wrote a style yesterday with 'div:before {display: 
run-in}' and noticed that Firefox didn't make a run-in, contrary to 
what I was expecting.)

Here is an attempt at a rewrite:

---------------------------------------------------------------------------
A run-in element (or pseudo-element) A behaves as follows:

   1. If A has any children[1] that inhibit run-in behavior (see below),
      then A is rendered as if it had 'display: block'.
  
   2. Let B be the first of A's following siblings[2] that is neither
      floating nor absolutely positioned[3] nor has 'display: none'. If
      B exists and has a specified value for 'display' of 'block'
      or 'list-item' and is not replaced[6], then A is rendered as
      an 'inline' element at the start of B's principal box[5]. Note: A
      is rendered before B's ':before' pseudo-element, if any.
      See 12.1[4].
  
   3. Otherwise, A is rendered as if it had 'display: block'.

In the above, "siblings" and "children" include both normal elements
and :before/:after pseudo-elements.

[6] conform.html#replaced-element
---------------------------------------------------------------------------

(The only pseudo-elements that the 'display' property applies to 
are ':before' and ':after', but that can be inferred already from 
section 5.12.)

>
> > [Definition:] An element or pseudo-element C inhibits run-in
> > behavior if one or more of the following are true. (Note that the
> > definition is recursive.)
> >
> >    a. C is not floating and not absolutely positioned[3] and the
> >       specified value of its 'display' is one of 'block',
> > 'list-item' or 'table'.
> >
> >    b. C is not floating and not absolutely positioned[3] and it has
> > one or more children that inhibit run-in behavior.
> >
> >    c. C is not floating and not absolutely positioned[3] and it has
> >       a :before pseudo element[4] that inhibits run-in behavior.
> >
> >    d. C is not floating and not absolutely positioned[3] and it has
> >       an :after pseudo element[4] that inhibits run-in behavior.
>
> This doesn't seem quite right to me.  In particular, the interaction
> of rules a and b is such that in this situation:
>
>    <div style="display:run-in">
>      <div style="display: table-cell">
>      </div>
>    </div>
>    <div style="display: block"></div>
>
> the run-in will run in, but in this situation:
>
>    <div style="display:run-in">
>      <div style="display: table-cell">
>        <div style="display: block"></div>
>      </div>
>    </div>
>    <div style="display: block"></div>
>
> it won't.  Indeed, the display:table-cell child doesn't inhibit
> run-in behavior on its own, per rule a, but does in the second case
> because of its own block child because of rule b.  Similar issues
> arise if C has display:inline-block or display:inline-table or
> whatnot.
>
> It might be that this is the behavior we want, but an alternative is
> adding "and the specified value of its display is 'inline'" to
> conditions b,c,d above.

My intention was indeed that inline tables and inline blocks are allowed 
inside a run-in element, so we do need your extra condition.

> And possibly that C is non-replaced, for 
> conditions b,c,d; if we have a replaced element which happens to have
> a DOM child (which is what our definition of children is here) that
> has specified "display:block", that should have no effect on the
> parent run-in, I would think.  Personally, I would prever this
> approach.

We haven't defined yet what :before/:after on a replaced element means 
(according to the note in 12.1). Do we expect

    IMG:before {content: "Boo!"; display: block}

to show a block element above the image? In that case, rule c is correct 
as it is, because that block inhibits its parent from being run-in. If 
we expect ':before' to simply not apply to replaced elements, then rule 
c is correct as well. But if we expect *something* to be generated in 
this case, but not a block, then rule c needs to change. I don't know 
how, though...

Here is an attempted rewrite with the added condition:

---------------------------------------------------------------------------
[Definition:] An element or pseudo-element C inhibits run-in behavior if 
one or more of the following are true. (Note that the definition is 
recursive.)

   a. C is not floating and not absolutely positioned[3] and the
      specified value of its 'display' is one of 'block', 'list-item'
      or 'table'.

   b. C is not floating and not absolutely positioned[3] and
      its 'display' is 'inline' or 'run-in' and it has one or more
      children that inhibit run-in behavior.

   c. C is not floating and not absolutely positioned[3] and
      its 'display' is 'inline' or 'run-in' and it has a :before
      pseudo-element[4] that inhibits run-in behavior.

   d. C is not floating and not absolutely positioned[3] and
      its 'display' is 'inline' or 'run-in' and it has an :after
      pseudo-element[4] that inhibits run-in behavior.
---------------------------------------------------------------------------

The added condition is "inline or run-in" instead of just "inline" 
because the following H2 contains a block and should not be rendered 
run-in:

    <h2 style="display: run-in">
      <span style="display: run-in">
        <span style="display: block">...</span>
      <span>
    </h2>
    <p>...

The definition can be made a little shorter by referring to the 
*computed* value of 'display' (see 9.7[7]), because a computed value 
of 'inline' already means that the element is neither floating nor 
absolutely positioned:

---------------------------------------------------------------------------
[Definition:] An element or pseudo-element C inhibits run-in behavior if 
one of the following is true. (Note that the definition is 
recursive.)

   a. C is not floating and not absolutely positioned[3] and the
      computed value of its 'display' is one of 'block', 'list-item'
      or 'table'.

   b. C has a computed value for 'display' of 'inline' or 'run-in' and
      it has one or more children that inhibit run-in behavior.
      (Where "children" includes both normal elements and :before/:after
      pseudo-elements.)
---------------------------------------------------------------------------

[7] http://www.w3.org/TR/2009/CR-CSS2-20090423/visuren.html#dis-pos-flo



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 Friday, 28 August 2009 13:00:20 UTC