MO-css3-grid-20111026

CSS Grid Positioning Module Level 3

W3C Member-only Draft 26 October 2011

This version:
http://www.w3.org/TR/2011/MO-css3-grid-20111026
Latest version:
http://www.w3.org/TR/css3-grid
Previous version:
none
Feedback:
www-style@w3.org with subject line “[css-grid-position] … message topic …” (archives)
Editors:
Alex Mogilevsky, Microsoft, alexmog@microsoft.com
Authors:
Alex Mogilevsky, Microsoft, alexmog@microsoft.com
Markus Mielke, Microsoft, mmielke@microsoft.com

This specification is not being actively maintained, and should not be used as a guide for implementations. It may be revived in the future, but for now should be considered obsolete.
If you have questions or comments on this specification, please send an email to the CSS Working Group's mailing list at www-style@w3.org. (Before sending mail for the first time, you have to subscribe at http://lists.w3.org/Archives/Public/www-style/.)

Abstract

This module describes integration of grid-based layout (similar to the grids traditionally used in books and newspapers) with CSS sizing and positioning.

Status of this document

This is a member-only draft. It may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

The (archived) mailing list w3c-css-wg@w3.org is preferred for discussion of this specification.

This document was produced for the CSS Working Group (part of the Style Activity).

This is the first public working draft of this module.

Table of contents

1. Dependencies on other modules

This CSS3 module depends on the following other CSS3 modules:

It has non-normative (informative) references to the following other CSS3 modules:

2. Introduction

Grid systems have provided great value to print designers for many years [THEGRID]. Now same concepts are applied to online content [SXSWGRIDS], [AGBDL]. Unlike print media however, dimensions of online devices vary broadly; a single fixed-sized grid that worked perfectly for print pages only works in a subset of web scenarios. Really adaptable solutions require dealing with a grid that adapts to fit devices of varying form factors.

This module adds capabilities for sizing and positioning in terms of a scalable grid . The grid can be specified directly by author, or can be implied from existing two-dimensional structures (tables or multi-column elements).

Grid positioning addresses layout in continuous media and in paged media.

3. Examples

Let's start with an illustration of grid in action.

3.1. Example 1

example of a 3-column layout with an image that spans the whole page and a 2-column box in bottom left corner

Floats in multi-column layout

Figure 1 shows a 3-column layout in paged media. It can be seen as a grid with 6 vertical lines (at each column boundary) and horizontal lines at margins.

body { columns:3; column-gap:2em; } 
float1 { float:page bottom left; width:3gr; }
/* Figure 1 */

The statement "float:page bottom left" positions the image at the bottom left corner of the page (as defined in [CSS3GCPM])

Property "width:3gr" makes it 3 "grid units" wide, where a "grid unit" is the distance between two adjacent grid lines. Each boundary between a column and a gap automatically produces a grid line, therefore to specify "two columns, including the gap between columns, but not including any gaps outside the columns" we can just say "3gr".

Also, in this example the author has added a horizontal line to align illustrations with. This can be done by explicitly defining grid lines:

body { columns:3; column-gap:2em;
       grid-rows: 1.5in 1fr; }

div.illustrations 
     { float:page top left; width:5gr; height:1gr;}
     
float1 { float:page bottom left; width:3gr; }
       
/* Figure 2 */

In this example, "grid-rows" divides vertical space with explicit grid lines.

"1fr" is a flex unit ('fr' for 'fraction'). If multiple flex units are used, they take space proportional to their values. If we wanted to define vertical lines that would exactly match the 3-column layout with 2em gaps we could say

       grid-columns: 1fr 2em 1fr 2em 1fr;

When only one value has a 'fr' unit (as in "grid-rows: 1.5in 1fr" above), it just takes all remaining space regardless of the number.

3.2. Example 2

The following example illustrates the use of a grid in construction of a complex web site (see [SXSWGRIDS] for how exactly this was built). Note how groups of elements are aligned with different sets of grid lines.

[image of a complex page with overlaid grid] [image of complex page]

Complex site designed with a grid

4. Grid declarations

There are two ways to define a grid.

  1. Explicit grid: defined with 'grid-columns', 'grid-rows' properties.
  2. Implicit grid: automatically created by elements with a natural grid structure (multi-column elements and tables).

4.1. Explicit grid

Grid lines can be defined in terms of rows and columns. Rows are always horizontal and columns are always vertical (this doesn't change in vertical writing modes)

4.1.1. grid-columns’ and ‘grid-rows’ properties

Name: grid-columns
Value: [[<length>|<percentage>|<fraction>] |
repeat([<length>|<percentage>|<fraction> ]+)]+ |
none | inherit
Initial: none
Applies to: non-replaced block-level elements
Inherited: no
Percentages: refer to width of the block
Media: visual, paged
Computed value: specified value
Name: grid-rows
Value: [[<length>|<percentage>|<fraction>] |
([<length>|<percentage>|<fraction> ]+)[‘[’<integer>‘]’]? ]+ |
none | inherit
Initial: none
Applies to: non-replaced block-level elements
Inherited: no
Percentages: refer to height of block
Media: visual, paged
Computed value: specified value

When grid-rows or grid-columns are specified, grid lines are defined as follows:

  1. 'start' edge of content box (logical start according to writing mode) defines a grid line
  2. each row or column of specified grid adds one line at the specified distance from previous line
  3. if the last specified row or column does not reach the 'end' edge of the content box, another grid line is added at the edge of the content box

 

Space for each column or row of the grid can be defined as

For example this rule

div { grid-columns: 50% 1fr 1fr 4em }

'fr' needs a precise definition. It is possible that there isn't any space to distribute between fractions, what happens then? fr becomes zero?

Grid lines can be defined in repeating groups using "repeat()" construct. Nested repeating groups are not allowed.

For example this rule

div { grid-rows: 4em repeat(0.25em 1em); }

It was proposed that property names refer to horizontalvertical lines instead of rows/columns (because they in fact define lines, not rows and columns). Possible alternatives: grid-horizontal-lines/grid-vertical-lines; or perhaps simply grid-horizontal/grid-vertical.

It was proposed to have syntax for repeating a certain number of times. It is not strictly necessary (if the number of times is known the values can be repeated inline) but handy.

4.2. Implicit grid

Elements with a natural grid structure automatically define a grid that aligns with the structure. It is called an implicit grid. Such elements are

4.2.1. Multi-column element

Left and right edges of each column form a grid line. There are twice as many grid lines as there are columns.

4.2.2. Table

Border box of each table column defines two vertical lines; border box of each table row defines two horizontal lines. In collapsing border model there is always a pair of identical grid lines between each pair of rows and columns. Maintaining same amount of lines per column keeps the definition consistent across all table models and multi-column elements (e.g. a span over 2 columns is always 3gr)

Definition of a grid for a table is only meaningful if there is something that can use it. Currently there are no table floats. Should there be? Something like "float:top left table; float-offset:2gr 4gr" would use the table grid. Is there a use case for such floats? There is still absolute positioning that can target at table of course...

4.2.3. Viewport

Viewport always defines a single-cell grid with the size of the viewport.

4.2.4. Priority of explicit grid definition

If explicit grid properties grid-columns or grid-rows are specified on an element with an implicit grid, the explicit properties have priority.

5. Grid units

gr is used to position in relation to the grid lines. Actual value of each gr depends on the grid cell in which it is used.

Example

div { columns:3; }
div img { float: top left column; 
          float-offset: 2gr; 
          width: 1gr }

The image is positioned over the 2nd column (left edge of second column is 2nd grid line from left; its width is the distance to the next grid line).

Lorem ipsum dolor
sit amet. Nam at jus.
Sed imp er di et ris.
Cur abi tur et sapen.
Vivamus a metus.
Aenean at risus
pharetra ante luctu
feugiat quis enim.
Cum sociis natoque
penatibus et magni.

Lorem ipsum dolor
sit amet. Nam at jus.
Sed imp er di et ris.
Cur abi tur et sapen.

Lorem ipsum dolor
sit amet. Nam at jus.
Sed imp er di et ris.
Cur abi tur et sapen.
Vivamus a metus.
Aenean at risus
pharetra ante luctu
feugiat quis enim.
Cum sociis natoque
penatibus et magni.

Fractions of gr unit can be used too. In this example

div img { float:left column; float-offset: 0.5gr; width: 2gr; }

the image takes exactly the width required to stretch from the middle of first column to the middle of second column. width:2gr in the example doesn't start from exactly a grid line, therefore it is calculated as a sum of grid parts (2gr = 0.5gr + 1gr + 0.5gr), which ends in the middle of second column.

Lorem ipsum dolor sit amet. Nam at jus. Sed imp er di et ris. Cur abi tur et sapen. Fusce sed ligula a turpis. Vivamus a metus.

Lorem ipsum dolor sit amet. Nam jus.
Sed imp er di et ris. Cur abi tur et sapen. Fusce sed ligula a turpis. 

Lorem ipsum dolor
sit amet. Nam at jus.
Sed imp er di et ris.
Cur abi tur et sapen.
Aenean at risus
pharetra ante luctu
feugiat quis enim.
Cum sociis natoque
penatibus et magni.

5.1. Applicability of grid units

Grid units are applicable to all properties of block elements that take values of type <length>.

When applied to margins, borders and padding, grid units refer to grid lines in the direction of line progression (horizontal in layout with horizontal lines).

Grid units never apply to inline elements, including inline blocks.

5.2. Grid container

Since separate grids can be defined on nested elements, it must be defined which grid is referred to for every use of 'gr' unit.

For all cases where 'gr' unit is applicable the grid is taken from the containing block (which is found as defined as defined in CSS2.1 section 10.1).

In this example, div1 is the positioning parent and therefore grid of div1 is used for positioning:

<style>
 .div1 { position:absolute; grid-columns:4em repeat(1em 4em); } /* this grid is used */
 .div2 { columns-width:10em; column-gap:1em; } 
 img { position:absolute; left:2gr; width:3gr; }
</style>
<div class="div1">
 <div class="div2">
  <img />
 </div>
</div>

However in the next example, grid of div2 is used by the float, because it is the float's containing block:

<style>
 .div1 { position:absolute; grid-columns:4.5em (1em 4.5em); }
 .div2 { columns-width:10em; column-gap:1em; } /* this grid is used */
 img { float:left; float-offset:2gr; width:3gr; }
</style>
<div class="div1">
  <div class="div2">
   <img />
  </div>
</div>

5.3. Reference point for grid units

Calculating grid units require a reference point within the grid and direction. This needs a precise definition. For the same element, grid units for position and size may have different reference points (but probably not different directions).

Define how 'gr' is used on in-flow blocks. Is '1gr' generally equivalent to '100%' there?

6. Grid in overflow

When a measure defined in grid units extends outside the boundaries of grid container, grid lines are repeated according to the following rules

Add an example

How important is an overflow grid? What use cases would suffer if 'gr' is just set to zero in overflow?

7. Issues

7.1. Grid on shrink-to-fit elements

Specifying a grid on an element with shrink-to-fit sizing can create difficult or unsolvable problems, similar to use percentages within shrink to fit but even more complicated. Consider ignoring grid definition on anything shrink-to-fit.

7.2. Additional implicit grid lines

On the implicit grids for multi-column elements, it might be useful to have one grid line on the left and right edge of each column, as well as a single grid line between each pair of columns. Perhaps doing the same thing for tables, one line on each side of the border spacing and another at the row/column boundary.

7.3. Snap to grid

Should there be an option to align flow content to next available gridline? It opens really cool scenarios. But are they compelling enough to create a next available notion?

7.4. Undefined grid and notion of 'default' grid

When a grid unit is used in context where there isn't an explicit or implicit grid specified, what should it be? Reaching to nearest parent with a defined grid may or may not be the right choice. There is an option to give any element a "default grid" of one cell.

7.5. Page grid

It must be possible to define different grids for left and right pages. Also, any page with different dimensions (such as named pages) should be able to define its own grid.

Add grid-columns/grid-rows to @page rule

7.6. Named grid lines and cells

If grid is used extensively, named grid locations would be quite helpful. Defining named grid lines could look for example like this:

body { grid-columns: "left-edge" 1fr 1em 1fr 0.5em "center" 0.5em 1fr 1em 1fr "right-edge";

This syntax doesn't easily extend to named cells. It was noted however that named cells also open a possibility for named flows (by providing a sequence of named cells to fill) which makes the feature quite attractive and further approaches Advanced Layout scenarios.

7.7. Templates in CSS3 Advanced Layout module

"Template-based positioning" in CSS3 Advanced Layout module [CSS3LAYOUT] defines scalable templates for content to fill and also used the term "grid".

The relationship between these modules certainly needs to be well defined.

Note that technically these modules are not contradictory (as long as is defined how an advanced-layout template produces an implicit grid).

Acknowledgments

This specification is made possible by input from Håkon Wium Lie, Steve Zilles, Mike Duggan, Bill Hill, Geraldine Wade, Rikkert Koppes, Peter Linss [to be added].

Thanks to Khoi Vinh for the “Yeeaahh!” Example.

 

References

Normative references

[CSS3VAL]
Håkon Wium Lie; Tab Atkins; Elika J. Etemad. CSS Values and Units Module Level 3. 6 September 2011. W3C Working Draft. (Work in progress.) URL: http://www.w3.org/TR/2011/WD-css3-values-20110906/

Other references

[AGBDL]
Charles Jacobs; et al. “Adaptive Grid Based Document Layout” in: ACM Transactions on Graphics. 22. 3. pp. 838–847. July 2003. URL: http://grail.cs.washington.edu/pub/papers/Jacobs2003.pdf
[CSS3COL]
Håkon Wium Lie. CSS Multi-column Layout Module. 12 April 2011. W3C Candidate Recommendation. (Work in progress.) URL: http://www.w3.org/TR/2011/CR-css3-multicol-20110412
[CSS3GCPM]
Håkon Wium Lie. CSS Generated Content for Paged Media Module. 8 June 2010. W3C Working Draft. (Work in progress.) URL: http://www.w3.org/TR/2010/WD-css3-gcpm-20100608
[CSS3LAYOUT]
Bert Bos; César Acebal. CSS Template Layout Module. 29 April 2010. W3C Working Draft. (Work in progress.) URL: http://www.w3.org/TR/2010/WD-css3-layout-20100429
[MEDIAQ]
Håkon Wium Lie; et al. Media Queries. 27 July 2010. W3C Candidate Recommendation. (Work in progress.) URL: http://www.w3.org/TR/2010/CR-css3-mediaqueries-20100727/
[SXSWGRIDS]
Khoi Vinh; Mark Boulton. Grids Are Good. March 2007. SXSW Interactive, Austin, TX. URL: http://www.subtraction.com/pics/0703/grids_are_good.pdf
[THEGRID]
Allen Hurlburt. Grid: A Modular System for the Design and Production of Newpapers, Magazines, and Books. Wiley. 1982. ISBN 0-471-28923-X.

Index

Property index

Property Values Initial Applies to Inh. Percentages Media
grid-columns [[<length>|<percentage>|<fraction>] | repeat([<length>|<percentage>|<fraction> ]+)]+ | none | inherit none non-replaced block-level elements no refer to width of the block visual, paged
grid-rows [[<length>|<percentage>|<fraction>] | ([<length>|<percentage>|<fraction> ]+)[‘[’<integer>‘]’]? ]+ | none | inherit none non-replaced block-level elements no refer to height of block visual, paged