Splitting 'display'

In preparation for a mild rewrite of Flexbox to make the concepts
expressed in it map to a cleaner model, I've gone ahead and revived
the idea of "display" as a shorthand.  This is *long* overdue.  I took
some text from an older WD of the Box module.

The only significant changes are that I'm using more straightforward
names for the sub-properties (display-inside and display-outside),
handle the table and ruby values slightly differently (in what I think
is a cleaner way), and have changed the names of the block-inside and
inline-inside values to "static" and "text" respectively.

You can check it out at http://www.xanthir.com/:ytg in HTML, or below
in Markdown:

The `display` property
======================

Previously, CSS conflated the ideas about how an element should react
to its parent and siblings (it's "outside" display), and how an
element should lay out its own children (its "inside" display), in the
single `display` property.  This resulted in a gradually-increasing
complexity debt, as every new layout mode needs to define multiple
display values to set both the new "inside" display and an appropriate
"outside" display.  In practice, not all "outside" displays are
accommodated, so authors must employ markup hacks to use both a
non-standard "outside" display and a new "inside" display.

To correct this, this specification redefines the `display` property
as a shorthand property for the `display-inside` and `display-outside`
properties.  **Issue: There are an additional set of concepts
conflated into `display`, exemplified by the `list-item` value.
Should this be defined as some sort of magic that translates into
another set of properties that actually trigger ::marker generation,
or perhaps as a shorthand for a third `display-extras` property?**

The `display` property now accepts one or two tokens.  If there are
two tokens, the first is taken as the value for `display-outside`, and
the second is taken as the value for `display-inside`.  If there is
one token, it is equivalent to a two-token expression as described
below:

Mapping of existing `display` values to the full shorthand
----------------------------------------------------------

`block`
: `block static`

`inline`
: `inline text`

`inline-block`
: `inline static`

`run-in`
: `run-in text`

`none`
: `none static`

`table`
: `block table`

`inline-table`
: `inline table`

`table-row-group | table-header-group | table-footer-group | table-row
| table-column-group | table-column`
: `(the given value) table-inside`

`table-caption`
: `table-caption static`

`table-cell`
: `table-cell static`

`ruby`
: `inline ruby`

`ruby-base-group | ruby-text-group`
: `(the given value) ruby-inside`

`ruby-text | ruby-base`
: `(the given value) static`

`list-item`
: `list-item static` **(Issue: I'm not happy with this.  It means that
it's impossible to have an inline list-item (this is bad for
footnotes, frex), so you have to fake it by floating the element.  We
could fix it by adding an inline-list-item display-outside value, but
that's just silly.  If we had a display-extras property, this would be
`block static marker`.)**


The `display-outside` property
------------------------------

Values: `block | inline | run-in | none | list-item | table-row-group
| table-header-group | table-footer-group | table-row |
table-column-group | table-column | table-caption | table-cell |
ruby-text | ruby-base | ruby-base-group | ruby-text-group `

`none`
: The element is not rendered. The rendering is the same as if the
element had been removed from the document tree, except for possible
effects on counters (see [generated] or [paged]).
    Note that :before and :after pseudo elements of this element are
also not rendered, see [generated].)

`run-in`
: The effect depends on what comes after the element. If the next
element (in the depth-first, left to right tree traversal, so not
necessarily a sibling) has a `display-inside` of `static`, the current
element will be rendered as if it had `display-outside: inline` and
was the first child of that block element. Otherwise this element will
be rendered as if it had `display-outside: block`.

`list-item`
: The element is rendered the same as if it had `display-outside:
block`, but in addition a marker is generated (see 'list-style').

`block`
: The element is rendered as a rectangular block. See Collapsing
margins for its position relative to earlier boxes in the same flow.
In paged media [ref] or inside another element that has two or more
columns, the box may be split into several smaller boxes.

`inline`
: The element is rendered inside a line box. It may be split into
several boxes because of line breaking and bidi processing (see the
Text module).

`table-*`
: See the Tables module.

`ruby-*`
: See the Ruby module.


The `display-inside` property
-----------------------------

Values: `static | text | table | table-inside | ruby | ruby-inside`

* If an element's computed value for `display-outside` is
`table-row-group | table-header-group | table-footer-group | table-row
| table-column-group | table-column`, the computed value of
`display-inside` is `table-inside`.
* If an element's computed value for `display-outside` is
`ruby-base-group | ruby-text-group`, the computed value of
`display-inside` is `ruby-inside`.

`table`
: See the Tables module.

`table-inside`
: If the computed value for `display-outside` is `table-row-group |
table-header-group | table-footer-group | table-row |
table-column-group | table-column`, see the Tables module.  Otherwise,
same as `static`.

`ruby`
: See the Ruby module

`ruby-inside`
: If the computed value for `display-outside` is `ruby-base-group |
ruby-text-group`, see the Ruby module.  Otherwise, same as `static`.

`text`
: If this is not an inline-level element, the effect is the same as
for 'static'. Otherwise the element's inline-level children and text
sequences that come before the first block-level child are rendered as
additional inline boxes for the line boxes of the containing block.
Ditto for the text sequences and inline-level children after the last
block-level child. The other children and text sequences are rendered
as for 'static'.

`static`
: Child elements are rendered as described for their
'display-outside'. Sequences of inline-level elements and anonymous
inline elements (ignoring elements with a display-role of 'none') are
rendered as one or more line boxes. (How many line boxes depends on
the line-breaking rules, see the Text module.)


Definition of "block-level" and "inline-level" elements
-------------------------------------------------------

An element is "block-level" if the computed value of its
`display-outside` property is `block`, `list-item`, or `run-in` if the
element is not running in.  An element is `inline-level` if the
computed value its `display-outside` property is `inline`, or `run-in`
if the element is running in.


Effects of `float` on `display-outside`
---------------------------------------

The effects of the `float` property on an element depend on the
`display-inside` value of the element's parent.

In `static` or `text` contexts, if an element's computed value for
`float` is not `none`, and the element's specified value for
`display-outside` is not `none` or `list-item`, the element's computed
value for `display-outside` is `block`.  **(Note: This is another
place where not having list-item be a magical synomym of block would
make things simpler.)

In all other contexts defined here, the `float` property has no
effect.  Future values of `display-inside` may define additional
handling for the `float` property.

Received on Friday, 16 April 2010 18:11:19 UTC