Re: layout idea

On Thu, Mar 19, 2009 at 2:27 PM, David Hyatt <hyatt@apple.com> wrote:
> Hmmm yeah thats tricky.  The difficulty here is deciding whether you ever
> specify cells or if you are just specifying objects that go into cells.  If
> your divs *are* display:table-cell, then I don't think things really work
> the way we want... since the div now *is* the cell, so how could a pseudo
> element represent it?  It couldn't.
>
> I think you'd need a model that works something like this:
>
> (a) Specifying table-rows and table-columns results in the creation of
> columns and rows.  It's as though a bunch of <col> and <tr> elements had
> been placed anonymously into the source (and styled with the specified
> lengths).
>
> (b) As table cells are encountered in markup, they would just behave as
> normal if table-position: auto(?) was specified.  In other words, you
> wouldn't fit into the existing grid.  You'd just tack on to it.  If
> table-position:fit or an explicit position is specified, then you'd end up
> placing the cells at certain positions within the existing grid.  We'd have
> to decide what happens if two cells want the same position in the grid.
>
> (c) As objects with table-position != auto are encountered that do *not*
> have display:table-cell specified, those would be placed at a particular
> cell position.  If no cell is occupying that position, an anonymous cell
> would be created.
>
> It would only be the anonymous objects created from (c) that could support
> spans on the pseudo-element like you wrote above, but yeah I believe it
> would work as you described as long as the divs you're placing are just
> normal blocks and not display:table-cell.

That makes good sense.

In (b), you say that display:table-cell elements are 'tacked on' to
the structure produced implicitly by table-rows and table-columns.
So, given this markup:

<style>
body {
  display: table;
  table-rows: 2;
}

.cell {
  display: table-cell;
}
</style>
<body>
  <div .cell />
  <div .cell />
</body>

Would you expect a three-row table, with the first two rows being
anonymous rows created implicitly by the table-rows:2 declaration, and
the third being an anonymous row generated around the <div .cell>
blocks?

If yes, then I think I like it.  It solves the problem of just what to
*do* with the non-positioned (or table-positioned) display:table-cell
elements in an unambiguous and satisfactory manner.

> I think that would probably not be the default behavior.  If you specify some initial rows and columns, it seems like you should still behave exactly like a table with table-layout auto specified by default.  Intelligent fitting of cells into the grid could be achieved by either specifying a new kind of table-layout value, e.g., table-layout: grid, or by specifying a value in table-position.... table-position: fit ....   I think I'd prefer specifying this using table-position.

I like table-position:fit.  It keeps us closer to the table model as
it exists now, and puts the burden on wrapping or extending on the
individual cells.  Good call.


> We pretty much agree, except I want the initial value to be "the way things work today" and to have a new value for table-position to get the fitting behavior we all like.

Cool, and I like the idea of table-position:fit.  Being a little more
specific, presumably this would mean "fit into the first empty
table-slot"?

Ooh!  Brad earlier said he prefers his col#/row# properties over
table-position because they let you specify either of them.  Perhaps
we can adapt this here.  Specifying a single keyword like "fit" or
"auto" works as normal.  Specifying *two* values, though, makes them
apply specifically to the row and col values.  This way you can do,
say, "table-position: 2 fit" to make it just slide into the first
available position *in row 2*.  This is nicely extensible with further
keywords if we feel the need, such as "first" or "last" or what have
you.



> (a) If #foo and #bar are table cells, then there is a conflict, and we need to decide what would happen.  I'd be inclined not to allow two cells to occupy the same position, but then we have to decide what to do when an invalid position is specified.
>
> (b) If #foo is a table cell and #bar is just a block, then #bar would be placed inside #foo.
>
> (c) if #foo is a block and #bar is a table cell, then #foo would be placed inside an anonymous cell at (2,2).  #bar would then cause a conflict as in example (a).
>
> (d) If both objects are blocks, then they would both get put inside an anonymous cell at (2,2).
>
> I think the model should encourage not specifying display:table-cell cells at all.... i.e., objects that specify table-position should commonly just be blocks not cells.

That's about what I was thinking.  I'm just completely at a loss as to
what happens when there's a conflict.  Next available slot, as Brad
suggests (in other words, an table-position that's already taken
causes the value to be treated as "fit")?  Is it
first-come-first-serve, or last to the finish line wins?


> (1) table-position on a display:table-cell.  The object actually becomes the cell at that position.  A pseudo-element can't refer to this cell position when this is done.
> (2) table-position on a normal flow object like a block.  The object is placed *into* the cell at that position.  If no cell exists at that position, then an anonymous one gets made.  A pseudo element can be used to style this cell.
> (3) position:absolute with grid units.  Provides out of flow alignment to cells in tables.

That works for me.

I'm rather happy with this as it stands.  With just a little more
clarification, I think it accomplishes everything that Grid Layout
does (the two are identical if the display:table block doesn't have
any display:table-cell children), with the additional power of a
decently intuitive horizontal flow model (via table-position:fit) and
less need for wrapper divs (as you can push blocks directly into table
cells without them *becoming* table cells themselves).

So, let me wrap up this post with an attempt to duplicate a Template
layout that I keep dragging out (I do this because this is actually
the primary layout for the sites I actually have responsibility over,
and the ability to easily state their layout would be greatly
appreciated):

The Template layout:
"aa" a=header
"bc" b=sidebar, c=breadcrumbs
"bd" d=content
"ee" e=footer

The Table Layout module:
<body>
  <header />
  <article />
  ...maybe more articles
  <nav #breadcrumbs />
  <nav #sitenav />
  <ul #blogroll />
  <aside #personal-info />
  <footer />
</body>
<style>
body {
  display: table;
  table-rows: 150px 2em 1* intrinsic;
  table-cols: 200px 1*;
}
header {
  table-position: 1 1;
}
::table-cell(1,1) {
  table-col-span: 2;
}
footer {
  table-position: 4 1;
}
::table-cell(4,1) {
  table-col-span: 2;
}
#breadcrumbs {
  table-position: 2 2;
}
#sitenav, #blogroll, #personal-info {
  table-position: 2 1;
}
::table-cell(2,1) {
  table-row-span: 2;
}
* { /* Everything else on the page... */
  table-position: 3 2;
}
</style>

~TJ

Received on Friday, 20 March 2009 00:32:22 UTC