Re: layout idea

(answering to all comments in one mail)

2009/3/21 Brad Kemper <brad.kemper@gmail.com>:
>[...]
>
> On Mar 20, 2009, at 3:50 PM, Tab Atkins Jr. wrote:
>
>> On Fri, Mar 20, 2009 at 5:30 PM, David Hyatt <hyatt@apple.com> wrote:
>>>
>>> On Mar 20, 2009, at 5:02 PM, Tab Atkins Jr. wrote:
>>>>
>>>> There's a few issues we need to settle on.
>>>>
>>>> Flowing blocks into a table cell
>>>> --------------------------------
>>>> I still believe that supporting flowing blocks into a cell is a
>>>> necessary thing to unleash the true power of a layout manager.
>>>> However, I'm okay with delaying this for a proper Named Flows module.
>>>> There's a lot of idea space here that needs to be properly covered,
>>>> and trying to rush it for this module will probably just mean we do it
>>>> wrong.  So, chunk this for now.  You want to push something around in
>>>> a table module, you can wrap it in a container.  This is a 90%
>>>> solution that works for me.
>
> Yes, that is essentially my outlook too. I would like to have something that
> is easily understandable, makes creating table-like structures easier than
> HTML tables do, and still have all the essential powers of table display,
> and can have source-order independence for the basic units of the table
> structure: the cell.[...]

I don't like having source-order-independence at all. Assuming that a
Named Flows module will be created and implemented at some time, I
don't see any use for "table-position", since it would be a duplicate
for "move-to".
Instead, if you have the rights to wrap content in a container, you
then are able to copy-paste content in different orders. This is btw
what we did from the very beginning.
And, as David Hyatt noticed, completely forbids incremental layout.
Yes, as Tab replied, current table implementations are not able to
render incrementally, but this is an issue only for the automatic
table layout, not for the table model in general.

> Maybe the mechanism for moving content footnotes in paged media could be
> extended to move things into table cells as well, but we don't need that to
> move forward with this.

This is what TJ meant with Named Flows.

>
>>> Really I'd like to see an example that proves this is needed.  It adds
>>> complexity that it would be nice to avoid if nobody can prove that it's
>>> really needed.

Actually, as Brad noticed, Named Flows are already required for
footnotes / section notes, so I feel that we're not proposing a new
feature, just reusing it creatively.

>> That would be why I said we can skip it for now.  ^_^  I do think it's
>> important, but I want to solve it *correctly*, and I don't want to be
>> forced to do that here.
>
> I am happy that we three at least seem to be in general agreement on this
> point.
>
>>>> Dealing with automatically generated anonymous table-cell blocks
>>>> ----------------------------------------------------------------
>>>> I'm talking about those generated by the table layout algorithm in the
>>>> Tables Module.  If you set an element as display:table and it has
>>>> children who don't aren't display:table-*, they'll get wrapped in
>>>> cells automatically.  Right now, we have no way to refer to them.  The
>>>> question is, do we care?  This is, btw, a big reason to *support*
>>>> flowing things into anonymous cells, so then you can name or otherwise
>>>> identify these things, but let's pretend that we're not considering
>>>> that at all right now.

First, you need to create the anonymous cells, and give it a name.
Then you may start filling it.
Template Layout resolves this issue declaring cells explicitly with an
identifier at the display-model declaration on the parent.

>>> That's almost a separate problem.  There's no way to refer to anonymous
>>> cells/rows/columns etc. now, and it's already an annoying issue.
>>
>> Indeed, so it's not a layout issue *per se*.  Something intelligent
>> does have to be done about this, though.
>
> If what we've been talking about here is a CSS3 tables module, then that
> would be a good place for it. Is there any compelling reason why the spec
> cannot just declare via fiat that ::table-cell includes anonymous cells? I'm
> significantly less concerned about ::table-row, and there is no real
> style-able element to select with ::table-column anyway.
>
> It would be really nice if we could also do ::nth-row(), ::nth-col(), or
> even something like ::nth-row(3)::nth-col(2) to select structures whether
> they were anonymous or not. There would be no way to select a row other-wise
> (if they are all anonymous with this wrapping scheme), and the row-spans and
> col-spans would mess up many hopes of using nth-child to select the right
> cells (at least if were are properties that ::col() wasn't allowed to
> style).

Are those pseudo-classes or pseudo-elements? If they were...
1) pseudo-classes, they could not select any anonymous element,
because they could only select elements really belonging to the DOM
(consider that selectors are not only used in CSS)
2) pseudo-elements, they could not select elements really present in
the DOM, because otherwise we would have two CSS elements (one real,
one pseudo) matching the same content.
The latter is not really an issue (aside from cascading problems), is
more architectural probably.

>
>>>> After some thought, you're right.  Table-cell blocks in the markup
>>>> should immediately flow into the table exactly as normal.  This is by
>>>> far the simplest and most comprehensible solution.  I think the core
>>>> of making this an actual layout manager hinges on intelligent behavior
>>>> for displacing table cells when other cells are moved into position.
>>>> Your original idea of the later declaration winning and the previous
>>>> one being shoved to the side is absolutely the way to go.
>>>
>>> I disagree.  I would expect the first cell to get the slot and later
>>> cells
>>> to get displaced.  Think about incremental rendering.  You want the
>>> earlier
>>> cells to win, not have everything popping all over the place as later
>>> cells
>>> suddenly displaced the earlier ones.
>>
>> You can't save incremental rendering when you're rearranging a table
>> no matter *what* you do.  If the first cell wins, as you want, then
>> the second cell has to go *somewhere*.  It either slides in to the
>> right of the first cell, in which case the *existing* rightward
>> neighbors of the first cell get shoved, borking incremental rendering,
>> or it goes to the first empty hole, which completely ruins the
>> source-order-independence ideal.
>>
>> If we want to keep source-order independence, I don't think it's
>> possible to keep incremental rendering without some
>> possibly-significant reflows.  If this is absolutely important, then
>> we can probably just stop right here, add row-span and col-span, and
>> then look for a layout manager that *does* allow incremental rendering
>> while preserving source-order independence.

This is what I think: source-order independence is out of the scope of
a table layout manager. Incremental rendering is not just an
implementation optimization, it is part of the core CSS, where element
just require a layed out parent (or containing block) and previous
sibling to get displaced appropriately.
The only algorithms in CSS that don't allow incremental rendering are
shrink-to-fit and table-auto-layout, both of which are expected to be
defined better in CSS3.

> Yeah, just to paint a mental picture, what I was imagining is more or less
> like what happens when you re-arrange icons on an iPhone home screen, or
> columns in a Mac OS X Finder window (but instantly before it renders,
> without the animation).
>
> It seems like the UA would need a few passes to get to the final product
> anyway:
>
> 1. Layout out all the cells into one row, with all spans included.
>
> 2. Wrap into rows to the column-count, letting too-wide col-spans extend
> beyond the right edge temporarily (a col-span would not wrap in mid-span).
> Row spans would limit the number of other cells that could exist along side
> them on their extra rows.
>
> 3. Do the iPhone home screen thing and move around any cells or rows that
> you need to, with other cells moving linearly out of the way and also
> filling the hole left behind, and rewrapping if needed.

Sorry, I don't have an iPhone at the moment, and I can't understand
what you mean.

> 4. Any col-spans that extended out beyond the specified number of columns
> would now be narrowed to fit (making them 'col-span:*').
>
> 5. Additional cells are added to fill out the last row if needed, or to meet
> the number of rows specified (which is really only helpful if you can apply
> height, background, border, etc. to them).
>
> Don't tables require a couple passes anyway, to resolve row heights and cell
> widths, for instance?

Only for the auto layout, not for the fixed layout, and I don't want
to break this.

>>>> Now we must address what do we do if this would increase the number of
>>>> columns?  If we stick close to the existing table model, the answer is
>>>> "increase the number of columns".  Is this sufficient?  I think so.
>
> See above. Last-rule-wins, because previously moved item gets bumped out of
> the way and becomes adjacent. Then I would wrap to the next row when the
> column count got too high, and impose a limit on column-spans, so that the
> author's intent on column number is the overriding consideration for
> building the table.

Sorry, I can't understand you, especially about "last-rule-win" (but,
just in case, don't forget we cannot rely on the cascading process to
get an appropriate layout, we would break the layering)

>
> [...]
>
> Do you mean if you've got an element with 'display:table-row' on it, mixed
> in with the automatically created rows? That is the tricky part. I've been
> thinking about that off and on. I'm leaning towards them being mutually
> exclusive. That is, if you set the number of columns to flow into, then
> ignore any display:table-row elements that would be part of the same table.
> Or.. have it act as a row-wrappable container for specifying things that
> rows can specify, like vertical-alignment or color. Or.. have it always
> appear as its own row, with anonymous cells completing the row above it if
> needed, and sticking out of the right side of the table if it is too many
> cells wide (like a sort of row-specific special row-specific  override).

Uhm.... you may just turn "table-row" into "table-row-group", forcing
a break in the row. Eg, from a DOM of:

<div style="display-model:table;table-column-count:3";>
<div style="display-role:table-cell;">1</div>
<div style="display-role:table-cell;">2</div>
<div style="display-role:table-cell;">3</div>
<div style="display-role:table-cell;">4</div>
<div style="display-role:table-row;"><div
style="display-role:table-row;">5</div></div>
</div>

you should get a rendering of:

| 1 | 2 | 3 |
| 4 |
| 5 |

that is actually a 3 x 3 table, missing some cells (for which the
"empty-cell" properties applies)

Anyway, I don't agree with automatic wrapping of cells in any case.
This is something that should be done in a different layout mode (eg
Flexible Box), not in the current table-layout.
So once more, the only proposals I currently support are "row-span"
and "col-span", that are required for compatibility with HTML4/5 and
supported by CSS21.
Anything else is just not a table.

Giovanni

Received on Saturday, 21 March 2009 14:54:00 UTC