- From: Bert Bos <bert@w3.org>
- Date: Thu, 2 Aug 2012 21:47:11 +0200
- To: www-style@w3.org
- Cc: Mark Boulton <mark@markboulton.co.uk>
On Thursday 02 August 2012 15:29:00 Mark Boulton wrote:
> In reference to:
> http://dev.w3.org/csswg/css3-grid-layout/#core-concepts-of-the-grid
>
> I'm confused as to the need to invent new terminology with regards to
> grids that have existed for centuries. I'm also a little concerned
> that the mental model this terminology builds is one more similar to
> tables and spreadsheets (where these terms could be interchangeable)
> than to grids and layout.
Thanks for your message, Mark. I think our terminology is based on table
terminology (rows, columns and cells) on purpose. Just about everybody
is familiar with tables, so building on that shared knowledge makes
sense.
The idea to base the grid on a constant-size Module and Gutter is a good
guideline for many kinds of layout, but it is not a useful base for
everything we want to do with grids and templates. Especially in GUIs,
but also in many Web pages, some Fields (we called them slots or
regions, to have a neutral term) have to be flexible, to adapt to their
content or to the viewport size. So we need a more general model, which
allows not only to build a grid out of fixed units, but also allows
arbitrary and content-dependent field sizes.
That's why we don't have properties for module and gutter, but
properties that specify the size of each column and row individually. If
you have eighteen columns and three rows plus the gutters between them,
that may be a bit more verbose than your solution, but it is as easy to
learn:
grid-columns: * 1em * 1em * 1em * 1em * 1em * 1em * 1em * 1em *
1em * 1em * 1em * 1em * 1em * 1em * 1em * 1em * 1em *;
grid-rows: * 1em * 1em *;
(Our drafts currently have both '*' and '1fr'. We probably don't need
the 'fr' unit.) In particular, this allows us to use the keyword 'fit-
content' for columns whose width should depend on their content (similar
to how table cells get their size).
Note that we don't have explicit gutters at this level. Just rows and
columns (and thus cells). Their function in the layout is determined
elsewhere.
With nothing but this grid you can already do an improved kind of
absolute positioning: position elements with their corners on the grid,
without any difficult calculation of x-y coordinates. That is useful if
CSS is used as part of a system for laying out GUIs. (We used to have a
special unit for that, similar to Mark's 'md', but in fact you don't
even need a unit. You can just use numbers. Indeed, a unit would be
confusing: e.g., '3md' isn't three times as wide as '1md'.)
But for laying out documents, we need more: We need to define Fields,
because in most cases there isn't an element in the document that
corresponds to a Field, but a set of elements that all need to go into
the same Field. E.g., if we have the following document
<h1>...</h1>
<img>
<p>...
<p>...
<p>...
and a layout with three Fields, we may want to put the H1 in the first
field, the IMG in the second, and all three Ps together in the third.
(Another reason to want fields, rather than just absolute positioning on
a grid, is that at some point we'll probably want to chain a number of
fields together into a single flow. Then we'll not only have the case
that several elements go into one field, but also the case that a single
element goes into several fields, each field taking the overflow of the
previous one. The former could be solved with XSLT, but the latter
cannot.)
Each field spans a whole number of modules horizontally and vertically.
It might be useful to allow fields to overlap, and I think there is a
note somewhere in one of our drafts about a possible future extension,
but the easy case is to just not allow that. And we need a way to refer
to fields, which seems more easily done by giving each field a name than
by using its coordinates.
These three pieces of data (size, location and name of each field) can
be very compactly specified as a template on top of the grid, e.g.:
grid-rows: 10em 1em *;
grid-columns: * 1em * 1em * 1em * 1em * 1em *;
grid-template: "a a a a a . b b b b b"
". . . . . . . . . . ."
"c c c . d d d . e e e"
(Note how I cleverly aligned the column widths with the field names. :-)
This is of course not required.)
This grid has six columns and five gutters in the traditional sense, or
simply eleven columns in the generalized model, which are used to define
five fields. E.g., the two top fields, a and b, could be used to show
two photos, and the three bottom fields, c, d and e, could contain three
short articles:
<figure>...</figure>
<figure>...</figure>
<!-- 1st article -->
<h2>...</h2>
<p>...
<p>...
<!-- 2nd article -->
<h2>...</h2>
<p>...
<p>...
<!-- 3rd article -->
<h2>...</h2>
<p>...
<p>...
The dots (".") in the template indicate cells that aren't part of any
field. Often they'll serve as visual gutters between the fields, as
here.
Possible rules to flow the elements into the fields, according to the
currently proposed syntax, are:
figure {flow: a}
figure + figure {flow: b}
h2:nth-of-type(1), h2:nth-of-type(1) ~ p {flow: c}
h2:nth-of-type(2), h2:nth-of-type(2) ~ p {flow: d}
h2:nth-of-type(3), h2:nth-of-type(3) ~ p {flow: e}
(The two figures probably also need 'width: 100%; height: 100%; object-
fit: cover' to make them the same size and fill the whole field.)
The example in Mark's article is this, in his notation:
div {
display: grid;
grid-module: 50px 30px;
grid-gutter: 21px;
grid-x-count: 10md;
grid-columns: 3md, 1fr, 2md;
grid-fields: 3md, auto, 1md;
}
In the notation of a recent draft (the notation tends to still evolve
somewhat between drafts), that would be:
div {
display: block;
grid: 50px 21px 50px 21px 50px 21px 50px 21px 50px 21px 50px
21px 50px 21px 50px 21px 50px 21px 50px
"aaaaa.bbbbbbbbb.ccc" 30px
"aaaaa.bbbbbbbbb.ccc" 21px
"aaaaa.bbbbbbbbb.ccc" 30px
"aaaaa.bbbbbbbbb.ccc" 21px
"aaaaa.bbbbbbbbb.ccc" 30px
"..................." 21px
"ddddd.eeeeeeeee.fff" *
"..................." 21px
"ggggg.hhhhhhhhh.iii" 30px;
}
(I think the 'auto' in the 'grid-fields' means the height of the
content, rounded up to the nearest (30 + 51n) px for n = 0, 1, 2... We
don't have such a thing in any draft yet. Do we need it?)
Obviously, this could be shortened a bit:
div {
display: block;
grid: 192px 21px 334px 21px 121px
"a . b . c" 132px
". . . . ." 21px
"d . e . f" *
". . . . ." 21px
"g . h . i" 30px;
}
We're investigating baseline grids as well, independent of design grids.
Some ideas are in http://dev.w3.org/csswg/css-line-grid/ (This is an
editor's draft, not yet an official proposal from the WG.)
To make snapping of lines to a baseline grid work well, we probably also
need to constrain the height of inline elements better, see some ideas
in http://dev.w3.org/csswg/css3-linebox/#LineStacking (Likewise only an
editor's draft.)
Bert
--
Bert Bos ( W 3 C ) http://www.w3.org/
http://www.w3.org/people/bos W3C/ERCIM
bert@w3.org 2004 Rt des Lucioles / BP 93
+33 (0)4 92 38 76 92 06902 Sophia Antipolis Cedex, France
Received on Thursday, 2 August 2012 19:47:43 UTC