Styling anonymous container and child boxes

Ian Hickson made a proposal [1] for styling anonymous container boxes
that would solve a number of problems, and then quickly withdrew it in
response to comments.  That proposal has been in the back of my mind
for the past year, and I've run across several cases where it would be
useful.  I am now reviving that proposal, in modified form.

The need for creating parent/child markup arises in numerous cases.
Letting CSS do this would eliminate many, if not most, of the cases
that need XSLT to style a document of semantic markup that does not
need to be reordered.


Adding this on top of the existing CSS model is somewhat difficult.  My
solution is quite different from Ian's, and there are probably many
other solutions.

I propose that generated boxes inside and outside of an element be
matched by :inside and :outside pseudo-elements.  To allow :inside and
:outside pseudo-elements, the default value of 'display' should be
changed from 'inline' to 'auto' and the 'auto' value of 'display'
should be defined so that:

 * For elements in the document tree (and :before/:after, for backwards
   compatibility), it is equivalent to 'inline'.
 * For :inside/:outside pseudo-elements, it would mean that they are
   not generated as part of the "display tree."  (By display tree, I
   mean the document tree that corresponds to what is displayed.  It
   differs from the content tree of the document by the removal of
   elements with 'display: none' and the addition of generated
   content.)

This change to the 'display' property would even allow pseudo-elements
to be nested.  For example, "p:inside:inside" would be possible,
although I could understand not requiring this in initial
implementations.

When an :outside pseudo-element is generated (i.e, has 'display' other
than 'auto'), it is placed in the display tree in place of the element
(or pseudo-element) for which it is generated, and that element is its
only child.  When an :inside pseudo-element is generated, it is placed
in the display tree as the only child of the element (or
pseudo-element) for which it is generated, and what would otherwise
have been the children of that element are made the children of the
:inside pseudo-element.


Here are some examples of the use of these pseudo-elements:

1) Modified system fonts (see Braden McDaniel's comments [2]):
   p { font: caption; }
   p:inside { font-weight: bolder; font-size: 1.2em; display: block; }

2) Backgrounds and borders on headers that do not span the width of
   the page (this would deal with a common reason people want
   shrink-wrap on blocks [3]):

   h1:inside {
     display: inline;
     background: yellow;
     color: black;
     border: 3px solid green;
     }

3) Describing the formatting of form buttons:

   input[type=button] {
     display: inline-block;
     border: 3px outset #ccc;
     background: #ccc;
     color: black;
     }

   input[type=button]:focus:inside {
     display: inline;
     outline: 1px dashed black;
     }

4) Putting multiple borders on block level elements (as is done using
   extra markup in [4]):

   body {
     background: white;
     color: black;
     padding: 2em 3%;
     border: 5px solid black;
     }

   body:outside {
     display: block;
     background: #f90;
     color: black;
     padding: 4em 5%;
     }

5) Inline markup on block level elements:  For example, one could
   suggest that paragraphs with class .highlight look like they had
   been highlighted with a yellow highliter with the rule

   p.highlight:inside {
     display: inline;
     background: yellow;
     }

6) Generated content around replaced elements:  Using generated content
   on replaced elements doesn't make any sense since the generated
   content is supposed to be the first/last child in the content, but
   the content is replaced.  However, this could be done with
   :outside using the rule

   img.item:outside:before {
     display: marker;
     content: counter(item, disc);
     }

7) It would allow lots of things with generated content (:before and
   :after), that would probably be done more elegantly by allowing
   nested :before and :after pseudo-elements.  Nested :before and
   :after pseudo-elements would be made theoretically possible by
   allowing the 'auto' value of 'display' (proposed above) to apply to
   :before and :after as it does to :inside and :outside.

   I'm not sure whether this is a good thing or not, that is, whether
   powerful content generation should be possible in CSS.  It could be
   prevented by forbidding :before and :after pseudo-elements of other
   pseudo-elements (:before, :after, :inside, and :outside).

8) This could also act as an alternative to the proposed 'box-sizing'
   property [5], although there are reasons to use a property.  One
   could specify that a float's border-edge was 50% of the width of its
   parent with:

   p.float {
     float: left;
     width: 50%;
     }

   p.float:inside {
     display: block;
     border: medium solid red;
     padding: 1.5em;
     }

-David

[1] http://lists.w3.org/Archives/Public/www-style/1999Feb/0021.html
[2] http://lists.w3.org/Archives/Public/www-style/2000Feb/0131.html
[3] http://lists.w3.org/Archives/Public/www-style/2000Feb/0223.html
[4] http://www.webstandards.org/css/
[5] http://www.w3.org/TR/css3-userint#box-sizing

L. David Baron    Sophomore, Harvard (Physics)    dbaron@fas.harvard.edu
Links, SatPix, CSS, etc.     <URL: http://www.fas.harvard.edu/~dbaron/ >
WSP CSS AC                      <URL: http://www.webstandards.org/css/ >

Received on Saturday, 11 March 2000 16:12:05 UTC