Re: layout idea

I'll squeeze a few comments in below on this one to reply to Hyatt and  
Tab, since I am responding several hours later, and I think the  
essentials of the three e-mails are all quoted herein.

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. The  
idea of just moving multiple whatevers of any kind into a particular  
cell really goes further than this, and does belong in a separate  
proposal (named flows, float-to, or whatever), for moving items not  
only into cells, but into blocks, column-boxes, other types of grids,  
etc. 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.

>> 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.
>
> 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.
>>
>> 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).


>>> 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.

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.

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?

>>> 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.

>>> The only time I can see it *not* being fine is when you have  
>>> something
>>> like this:
>>>
>>> <div #some-content-blocks>
>>>  <div>blah</div>
>>>  <div>blah</div>
>>>  ...
>>> </div>
>>>
>>> You don't know how many content blocks you'll have, you just know  
>>> that
>>> you want them to look like a table; that is, you want all the blocks
>>> on a particular row to have the same height and the widths to align.
>>>
>>> This seems like something Flexible Box can solve by itself, as David
>>> alluded to.  Make #some-content-blocks a table-cell and position it,
>>> possible with a row-span, then use horizontal box flow with a %  
>>> width
>>> to lay out the individual blocks.  They'll flow sideways, and then
>>> move onto a new line when the current one is full.
>>>
>>> So, I think we can just stick with the existing table model there.
>>> Cells absolutely stay on the row they are laid out on, unless you
>>> explicitly move them with table-position, and will increase the  
>>> column
>>> count if necessary.
>>
>> Yeah if you have extra explicit rows that then specify more columns  
>> than the
>> original grid did, you have to decide whether intelligent fitting  
>> algorithm
>> will adjust because new columns have been added.  That's tricky.
>
> Well, what's the intelligent fitting algorithm you've got in mind?
> Currently in my head it's just "act like tables".
>
> ~TJ

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).

Received on Saturday, 21 March 2009 10:58:10 UTC