- From: Anton Prowse <prowse@moonhenge.net>
- Date: Sat, 20 Oct 2012 02:06:09 +0200
- To: "www-style@w3.org" <www-style@w3.org>
- CC: "Tab Atkins Jr." <jackalmage@gmail.com>
Seems that Tab and I have both been thinking about this in recent days![0] I haven't yet compared what's in [0] with what's below, but I will do shortly. Bert and I are currently discussing what I've written below, which is why I hadn't posted it so far; but seeing as the topic is live right now I think it's worth posting straight away so that we can all compare the issues and figure out how best to proceed. [0] http://lists.w3.org/Archives/Public/www-style/2012Oct/0552.html On Wed, 21 Apr 2010 08:49:42 -0700 Tab Atkins Jr. wrote: >> On Fri, 16 Apr 2010 12:23:18 -0700 Tab Atkins Jr. wrote: >>> On Fri, 16 Apr 2010 11:10:25 -0700 Tab Atkins Jr. wrote: >>>> 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. A couple of years on, and I've been thinking about this afresh for css3-box. To get another perspective and to re-evaluate assumptions, I decided to first approach the problem completely independently from the above thread and other past ones; however, when I compared my resulting model with Tab's (an update version of which is presented in http://www.xanthir.com/blog/b45F0 ), I found that our thinking is pretty much identical. >>> It's probably good to explain why I did this. [...] >>> >>> [...] our conflation of the inside >>> and outside values has gotten somewhat ridiculous. At the very least, >>> any new display value has to be duplicated as a block and inline >>> version. This doesn't cover all useful cases, though. For example, >>> it's impossible to make a list-item act like a table, or a table-cell >>> to format its children as a flexbox. ...or for a flexbox item to act like a grid, or for a table caption to format its children like a flexbox, ... As we know, an old draft of the css3-box spec split 'display' into 'display-role' and 'display-model'. >>> [Treating 'display' as a shorthand for two longhand properties] makes >>> this all work simply, like its supposed to. This split continues to make sense to me, though like Tab I prefer the names 'display-outside' and 'display-inside'. > There are three areas of difference [from] the older draft: > > 1. Some names have been changed > 2. All corner cases are specified (the older draft forgot to address a > few places) > 3. A slightly different mapping between some of the single-keywords > forms and the double-keyword forms. I don't think the differences > here are significant. >>>> 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 >>>> ---------------------------------------------------------- 'display' |'display-outside'|'display-inside'| -----------------|-----------------|----------------| block | block | block | inline | inline | inline | inline-block | inline | block | table | block | table | inline-table | inline | table | table-* | table-* | block | <- for discussion table-cell | table-cell | block | table-caption | table-caption | block | run-in | run-in | inline | compact | compact | block | ruby | inline | ruby | ruby-base | ruby-base | inline | ruby-text | ruby-text | inline | ruby-base-group | ruby-base-group | block | <- for discussion ruby-text-group | ruby-text-group | block | <- for discussion flex | block | flex | inline-flex | inline | flex | grid | block | grid | inline-grid | inline | grid | -----------------|-----------------|----------------| none | none | block | <- for discussion -----------------|-----------------|----------------| list-item | list-item | block | <- anomalies inline-list-item | inline-list-item| block | -----------------|-----------------|----------------- align-box | block | align-box | <- possible future flex-item | flex-item | block | values ----------------------------------------------------- Note that 'inline-block', 'inline-flex', 'inline-grid' and 'inline-table' are neither valid values of 'display-inside' nor of 'display-outside', but they are valid values of the 'display' shorthand property. The 'display-outside' property: Initial value: inline Values: none -> generates no boxes inline -> generates an inline-level principal box block -> generates a block-level principal box list-item -> generates a block-level principal box and a marker box inline-list-item -> generates an inline-level principal box and a marker box table-* -> generates a principal table-* box table-cell -> generates a cell-level principal box table-caption -> generates a caption-level principal box run-in -> generates either a block-level principal box or an inline-level principal box depending on context compact -> generates either a block-level principal box or a principal "margin box" depending on context ruby-* -> generates a principal ruby-* box flex-item -> generates a flex-level principal box The 'display-inside' property : Initial value: inline Values: inline -> the principal box is an inline box block -> the principal box is a block container box table -> the principal box is a table wrapper box and the element also generates a child table box ruby -> the principal box is a ruby wrapper box flex -> the principal box is a flex container box grid -> the principal box generates grid slot boxes align-box -> the principal box is an align box For discussion of the 'display-inside' value of elements whose 'display-outside' is 'table-*' and 'ruby-base-group' and 'ruby-text-group', see below. Note that values of 'display-inside' have no effect on replaced elements. To prevent unworkable combinations of 'display-outside' and 'display-inside', we need just three rules: (1) If 'display-outside' doesn't compute to 'inline', 'run-in', or 'ruby-*' then a specified value of 'inline' for 'display-inside' computes to 'block' (but see (3) below for 'ruby-base-group' and 'ruby-text-group'). (2) If 'display-outside' computes to 'ruby-base' or 'ruby-text' then the computed value of 'display-inside' is 'inline'. (This differs from Tab's proposal in which the computed value is 'block'; I'm not too familiar with the Ruby spec but 'inline' looks more correct.) (3) If 'display-outside' computes to one of the 'ruby-base-group', 'ruby-text-group' or 'table-*' values as per the list of values given above, the "inside behaviour" is glued to the "outside behaviour", so the 'display-inside' value is not important but needs to be "normalized" to something. It's cleaner not to introduce all the 'table-*' etc values to 'display-inside' corresponding to the same values for 'display-outside', so I suggest we choose some single other value. Tab created new values 'table-inside' and 'ruby-inside' for this purpose... but perhaps we can just choose 'block'? Note that one of the axioms of the solution design is that 'display-outside' can influence the computed value of 'display-inside' but not vice versa. Run-ins and compact boxes In theory there need be no limitation on the 'display-inside' value of run-ins and compact boxes. A table element, flex container elements or grid element that runs becomes an inline-table, inline-flex or inline-grid, for example. display:none If we are to handle display:none using one or other of the 'display-outside' and 'display-inside' properties then 'display-outside' feels more natural. When 'display-outside' is 'none' then it's then an open question which value the 'display-inside' property should compute to. We could introduce a 'none' value of that property, but just as in rule 3 above it doesn't seem necessary; like Tab, I think that 'block' is as good a choice as any. With this approach, we need another rule: (4) If 'display-outside' computes to 'none' then the computed value of 'display-inside' is 'block'. However, the second of the two key issues raised on the original proposal to split the 'display' property concerned the ability of authors to toggle display (ie box generation) between none and not-none via script etc. When 'none' is handled by one of 'display-outside' or 'display-inside', it's necessary to first query and remember the current used value in order to know how to toggle between none and not-none. An alternative approach is to introduce a third longhand value for 'display'. For want of a better name, let's assume this property is called 'display-role' (thus reusing a previously-proposed term for a different purpose). The values would be defined as follows. The 'display-role' property: Initial value: normal Values: none -> boxes are generated as specified according to the values of 'display-outside' and 'display-inside' normal -> no boxes are generated for the element, irrespective of the values of 'display-outside' and 'display-inside' There would no longer be a need for a 'none' value of 'display-outside', "display:none" would be equivalent to "display: inline inline none", and box generation would be toggled using 'display-role' alone. The initial value of 'display' would be "inline inline normal". list items It has been argued that the 'list-item' value of 'display' is anomalous. For example: >>>> 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? > On Wed, 21 Apr 2010 10:12:34 +0300 Mikko Rantalainen wrote: >> I agree with your reasoning about list-item and the I think that it >> requires something pretty special. I'm afraid that for backwards >> compatibility and special side-effects required for current definition >> of 'display: list-item', the only logical choice is a third display >> property. I don't know if it should be called 'display-extras' or >> 'display-side-effects' or 'display-magic' or 'display-compatibility' but >> it would make following >> display: list-item; >> a short hand for >> display-outside: block; >> display-inside: inline; >> display-extras: list-item; /* ::marker and counter magic */ > > Well, display-inside is 'block' for list-item, but otherwise yes. The argument is that a list item is really a block-level box with an extra marker box, and so 'display-outside' really ought to be block, and the list item nature ought to be captured in some other way. Originally I thought the same thing, especially since it would seem natural to make a list item inline-level just by changing 'display-outside' from block to inline. However, I've recently moved away from that position. I don't think being a list item is orthogonal to 'display-outside'; I don't perceive a need for flex items or table captions that are also list items. I think it's reasonable to have 'list-item' and 'inline-list-item' values of 'display-outside' since list items are only really appropriate to block and inline formatting contexts. In contrast, tables, block containers and flex containers are appropriate to many formatting contexts and so having inline-* versions of them is peculiar. However, there is an editorial disadvantage to using 'display-outside', described below. Still, if we pursue the argument that list items are orthogonal to 'display-outside', we need to decide how to induce list item behaviour. It's also been argued that it doesn't make sense to use 'display-inside' for this, since it's reasonable to want list items which are flex containers, grids or tables. I'm on the fence about this. I'm not convinced we do want such things, in which case 'display-inline' is a viable possibility. (We'd only need one value, namely 'list-item'. This approach has the advantage of reusing a keyword that's already used for 'display'.) Another option is to introduce another longhand property for the 'display' shorthand, as discussed by others above. The name and values don't particularly interest me at this point, although I rather like 'display-model':'list-item' which again reuses a property name that was proposed for a rather different purpose and which reuses an existing keyword. (Presumably the other value would be 'normal' or suchlike.) We would need to introduce another rule: (5) If 'display-outside' doesn't compute to 'inline' or 'block' then a specified value of 'list-item' for 'display-model' (or 'marker' for 'display-extras' or whatever) computes to 'normal'. Yet another option is to not use a display longhand property at all, and instead use the existence of a non-empty ::marker pseudo-element. (Then "list-style-type:none" would create a marker with the equivalent of visibility:hidden rather than "display:none"; there's no rendering difference between the two at the moment, but there might be in future: eg see [1].) Whilst this seems rather natural, it's a rather more complex model (and the 'display' shorthand would be influenced by things other than its own longhand properties, which is possibly unacceptable). It also sounds harder to implement, and there is an editorial disadvantage, described below. Consequences One editorial thing to bear in mind when thinking about all this is that in various places in the spec we require that boxes be "blockified". For example, when boxes are floated or absolutely positioned, inline-* boxes become * boxes as per the table in CSS21 9.7 (extended in the flexbox spec to handle inline-flex, and tentatively in the lists spec to handle the proposed inline-list-item value). It would be great to be able to model that as a simple switch of 'display-inside' from 'inline' to 'block', so that we didn't need that table any more. Regarding list items, this switch is compatible with using 'display-inline' or 'display-model' etc to handle list items, but is incompatible with using 'display-outside' or an approach involving sniffing ::marker. [1] http://lists.w3.org/Archives/Public/www-style/2012Oct/0419.html Cheers, Anton Prowse http://dev.moonhenge.net
Received on Saturday, 20 October 2012 00:06:41 UTC