CSS Grid Template Module

[LONGSTATUS] [DATE]

This version:
https://www.w3.org/TR/[YEAR]/ED-css3-grid-template-[CDATE]/
Latest version:
https://www.w3.org/TR/[SHORTNAME]/
Editor's draft:
https://drafts.csswg.org/[SHORTNAME]/
Previous version:
http://www.w3.org/PreviousVersionURI
Issues List:
http://www.w3.org/Style/CSS/Tracker/products/FIXME
Discussion:
www-style@w3.org with subject line “[[SHORTNAME]] … message topic …
Editors:
[editor1 name], [affiliation (opt.)],
[editor2 name], [affiliation (opt.)],

Abstract

CSS is a language for describing the rendering of structured documents (such as HTML and XML) on screen, on paper, in speech, etc. This module contains the features of CSS level 3 relating to DESCRIBE HERE. It includes and extends the functionality of CSS level 2 [[!CSS21]], which builds on CSS level 1 [[CSS1]]. The main extensions compared to level 2 are SUMMARIZE HERE.

Status of this document

The following features are at risk: …

Leave for next level or different module: chaining regions, page templates, repeat (automatically add) columns and rows, style fragments of elements that are in a certain slot (region-based styling).

Table of contents

Introduction

This section is not normative.

Merge introductory text, which right now is simply concatenated between Grid and Template.

Image: four elements move to four slots
    in a template

Four slots, called a, b, c and d, each receive a part of a document

The styling of a Web page, a form or a graphical user interface can roughly be divided in two parts: (1) defining the overall “grid” of the page or window and (2) specifying the fonts, indents, colors, etc., of the text and other objects. The two are not completely separate, of course, because indenting or coloring a text influences the perceived grid as well. Nevertheless, when one separates the parts of a style that should change when the window gets bigger from the parts that stay the same, one often finds that the grid changes (room for a sidebar, extra navigation bar, big margins, larger images…), while fonts, colors, indents, numbering styles, and many other things don't have to change, until the size of the window becomes extreme.

The properties in this specification work by associating a layout grid with an element. Rather than letting an element lay out its descendants in their normal order as inline text or as blocks of text (the policies available in CSS level 1), the policy defined in this module gives an element an invisible grid for aligning selected descendant elements.

Because layouts on the Web have to adapt to different window and paper sizes, the rows and columns of the grid can be made fixed or flexible in size.

The typical use cases for these properties include:

Grid-based positioning is an alternative to absolute positioning, which, like absolute positioning, is especially useful for aligning elements that don't have simple relationships in the source (parent-child, ancestor-descendant, immediate sibling). But in contrast to absolute positioning, the elements are not positioned with the help of horizontal and vertical coordinates, but by mapping them into slots in a table-like template. The relative size and alignment of elements is thus governed implicitly by the rows and columns of the template.

The mapping is done with the 'position' property, which specifies in this case into which slot of the template the element goes. The template itself is specified on the 'grid-template' property of some ancestor of the elements to remap.

In this example, the four children of an element are assigned to four slots (called a, b, c and d) in a 2×2 template. (All mark-up examples in this specification are HTML fragments, unless otherwise stated.)

Image: sample rendering

Each element occupies one slot. In this template, all slots have the same size.

<style type="text/css">
  dl { grid: "ab"
             "cd" }
  #sym1 { position: slot(a) }
  #lab1 { position: slot(b) }
  #sym2 { position: slot(c) }
  #lab2 { position: slot(d) }
</style>
<dl>
  <dt id=sym1>A
  <dd id=lab1>A is een aapje
  <dt id=sym2>B
  <dd id=lab2>B is de bakker
</dl>
    

Templates can also help with device-independence. This example uses Media Queries [[MEDIAQ]] to change the overall layout of a page from 3-column layout for a wide screen to a 1-column layout for a narrow screen. It assumes the page has been marked-up with logical sections with IDs.

@media all
{
  body { grid: "aaa"
               "bcd" }
  #head { position: slot(a) }
  #nav  { position: slot(b) }
  #adv  { position: slot(c) }
  #body { position: slot(d) }
}
@media all and (max-width: 500px)
{
  body { grid: "a"
               "b"
               "c" }
  #head { position: slot(a) }
  #nav  { position: slot(b) }
  #adv  { display: none }
  #body { position: slot(c) }
}

Elements can be positioned this way, but not made to overlap, unless with negative margins. Here is how the “zunflower” design of the Zen Garden could be done:

#container { grid: "abc" }
#intro { position: (a); margin-right: -2em; box-shadow: 0.5em 0.5em 0.5em }
#supportingText { position: slot(b); box-shadow: 0.5em 0.5em 0.5em }
#linkList { position: slot(c) }

Template-based positioning borrows some concepts from table layout, in particular the idea of aligning elements in rows and columns, so that they constrain each other's size. But there are also differences. This example shows some of them. Assume this document fragment:

<div class=group>
 <div>aa aa aa aa aa aa</div>
 <div>bbb</div>
 <div class=menu>ccccc</div>
</div>

We can lay it out as three columns, as the following illustrations show. The style sheet would contain the following.

.group {display: table}
.group > div {display: table-cell}
    

[Three unequal cells]

Example of rendering with a table.

We can also use a template, in which case the style sheet would contain this:

.group {grid: "abc"}
.group > div {position: slot(a)}
.group > div + div {position: slot(b)}
.group > div + div + div {position: slot(c)}
    

By default, the table is as wide as needed to fit its contents. To make sure it is as wide as its containing block, we need to add

.group {display: table; width: 100%}

That is not needed for the template, but, on the other hand, if we want the template to fit its contents, we would need to say so:

.group {grid: "abc"; width: fit-content}

(See [[!CSS3BOX]] for the definition of the 'width' property.) The columns of the template are by default all the same size. The columns of the table satisfy certain constraints, but the exact size is not defined. We can make them all the same by adding a rule (see [[!CSS3TBL]]):

.group {display: table; width: 100%; table-layout: fixed}

[Three equal cells]

Example of rendering with equal columns.

In both styles, we can set a column to a certain size:

div.menu {width: 3em}

resp.,

.group {grid: "abc" * * 3em}

[Two equal cells, third is 3em wide]

Example of rendering with a fixed third column and the other two columns of equal width.

If there is an unknown number of columns (children of the div.group element), the style sheet for the table model will automatically take them into account. The style sheet for the template model, however, creates a template of exactly three columns and can't handle tables with an unknown number of columns. The extra elements will be added into the default slot (in this case the ''a'' slot).

In both models, elements can have borders, but only in the table model can borders be collapsed, which makes setting borders a little easier in the table model:

.group {display: table; border-collapse: collapse}
.group > div {border: solid}

resp.,

.group > div {border: solid; border-left: none}
.group > div:first-child {border-left: solid}
    

In the template model, the order of the elements is explicit, and thus it is possible to reverse the order of the columns:

.group > div {position: slot(c)}
.group > div + div {position: slot(b)}
.group > div + div + div {position: slot(a)}
    

[Different contents for the cells]

Example of rendering with the contents of the three columns reversed: the third element is shown in the first slot and the first element in the third slot.

In the table model, the order of the rows and columns is given by the document source and thus can't be changed.

This example shows a way to move notes to the end of a section. “Notes” in this example refers to elements in HTML with a class of “note”. A fragment of HTML such as

<div class=section>
  <p>The balubious coster of the fifth secter<span
    class=note> The sixth secter coster is a difter
    manon.</span> of The Rollow Carpug mentizes a costernica.
  <p>…
</div>

with this style sheet

div.section {
    grid: "*" available
          "F" available}
.note {
    position: slot(F);
    content: counter(note) ".\A0" contents;
    counter-increment: note;
    font-size: smaller}
.note::before {
    content: counter(note);
    position: slot(*);
    vertical-align: super;
    font-size: larger}

results in a rendering similar to this:

Same text, with the SPAN replaced by
      “(1)” and its content moved to the end.

Rendering of a text with footnotes.

Introduction to Grids

Background

FIXME

Application layout example requiring horizontal and vertical alignment.

As websites evolved from simple documents into complex, interactive applications, tools for document layout, e.g. floats, were not necessarily well suited for application layout. By using a combination of tables, JavaScript, or careful measurements on floated elements, authors discovered workarounds to achieve desired layouts. Layouts that adapted to the available space were often brittle and resulted in counter-intuitive behavior as space became constrained. As an alternative, authors of many web applications opted for a fixed layout that cannot take advantage of changes in the available rendering space on a screen.

The layout capabilities of the Grid address these problems. The Grid provides a mechanism for authors to divide available space for layout into columns and rows using a set of predictable sizing behaviors. Authors can then precisely position and size the building block elements of their application by referencing the Grid Lines between the columns and rows, or by defining and referencing a Grid Slot, which is a rectangular space covering an intersection of columns and rows. Figure 1 illustrates a basic layout which can be achieved with the Grid.

Adapting Layouts to Available Space

FIXME

Five grid items arranged according to content size and available space.

FIXME

Growth in the grid due to an increase in available space.

The grid element can be used to intelligently reflow elements within a webpage. Figure 2 represents a game with five major areas in the layout: the game title, stats area, game board, score area, and control area. The author's intent is to divide the space for the game such that:

As an alternative to using script to control the absolute position, width, and height of all elements, the author can use the grid element, as shown in Figure 3. The following example shows how an author might achieve all the sizing, placement, and alignment rules declaratively.

Note that there are multiple ways to specify the structure of the Grid and to position and size grid items, each optimized for different scenarios. This example illustrates one that an author may use to define the position and space for each grid item using the 'grid-rows' and 'grid-columns' properties of the grid element, and the 'grid-row' and 'grid-column' properties on each grid item.

<style type="text/css">
    #grid { 
        display: grid;

        /* Two columns: the first sized to content, the second receives the remaining space,   */
        /* but is never smaller than the minimum size of the board or the game controls, which */
        /* occupy this column. */
        grid-columns: auto minmax(min-content, 1fr);

        /* Three rows: the first and last sized to content, the middle row receives the remaining */
        /* space, but is never smaller than the minimum height of the board or stats areas.       */
        grid-rows: auto minmax(min-content, 1fr) auto
    }

    /* Each part of the game is positioned between grid lines by referencing the starting grid line and */
    /* then specifying, if more than one, the number of rows or columns spanned to determine the ending */
    /* grid line, which establishes bounds for the part. */
    #title    { grid-column: 1; grid-row: 1 }
    #score    { grid-column: 1; grid-row: 3 }
    #stats    { grid-column: 1; grid-row: 2; grid-row-align: start }
    #board    { grid-column: 2; grid-row: 1; grid-row-span: 2 }
    #controls { grid-column: 2; grid-row: 3; grid-column-align: center }
</style>

<div id="grid">
    <div id="title">Game Title</div>
    <div id="score">Score</div>
    <div id="stats">Stats</div>
    <div id="board">Board</div>
    <div id="controls">Controls</div>
</div>

Source Independence

FIXME

An arrangement suitable for "portrait" orientation.

FIXME

An arrangement suitable for "landscape" orientation.

Continuing the prior example, the author also wants the game to adapt to the space available on traditional computer monitors, handheld devices, or tablet computers. Also, the game should optimize the placement of the components when viewed either in landscape or portrait orientation (Figures 4 and 5). By combining the CSS markup for the grid element with media queries [[MEDIAQ]], the author is able to use the same semantic markup, but rearranged independent of its source order, to achieve the desired layout in both orientations.

The following example leverages the Grid's ability to name the space which will be occupied by a grid item. This allows the author to avoid rewriting rules for grid items as the Grid's definition changes.

<style type="text/css">
    @media (orientation: portrait) {
        #grid { 
            display: grid;
            
            /* The rows, columns and cells of the grid are defined visually using the grid-template property.        */
            /* Each string is a row, and each letter a cell.  The max number of letters in any one string determines */
            /* the number of columns. */
            grid-template: "ta"
                           "sa"
                           "bb"
                           "cc";
            
            /* Columns and rows created with the template property can be assigned a sizing function with the */
            /* grid-columns and grid-rows properties. */
            grid-columns: auto minmax(min-content, 1fr); 
            grid-rows: auto auto minmax(min-content, 1fr) auto
        }
    }

    @media (orientation: landscape) {
        #grid { 
            display: grid;
            
            /* Again the template property defines cells of the same name, but this time positioned differently */
            /* to better suit a landscape orientation. */
            grid-template: "tb"
                           "ab"
                           "sc";
            
            grid-columns: auto minmax(min-content, 1fr); 
            grid-rows: auto minmax(min-content, 1fr) auto
        }
    }

    /* The grid-cell property places a grid item into named region (cell) of the grid. */
    #title    { grid-cell: "t" }
    #score    { grid-cell: "s" }
    #stats    { grid-cell: "a" }
    #board    { grid-cell: "b" }
    #controls { grid-cell: "c" }
</style>

<div id="grid">
    <div id="title">Game Title</div>
    <div id="score">Score</div>
    <div id="stats">Stats</div>
    <div id="board">Board</div>
    <div id="controls">Controls</div>
</div>

A note on the accessibility of content reordering

(This section is not normative.)

The facilities in this specification allow elements from a document to be displayed in a visual order that is to a large extent independent of the order in the document. That may have both positive and negative effects on accessibility. The positive aspect is that it allows the content in the document to be kept in logical order, so that the document is as functional as possible without the style sheet and on media where the style sheet doesn't apply. A negative aspect is that a document that has a defined tab order (the order in which elements get the focus when the tab-key is pressed) will show on the screen with a tab order unrelated to the visual order. It may be necessary to use the keyboard control features of the CSS Basic User Interface module [[CSS3UI]] to ensure that the tab navigation follows the visual order, or to refrain from positioning semantically related elements in different parts of a template.

The following two requirements from the Web Content Accessibility Guidelines (WCAG) 2.0 [[WCAG20]] are particularly relevant. See that specification for more information.

1.3.2 Meaningful Sequence: When the sequence in which content is presented affects its meaning, a correct reading sequence can be programmatically determined. (Level A)

2.4.3 Focus Order: If a Web page can be navigated sequentially and the navigation sequences affect meaning or operation, focusable components receive focus in an order that preserves meaning and operability. (Level A)

Grid Layering of Elements

FIXME

A control composed of layered HTML elements.

In the example shown in Figure 6, the author is creating a custom slider control. The control has six parts. The lower and upper labels align to the left and right edges of the control. The track of the slider spans the area between the labels. The lower and upper fill parts touch beneath the thumb, and the thumb is a fixed width and height that can be moved along the track by updating the two fraction-sized columns.

Prior to the grid element, the author would have likely used absolute positioning to control the top and left coordinates, along with the width and height of each HTML element that comprises the control. By leveraging the grid element, the author can instead limit script usage to handling mouse events on the thumb, which snaps to various positions along the track as the 'grid-columns' property of the grid element is updated.

<style type="text/css">
    #grid { 
        display: grid;

        /* The grid-columns and rows properties also support naming grid lines which can then be used */
        /* to position grid items.  The line names are assigned on either side of a column or row     */
        /* sizing function where the line would logically exist. */
        grid-columns:      
            "start"        auto 
            "track-start"  0.5fr 
            "thumb-start"  auto 
            "fill-split"   auto 
            "thumb-end"    0.5fr 
            "track-end"    auto
            "end";
    }

    /* Grid-column and grid-row accept a starting and optional endling line.  Below the lines are referred to by name. */
    /* Beyond any semantic advantage, the names also allow the author to avoid renumbering the grid-row and column     */
    /* properties of the grid items.  This is similar to the concept demonstrated in the prior example with the        */
    /* grid-template property during orientation changes, but grid lines can also work with layered grid items that    */
    /* have overlapping cells of different shapes like the thumb and track parts in this example. */
    #lower-label { grid-column: "start" }
    #track       { grid-column: "track-start" "track-end"; grid-row-align: center }
    #upper-label { grid-column: "track-end"; }
    
    /* Fill parts are drawn above the track so set z-index to 5. */
    #lower-fill  { grid-column: "track-start" "fill-split"; grid-row-align: center; z-index: 5 }
    #upper-fill  { grid-column: "fill-split" "track-end"; grid-row-align: center; z-index: 5 }
    
    /* Thumb is the topmost part; assign it the highest z-index value. */
    #thumb       { grid-column: "thumb-start" "thumb-end"; z-index: 10 }
</style>

<div id="grid">
    <div id="lower-label">Lower Label</div>
    <div id="upper-label">Upper Label</div>
    <div id="track">Track</div>
    <div id="lower-fill">Lower Fill</div>
    <div id="upper-fill">Upper Fill</div>
    <div id="thumb">Thumb</div>
</div>

Module interactions

Explain, normatively, how this module affects the definition of CSS.

This module replaces and extends the SUMMARIZE HERE features defined in [[!CSS21]] sections W.X and Y.Z.

See [[!CSS3PAGE]] for the definition of multi-column element.

[[!CSS3-WRITING-MODES]] defines the writing-mode property, which defines when elements have a vertical writing mode (text lines are vertical) or a horizontal writing mode (text lines are horizontal). For brevity, we refer to the former as a vertical element and to the latter as a horizontal element.

[[!CSS3BOX]] defines the intrinsic sizes of boxes.

Following [[!CSS3-WRITING-MODES]] and [[!CSS3BOX]], we define the inline dimension of a box, element or slot as meaning either its width or height, depending on whether it is horizontal or vertical, respectively. And likewise: the block dimension of a box, element or slot at a given inline dimension is its size in the perpendicular dimension.

'Direction' is defined in [[!CSS21]].

Values

This specification follows the CSS property definition conventions from [[!CSS21]]. Value types not defined in this specification are defined in CSS Level 2 Revision 1 [[!CSS21]]. Other CSS modules may expand the definitions of these value types: for example [[CSS3COLOR]], when combined with this module, expands the definition of the <color> value type as used in this specification.

In addition to the property-specific values listed in their definitions, all properties defined in this specification also accept the inherit keyword as their property value. For readability it has not been repeated explicitly.

Core Concepts of the Grid

FIXME

A diagram illustrating the relationship between the grid element and its Tracks, Lines, Cells and Items.

A grid element is declared in markup by setting the display property of an element to ''grid'' or ''inline-grid''.

Figure 7 illustrates the relationship between these concepts and the markup in the subsections that follow produce the result shown in the figure.

Grid track is the generic name in this specification for a row or column in a grid. Grid tracks are defined with the properties 'grid-rows' (to define rows) and 'grid-columns' (to define columns) on the grid element. Each track is defined by declaring a list of sizes, one size for each track.

<style type="text/css">
#grid { 
    grid-columns: 150px 1fr; /* two columns */
    grid-rows: 50px 1fr 50px /* three rows  */
}
</style>

Grid line is the term in this specification for the vertical edges of columns and the horizontal edges of rows. If there are N columns, their edges are numbered from 1 (the leftmost edge of the first column) to N+1 (the rightmost edge of the last column. Analogously for the edges of the rows.

A grid cell is the intersection of a row and a column. A grid with N columns and M rows has N*M cells.

Declaring a grid template

An element is a grid element (i.e., it defines a grid for its descendants) if its 'display' value is ''grid'' or ''inline-grid''.

The grid ancestor of an element is the nearest ancestor that is a grid element.

Name: display
Value: … | grid | inline-grid

This module adds the ''grid'' and ''inline-grid'' values to the 'display' property [[CSS21]], as defined below:

''grid''
A value of grid causes an element to display as a block-level grid element.
''inline-grid''
A value of inline-grid causes an element to display as an inline-level grid element.

Should grid elements be created automatically without using 'display'? On the one hand, this (a) is not consistent with how flex boxes are created and (b) could create some confusing dynamics (e.g., setting ''display: table'' or 'display: flexbox' removes any grid, but setting 'display: table-cell' or 'display: list-item' keeps the grid); but (1) requires only one instead of two properties to create a grid element, (2) allows other block container elements (such as table cells, table captions, list items, flex items…) to contain a grid, without extra keywords for 'display' ('table-cell-grid', 'list-item-grid'…), and (3) is consistent with how multicolumn elements are created.

Proposed text:

An element is a grid element (i.e., it defines a grid for its descendants) if it generates a a block container box [[!CSS21]] and one or more of the following is true:

These properties are defined below.

Block containers are, informally, elements that can have block elements as children, such as blocks, inline blocks or table cells, but not inline elements or replaced elements.

The number of columns of a grid element is defined as follows:

  1. If 'grid-template' is not 'none', it determines the number of columns.
  2. Otherwise, if 'grid-columns' is not 'auto', the number of columns is equal to the number of <track-size> values in 'grid-columns'.
  3. Otherwise, the grid has one column.

The number of rows of a grid element is defined as follows:

  1. If 'grid-template' is not 'none', it determines the number of rows.
  2. Otherwise, if 'grid-rows' is not 'auto', the number of rows is equal to the number of <track-size> values in 'grid-rows'.
  3. Otherwise, the grid has one row.

Alternative definition:

The number of columns is the number of <track-size> values in 'grid-columns' or the number of columns in 'grid-template', whichever is larger. (A value of ''none'' in this case means zero columns.)

The number of rows is the number of <track-size> values in 'grid-rows' or the number of rows in 'grid-template', whichever is larger. (A value of ''none'' in this case means zero rows.)

What if an element has both 'columns' and 'grid-template', is it a grid element or a column element? (or do the columns apply to the default slot?)

Use 'fr' unit (as in css3-grid-align) instead of '*' (as in css3-layout).

Grid Lines and Tracks

Image: Grid Lines.

Grid Lines.

grid elements use Grid Lines to divide their space. There are two sets of Grid Lines: one set defined by the columns parallel to the block flow dimension, and another orthogonal set defined by rows in the inline dimension.

A Grid Track is a generic term for the column or row between two Grid Lines. Each Grid Track is assigned a sizing function, which controls how wide or tall the column or row may grow, and thus how far apart two Grid Lines are. The sizing function specified can be a length, a percentage of the grid element's size, derived from the contents occupying the column or row, or a proportion of the space which remains in the grid element. In the last case, remaining space refers to the width or height of the grid element after accounting for space already consumed by columns and rows sized with a length, percentage or content. The size can also be specified as a range using a minmax function, which can combine any of the previously mentioned mechanisms to define a min and max size for the column or row.

In the following example there are two columns and three rows.  The first column is 150px wide beginning from the starting edge of the grid element's content box.  The second column uses fractional sizing, which is a function of the remaining space in the Grid.  Its size will vary as the width of the grid element changes.  If the used width of the grid element is 200px, then the second column 50px wide.  If the used width of the grid element is 100px, then the second column is 0px and any content positioned in the column will be overflowing the grid element.  Sizing occurs in a similar fashion for the rows.

<style type="text/css">
  #grid { 
    display: grid; 
    grid-columns: 150px 1fr;
    grid-rows: 50px 1fr 50px
  }
</style>

Declaring a template: 'grid-template'

The 'grid-template' property implicitly assigns a grid to an element and defines named slots in the grid. It can also designate a slot as the default slot, for unpositioned content.

Name: grid-template
Value: none | <string>+
Initial: none
Applies to: block container elements [[!CSS21]]
Inherited: no
Animatable: no
Percentages: N/A
Computed value: specified value
Canonical order: per grammar

Each string consist of one or more asterisks (“*”), letters, periods (“.”), spaces and tabs. Each string represents one row in the template, each symbol other than a space or tab represents one column in that row. Spaces and tabs have no meaning. They may be added for readability.

The symbols in the template have the following meaning

<letter>
Named slot for content
''*'' (asterisk)
Default slot for content (explained below).
. (period)
Blank space.

Multiple identical letters in adjacent rows or columns form a single slot that spans those rows and columns. Ditto for multiple “*”s. Slot names are case-sensitive, so uppercase and lowercase letters are considered to be different letters.

Non-rectangular slots and multiple slots with the same letter are illegal. A template without any letter or “*” is illegal. A template with more than one “*” slot is illegal. These errors cause the declaration to be ignored.

Note: non-rectangular and disconnected regions may be permitted in a future update of CSS.

Rows with fewer columns than other rows are implicitly padded with periods (“.”).

Each slot (letter or “*”) acts as a block element for its contents.

If the value is ''none'', then no explicit slots are defined. If the element is a grid element, then the element instead has an implicit template consisting of a single, anonymous slot. I.e., for a grid element with N columns and M rows, the implicit template is equivalent to M strings of N asterisks:

"******"
"******"

"******"

Note that an element is a grid element in this case if 'grid-columns' and 'grid-rows' are not both ''auto''.

Are grid templates logically oriented (relative to writing mode), or absolutely-oriented?

Specifying the widths of columns: 'grid-columns'

The 'grid-columns' property specifies the sizes of the columns of a grid.

Name: grid-columns
Value: auto | <track-size>+
Initial: auto
Applies to: block container elements [[!CSS21]]
Inherited: no
Animatable: yes, between grids with the same number of tracks
Percentages: N/A
Computed value: specified value
Canonical order: per grammar

Where

<track-size> = <length> | <percentage> | * | <fraction> |
  <minmax> | min-content | max-content | fit-content
<minmax> = minmax( <track-size> , <track-size> )
  

Each <track-size> sets the width of a column.

If an element has N columns, only the first N <track-size> values are used, the others are ignored. If there are fewer than N values, or if the value is 'auto', the missing ones are all '*' [or '1fr'].

Each <track-size> can be one of the following:

<length>
An explicit width for that column. Negative values are illegal.
<fraction>
(A non-negative number followed by 'fr'.) A fraction of the remaining space, see Fraction values below.
''*'' (asterisk)
All columns with a width of '*' have the same width.
<percentage>
Expresses a size as a percentage of the a-priori width. When the width of the grid element is dependent on content, the result is undefined.
''max-content''
''min-content''
The column's width is determined by its contents. See the algorithm below.
''minmax(p,q)''
The column's width is constrained to be greater than or equal to p and less than or equal to q. p and q stand for [ <length> | max-content | min-content | * ]. There may be white space around the p and q. If q < p, then q is ignored and ''minmax(p,q)'' is treated as 'minmax(p,p)'.
''fit-content''
Equivalent to 'minmax(min-content, max-content)'.

''fit-content'' is normally equivalent to max(min-content, max(max-content, fill-available)). This definition doesn't quite make sense here, but should the keyword be the same then? maybe ''auto''?

Which is easier, '1fr' or '*'? Or do we need both?
grid-template: "a . c";
grid-columns: 1fr 1em 3fr;
or
grid-template: "a . c c c";
grid-columns: * 1em * * *;

Do we need percentages? It seems in practice a fraction of the remaining space is all that is necessary.

Flex?

The following example:

div { grid-columns: 100px 1fr max-content minmax(min-content, 1fr) }

Additional examples of valid Grid Track definitions:

/* examples of valid track definitions */
grid-rows: 1fr minmax(min-content, 1fr);
grid-rows: 10px (1fr auto minmax(30%, 1fr))[2];
grid-rows: (10px);
grid-rows: calc(4em - 5px)

Specifying the height of rows: 'grid-rows'

Name: grid-rows
Value: auto | <track-size>+
Initial: auto
Applies to: block container elements [[!CSS21]]
Inherited: no
Animatable: yes, between grids with the same number of tracks
Percentages: N/A
Computed value: specified value
Canonical order: per grammar

The 'grid-rows' property specifies the sizes of the rows of a grid. It takes the same values as 'grid-columns'.

If an element has N rows, only the first N <track-size> values are used, the others are ignored. If there are fewer than N values, or if the value is 'auto', the missing ones are all 'fit-content'.

The 'grid' shorthand property

The 'grid' property is a shorthand for 'grid-template', 'grid-columns' and 'grid-rows'.

Name: grid
Value: none | [ [ <string> [ / <row-height> ]? ]+ ] <col-width>*
Initial: none
Applies to: block container elements [[!CSS21]]
Inherited: no
Animatable: see individual properties
Percentages: see individual properties
Computed value: see individual properties
Canonical order: N/A

The 'grid' property is a shorthand for 'grid-template', 'grid-rows' and 'grid-columns'. The value of 'grid-template' is the list of <string> values. The value of 'grid-rows' is the list of <row-height> values, with any omitted ones set to 'fit-content'. And the value of 'grid-columns' is the list of <col-width> values, or 'auto' if there are none.

For example, the rule

grid: "a b c" "a b d"/4em * 10em

is the same as

grid-template: "a b c" "a b d";
grid-rows: fit-content 4em;
grid-columns: * 10em;

Note the ''fit-content'' keyword that was implied in the shorthand, but must be made explicit in the 'grid-rows' property.

Note that it is not possible in the short hand to specify more row heights than here are rows, unlike in the 'grid-rows' property, where any number of extra (but ignored), row heights can be added at the end.

Default slots

Every grid element has a default slot. If there is an asterisk (“*”) in the template, then that slot is the default. If there is no asterisk, then the first letter in the template defines the default slot.

For example, if the template is defined by 'grid-template: "..." "..c" "abb" "abb"', then “c” is the default slot.

If the grid has an implicit template (i.e., 'grid-template' is ''none''), then the default slot is the single, anonymous slot of that implicit template.

All content of a grid element that is not inside another flow (e.g., because it is inside a float, absolutely positioned, or positioned in a different slot with '[grid-]position') is positioned in the default flow.

In particular, any text content of the grid element itself is positioned in the default flow.

For example, in this document fragment

<DIV STYLE="grid: 'ab*'">
 <IMG STYLE="flow: a" SRC="image.png" ALT="Foo">
 This is an
 <EM STYLE="flow: *">emphasized</EM>
 <EM STYLE="flow: b">(note well!)</EM>
 sentence.
 <
</DIV>

The three slots of the grid contain:

Slot a
The image
Slot b
The text “(note well!)”
Default slot
The text “This is an emphasized sentence.”

Fraction Values: 'fr'

Fraction values are new units applicable to the 'grid-rows' and 'grid-columns' properties:

fr
Fraction of available space.

The distribution of fractional space occurs after all <length> or content-based row and column sizes have reached their maximum. The total size of the rows or columns is then subtracted from the available space and the remainder is divided proportionately among the fractional rows and columns.

Each column or row's proportional share can be computed as the column or row's <fraction> * <remaining space> / <sum of all fractions>. Fractions occurring within a ''minmax()'' function are only counted in the sum if in the max position. Further, fractions that occur in the min position are treated as an absolute length of ''0''.

When remaining space cannot be determined because the width or height of the grid element is undefined, fraction-sized Grid Tracks are sized to their contents while retaining their respective proportions. In such cases the size of each fractional Grid Track can be computed by determining the ''max-content'' size of each fractional Grid Track and dividing that size by the respective fraction. The maximum value of those results is treated as the ''1fr'' value, which is then multiplied by each Grid Track's fraction to determine its final size.

''getComputedStyle()'' values for 'grid-rows' and 'grid-columns'

The resolved size of all Grid Tracks as returned for the 'grid-rows' and 'grid-columns' properties via ''getComputedStyle()'' is normalized to used pixel values.

All Grid Tracks are included in the computed value reported for 'grid-rows' and 'grid-columns' regardless of how the Grid Tracks were created, e.g. implicit tracks may be created by grid items referencing a Grid Line not explicitly defined by a 'grid-rows' or grid-columns' property.

Calculating the size of the grid

For the purpose of the calculations below, each slot (letter or “*”) in a grid has four dimensions associated with it, called MINW (“minimum width”), PREFW (“preferred width”), MINH (“minimum height”) and PREFH (“preferred height”). We can think of them as the minimum and preferred dimensions of the slot in isolation, i.e., if it wasn't constrained by other slots in the same row or column. They are defined as follows:

MINW
PREFW
MINH
PREFH

For example, the MINW values of the slots in this grid

grid: "    a      a      ."
      "    b      .      c"
      fit-content *    10em

are as follows:

a
'min-content' (because the slot spans at least one column with a width specified as 'min-content' or 'fit-content').
b
'min-content' (ditto).
c
0 (because the slot spans only columns with a width that is independent of the content).

The UA must choose the widths and heights of all columns and rows such that the following constraints are satisfied.

  1. If the element has an a-priori known content height, then the sum of the heights of all rows must be equal to the element's height.

    For example, the two rows in this grid must be 8em each so that the total height matches the height of the element:

    div {
      height: 16em;
      grid: "a.b" / *
            "ac." / * }
  2. If the grid element has an a-priori known content width, then the sum of the widths of all columns must be equal to the element's width .

    For example, the three columns in this grid must be 20em each:

    div {width: 60em; grid: "abc"}
  3. Each row with a height specified as a <length> must have exactly that height.
  4. Each column with a width specified as a <length> must have exactly that width.
  5. All rows with a height specified as '*' must have the same height.

    If we have both '*' and 'fr', then '*' will be defined as '1fr' and we can drop this rule and the next. Otherwise either these two rules or the next two must be removed.

  6. All columns with a width specified as '*' must have the same width.
  7. For any pair (i,j) of rows whose <row-height> values hi and hj are both specified in 'fr', the computed heights Hi and Hj must be such that Hi * hj = Hj * hi. (I.e., their heights are proportional to their number of 'fr' units.)
  8. For any pair (i,j) of columns whose <col-width> values wi and wj are both specified in 'fr', the computed width Wi and Wj must be such that Wi * wj = Wj * Wi. (I.e., their widths are proportional to their number of 'fr' units.)
  9. Each row that contains slots that span only one row and no slots that span more than one row, must not be higher than the largest PREFH of all slots in the row.

    For example, the third row in this grid

    grid: "a.c.." / 5em
          "a...."
          "....b"

    must not be taller than the height (block dimension) of slot b. The first row contains a slot that spans two rows (slot a), so this rule does not apply to that row.

  10. Each column that contains slots that span only one column and no slots that span more than one column, must not be wider than the largest PREFW of all slots in the column.

    For example, in this grid

    grid: "ac"
          "ab"
          fit-content *

    the first column must not be wider than the PREFW of slot a. Both slots in the second column have an infinite PREFW, so this rule effectively puts no constraint on that column.

  11. Each slot must be at least as wide as its MINW.
  12. Each slot must be at least as high as its MINH.

If it is impossible to choose such widths and heights, then try without constraint 1. If it is still impossible, try without constraint 2 instead. And, finally, try with both 1 and 2 dropped.

For example, the sum of the row heights in this example can never be the same as the height of the element:

div {
  height: 20em;
  grid: "a b c" / 7em
        "a . c" / 7em }

The first constraint is therefore ignored, the rows are 7em each and 6em of space below the grid remains empty.

If there are multiple solutions, and constraint 1 was dropped or did not apply, then the sizes must additionally be chosen such that the sum of the heights of the rows is minimized.

If there are still multiple solutions, and constraint 2 was dropped or did not apply, then the sizes must additionally be chosen such that the sum of the widths of the columns is minimized.

For example, there would be multiple solutions for this grid:

<DIV STYLE="float: left; grid: 'a.b'">
 <P STYLE="flow: a">Two words
 <P STYLE="flow: b">Only three words
</DIV>

The columns must have equal width, but there is no other constraint on the width. They could be narrow:

Two  
words
     
     
     
     
Only 
three
words

or wider:

Two words                       Only three words

or even wider still, e.g.:

Two words                             Only three words   

The rule to minimize height excludes the first, narrow solution. The rule to minimize width excludes the third and all wider solutions. So the second layout, the narrowest that has all words on one line, is the correct one.

(This example assumes the width of the floating DIV's containing block is large enough. The default width of a float is actually 'fit-content', and thus if the containing block is too narrow, the result will be narrower, too, because the calculation will have to be redone using that width as the a-priori width for the DIV.)

The width isn't known a-priori, if, e.g., 'width' is ''auto'' and the element is floating, absolutely positioned, inline-block or a child of a block with vertical writing mode.

An extra step may be necessary in paged media if a page break occurs inside a template (only in the case of an element-based template, see below). If the template, after computing the width and height, is too big to fit on the current page, and if a suitable break point exists, the part of the template after that break point is put on the next page. The width of the containing block on that page may be different if that page has different margins from the current page (see [[!CSS3PAGE]]) and thus the width and height of that part of the template must be recalculated in the new context.

Note that the widths of the columns can be completely determined before laying out any of the contents as long as there are no columns with a <col-width> of ''min-content'' or ''max-content''.

Do we define restrictions or approximations for slots that are part of a chain to avoid complicated optimization algorithms?

Note: In a future update of CSS, rows might get a property to specify how the height of that row is adjusted in case the above calculation yields a template that is less tall than the element itself.

The height of a slot is measured as if the slot had one anonymous block as a child that contains all the slot's contents and the anonymous block is a flow root (see [[!CSS3BOX]]).

This example divides the window in three rows and three columns, separated by 1em of white space. The middle row and the middle column are flexible, the others are fixed at a specific size. The first column is 5em wide, the last one 10em.

<style type="text/css">
  body {
    height: 100%;
    display: "a   .   b   .   c"  /2em
             ".   .   .   .   ."  /1em
             "d   .   e   .   f"
             ".   .   .   .   ."  /1em
             "g   .   h   .   i"  /2em
             5em 1em  *  1em 10em}
  #logo {position: a}
  #motto {position: b}
  #date {position: c}
  #main {position: e}
  #adv {position: f}
  #copy {position: g}
  #about {position: h}
</style>
<p id=logo><img src=...
<p id=motto>Making Web pages since 1862
<p id=date>August 2, 2004
...

[Add example with three columns, first two as narrow as possible, third one taking up all remaining space.]

Positioning content into a grid element

This section until the next subsection is not normative.

Grids can be used in two different ways to position content. The first way is to flow content into slots (either into explicit slots identified by letters, or the default slot “*”). Each slot is an individual flow root (“establishes a block formatting context” in the terminology of CSS level 2), very much like a table cell.

The second way is to absolutely position elements using four grid lines to specify the positions of the four margin edges of the element. As positioned elements [[!CSS21]], these elements can overlap each other and the 'z-index' property applies to them.

Flowing content into slots: 'flow'

The 'flow' property adds an element to a slot.

Name: flow
Value: auto | <identifier> | '*'
Initial: auto
Applies to: elements with 'position' equal to 'static' or 'relative'
Inherited: no
Animatable: no
Percentages: N/A
Computed value: specified value
Canonical order: per grammar

If the value is not 'auto', the element is added to the flow of the given slot, instead of to the flow of its parent.

If the element has no grid ancestor, or that grid ancestor has no slot of the given name, the effect is the same as for 'auto'.

If the letter refers to a slot that doesn't exist in the element's grid ancestor (or there is no grid ancestor) what is the effect?

  1. The element is not positioned (i.e., it is positioned in the current flow).
  2. The letter is looked for in the grid ancestor's own grid ancestor, etc., recursively. If no slot of that name is found in any of them, then the element is not positioned.
  3. The element is positioned in the default slot (i.e., as if '[grid-]position: *' had been specified); or not positioned at all, in case there is no grid ancestor.
  4. The letter is looked for in the grid ancestor's own grid ancestor, etc., recursively. If no slot of that name is found in any of them, then the element is positioned in the default slot.

All content flowed into the same slot, whether explicitly with 'flow' or implicitly by flowing into the default slot, forms a single flow, with content in document order. The slot establishes a block formatting context and becomes the containing block of the resulting content flow. The boxes of elements flowed into the same slot explicitly (by means of 'flow') are each others siblings in the slot.

The content flowed into a slot does not inherit properties from the slot.

For example, the style sheet

BODY {grid: "a." ".b"}
.paris {flow: a}
.london {flow: b}

with this document

<DIV CLASS=london>
 <P>The...
 <DIV CLASS=paris>
  <P>The...
  <DIV CLASS=london>
   <P>The...
  </DIV>
 </DIV>
</DIV>

causes the second and third DIVs to be taken out of their parents. The second DIV becomes the first child of slot a (i.e., of the pseudo-element called '::slot(a)'). The third DIV becomes the sibling of the first DIV, because both are added to slot b independently.

Note that 'flow' applies to floating elements: they are floated relative to their containing block, and if their 'flow' property indicates a slot in a grid, that slot is their containing block. See also “Floating elements inside templates” below.

What if the numbers refer to a non-existing row or column? Automatically created (see repeating below)? Ignored?

Absolute positioning using a grid: 'grid-column' and 'grid-row'

Trying to combine 'grid-row/column' and 'grid-row/column-span', because they should not cascade independently. (If one style rule tries to place by start/end lines, and another tries to place by span, the result of the cascade will be a mess.)

The 'grid-column' and 'grid-row' properties can be used to absolutely position an element relative to a grid.

Name: grid-row, grid-column
Value: auto | <identifier> | '*' | <grid-track>
Initial: auto
Applies to: elements with 'position: absolute'
Inherited: no
Animatable: no
Percentages: N/A
Computed value: specified value
Canonical order: per grammar

Here

<grid-track> = <integer> <integer>?
  

If the value of either or both of these properties is 'auto', the element is not positioned relative to a grid, but is positioned using 'top', 'right', 'bottom' and 'left' (see [[!CSS21]]).

If the value is an identifier or '*', the element is positioned such that its top and bottom margin edges (for 'grid-rows') or its left and right margin edges (for 'grid-columns') align with the corresponding margin edges of the slot of that name in the element's grid ancestor. ('*' refers to the default slot.) The 'top', 'right', 'bottom' and 'left' properties do not apply.

For example, these rules

DIV {grid: "ab" "cd"}
P {grid-row: a; grid-column: d}
   

mean that any P spans the same rows as slot a and spans the same columns as slot c. (In this case, that means it coincides with slot b.)

If the value is given as ''<grid-track>'' and the second number is omitted, it is equal to the first + 1.

If the value is given as ''<grid-track>'', the element is positioned such that its top and bottom margin edges (for 'grid-row') or left and right margin edges (for 'grid-column') align with the grid lines indicated by the two numbers. The 'top', 'right', 'bottom' and 'left' properties do not apply.

It is an error if the second number is less than the first, or if either number is zero.

Use negative number to count from the right/bottom?

Note that it is legal to specify the same edge twice, e.g. ''grid-rows: 1 1''. This simply makes a margin box with zero height.

If the element has no grid ancestor, or the value is a name that does not appear in its grid ancestor, or the value refers to grid lines that do not exist in the grid ancestor, then the effect is the same as if 'auto' had been specified.

This needs to be worked into the constraints for the calculation of the grid size, so that these absolutely positioned elements also contribute to the calculation of 'min-content' and 'max-content'.

Absolute positioning using a grid: 'top', 'right', 'bottom', 'right'

Instead of introducing properties 'grid-column' and 'grid-row' that override 'top', 'right', 'bottom' and 'right', it might be better to extend those properties.

Name: top, right, bottom, left
Value: <identifier> | '*' | <integer>

The new values for these properties refer to grid lines of the element's grid ancestor as follows:

An identifier or '*' refers to an edge of the slot of that name: the top edge if used on 'top', the right edge if used on 'right', the bottom edge if used on 'bottom', and the left edge if used on 'left'. ('*' refers to the default slot.)

For example, these rules

DIV {grid: "ab"
           "cd"}
P {position: absolute; top: a; left: d}

mean that any P is positioned with its top at the top of the first row and its left at the left of the second column, i.e., at the top left corner of slot b. In other words, the declarations 'top: b; left: b' would have meant the same thing.

This example positions all four sides of an element at grid lines, so that the element will exactly overlap a given slot. (This assumes 'width' and 'height' have their default value of ''auto'.)

DIV {grid: "aaa"
           "bbb"}
DIV H2 {position: absolute; top: a; right: a;
  bottom: a; left: a}

A number value refers to row grid lines (on 'top' and 'bottom') or to column grid lines (on 'left' and 'right').

Use negative number to count from the right/bottom? Then 'left: 1; right: -1' would make the element as wide as the grid, no matter how many columns it had.

A number '0' is an error.

If the value refers to a slot or grid line that does not exist in the grid ancestor, or if there is no grid ancestor, the value is treated as ''auto''.

The 'grid-position' shorthand property

Name: grid-position
Value: auto | <identifier> | '*' | <grid-track> / <grid-track>
Initial: auto
Applies to: elements with 'position: absolute'
Inherited: no
Animatable: no
Percentages: N/A
Computed value: specified value
Canonical order: per grammar

This is a shorthand for 'grid-column' and 'grid-row'. The values have the following meaning:

''auto''
Same as setting 'grid-column' and 'grid-row' both to auto.
<identifier>
Same as setting 'grid-column' and 'grid-row' both to this value.
''*''
Same as 'grid-column' and 'grid-row' both to '*'.
<grid-track> / <grid-track>
Same as setting 'grid-column' to the value before the slash ('/') and 'grid-row' to the value after the slash.

Note that some combinations cannot be expressed in the shorthand, e.g., 'grid-column: a; grid-row: b'. On the other hand, 'grid-column: auto; grid-row: b' is the same as 'grid-position: auto'

It is also possible to re-use 'position' instead of a new 'grid-position' property. Advantage: no new property to learn. Disadvantage: difficult to make 'position' into a shorthand for 'grid-column' and 'grid-row'.

css3-grid-align allows to define a position either by saying how many rows/columns it spans, or by saying at which row and column it ends. Some possible interpretations of four numbers:

  1. ''1 5 / 3 4'' = start at column 1 row 3, span 5 columns and 4 rows
    . . . . . . .
    . . . . . . .
    x x x x x . .
    x x x x x . .
    x x x x x . .
    x x x x x . .
    . . . . . . .
    
  2. ''1 to 5 / 3 to 4'' = start at column 1 row 3, end with column 5 row 4
    . . . . . . .
    . . . . . . .
    x x x x x . .
    x x x x x . .
    . . . . . . .
    . . . . . . .
    . . . . . . .
    
  3. ''1 to 5 / 3 to 4'' = start at column 1 row 3, end before column 5 row 4
    . . . . . . .
    . . . . . . .
    x x x x . . .
    . . . . . . .
    . . . . . . .
    . . . . . . .
    . . . . . . .
    

Do we need only one? Which one is the easiest to remember?

Do we need keywords such as ''same'' (position into same slot as the preceding element with the same grid ancestor), ''next-row'' (position into the next slot below the preceding element with the same grid ancestor), ''next-column'; or ''next''?

Floating elements inside templates

An element may be positioned inside a template (with 'flow') and be a floating element ('float' property) at the same time. The following cases must be distinguished:

Page floats

For the purpose of page floats [[!CSS3PAGE]], the slot acts as a page.

For example, if an element has 'float: top', it floats to the top of the slot (or the top of the current column, if it has a multicolumn element as ancestor that is nearer than its grid ancestor).

Other floats

In other cases, the element floats normally within its containing block, which in this case is its slot in the template (as defined above).

Styling named slots: the ''::slot()'' pseudo-element

The slots of a grid element can be individually addressed with the ''::slot()'' pseudo-element.

For example, the following sets the background color and vertical alignment of some of the slots in a template:

body { grid: "aaa"
             "bcd" }
body::slot(b) { background: #FF0 }
body::slot(c), body::slot(d) { vertical-align: bottom }

The ''::slot()'' pseudo-element can also be used to create slots that overlap with other slots?

For example, the following creates a slot that overlaps two other slots. The slot z starts at the top left and is one column wide and two rows high, overlapping the left third of the a slot and the whole of the b slot.

body { grid: "aaa"
             "bcd" }
body::slot(foo) { position: 1 1 / 1 2 }

If a '::slot()' pseudo-element refers to a name that already exists in the element's grid template, than any 'position' property on that pseudo-element is ignored.

If a '::slot()' pseudo-element defines a new slot that coincides exactly with another slot in the element's grid element, then it is in fact the same slot, and the new name is an alias for that slot. Unless it has a different 'z-index'? Or are slots independent, even if they have the same position?

Only the following properties apply to the '':slot()'' pseudo-element:

The background of a slot is drawn immediately on top of the background of the element itself. E.g., the background set on ''P::slot(a)'' is immediately in front of the background set on ''P''.

Need to define the width when a slot has padding and border, including when the width is too small.

Do the margins of a slot collapse with the margins of elements that are flowed into the slot?

Layout within a slot

Can use the margins of the '::slot()'' pseudo, or re-use the 'vertical-align' property (bottom, top, middle, baseline), or a new property ('flex-align'?) [Using 'margin' means there needs to be another property if baseline alignment is required.]

FIXME

Latin-based language row and column orientation.

FIXME

Arabic language row and column orientation.

FIXME

East Asian language row and column orientation.

A grid item's alignment within its Cell can be controlled by using the 'grid-column-align' and 'grid-row-align' properties. Alignment refers to the logical edges of the grid item's slot.

The start edge of a column is defined by the inline base direction. The start edge of a row is defined by block flow direction. The alignment values refer to the edge of the grid item's slot against which the grid item will align one of its edges. Which edge of the grid item actually aligns against the specified edge of the Cell is dependent on whether the grid item shares the same inline text direction and block flow direction as the grid element. All descriptions below assume that the grid item shares the same inline text direction and block flow direction as the grid element. Refer to the CSS Writing Modes Module Level 3 for more details about the relationship between parent and child elements with differing writing-modes, and for the definitions of inline direction and block flow direction. [[!CSS3-WRITING-MODES]]

The next three figures illustrate the placement and orientation of the grid element's rows, columns, and grid items using different writing modes on the grid element. In each of the figures, the markup shown in the following example is used to place grid item A in column 1, row 1, and grid item B in column 2, row 2. Grid item A is aligned in each figure to the starting edges of its row and column. Grid item B is aligned in each figure to the ending edges of its row and column.

<style type="text/css">
    #grid { display: grid; grid-columns: 1fr 1fr; grid-rows: 1fr 1fr }
    #A { grid-column: 1; grid-row: 1; grid-column-align: start; grid-row-align: start }
    #B { grid-column: 2; grid-row: 2; grid-column-align: end; grid-row-align: end }
</style>

<div id="grid">
    <div id="A">A</div>
    <div id="B">B</div>
</div>

Alignment

We need a general way to align and center content and elements in a fixed-size parent. The Positioning module proposes 'position: center', but it only applies to absolutely positioned elements and it only centers. ''Auto'' margins are limited to aligning horizontally and they fail to center when the element is wider than its parent. 'Vertical-align' applies to table cells and could apply to slots (and it has a useful ''baseline'' value), but only aligns vertically. 'Text-align: center' fails to center when there is a float next to the line box…

Name: grid-column-align
Value: 'start' | 'end' | 'center' | 'stretch'
Initial: 'stretch'
Applies to: Grid Item elements
Inherited: no
Percentages: n/a
Computed value: specified value
''start''
Aligns the starting edge of the grid item's margin box to the starting edge of the grid item's column.
''end''
Aligns the end edge of the grid item's margin box to the end edge of the grid item's column.
''center''
Places the center of the grid item's margin box at the center of the the grid item's column.
''stretch''
Ensures that the grid item's margin box is equal to the size of the grid item's column.
Name: grid-row-align
Value: 'start' | 'end' | 'center' | 'stretch'
Initial: 'stretch'
Applies to: Grid Item elements
Inherited: no
Percentages: n/a
Computed value: specified value
''start''
Aligns the starting edge of the grid item's margin box to the starting edge of the grid item's row.
''end''
Aligns the end edge of the grid item's margin box to the end edge of the grid item's row.
''center''
Places the center of the grid item's margin box at the center of the the grid item's row.
''stretch''
Ensures that the grid item's margin box is equal to the size of the grid item's row.

Calculating the Size of Grid Items

The values ''start'', ''end'', and ''center'' all cause the grid item to produce a box sized shrink-to-fit for its cell in accordance with the CSS3 Box Model. Note that percentage lengths specified on a grid item resolve against the dimensions of the grid slot (i.e. the slot serves as the containing block for the grid item). Percentages specified for margin-top, padding-top, margin-bottom, and padding-bottom resolve against the height of the grid cell, rather than the width of the grid slot. If the min-content size of the grid item's box is greater than the size of its slot, it will overflow the bounds of its slot in a direction determined by its alignment.

A value of ''stretch'' causes the grid item's to take the fill-available size. Note that this calculation is symmetric for both the width and height of the grid item.

Vertical alignment

The 'vertical-align' property of a '::slot()' pseudo-element can be used to align content vertically in a slot. We assume the content of a slot is wrapped in an anonymous block box (similar to the cell box in a table cell, see [[!CSS21]]). That box is aligned inside the slot according to the value of 'vertical-align':

bottom
The content of the slot is aligned to the bottom of the slot: the bottom margin edge of the anonymous block coincides with the bottom of the slot.
middle
The content of the slot is vertically centered in the slot: the distance between the top margin edge of the anonymous block and the top of the slot is equal to the distance between the bottom margin edge of the anonymous block and the bottom of the slot. (Note that if the content overflows the slot, it will overflow both at the top and at the bottom.)
baseline
The anonymous block that encloses the content is placed as high as possible under two constraints:
  1. The top margin edge of the anonymous block may not be higher than the top edge of the slot.
  2. The topmost baseline in the content may not be higher than the topmost baseline of content in any other slot in the same row that also has 'vertical-align: baseline'. Baselines of content inside floats are not taken into account. Slots that span several rows are considered to occur in their topmost row.

For all other values, the content is top aligned: the top margin edge of the anonymous box coincides with the top edge of the slot.

Conformance

Document conventions

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [[!RFC2119]]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

Conformance classes

Conformance to CSS TEMPLATE Module is defined for three conformance classes:

style sheet
A CSS style sheet.
renderer
A UA that interprets the semantics of a style sheet and renders documents that use them.
authoring tool
A UA that writes a style sheet.

A style sheet is conformant to CSS TEMPLATE Module if all of its statements that use syntax defined in this module are valid according to the generic CSS grammar and the individual grammars of each feature defined in this module.

A renderer is conformant to CSS TEMPLATE Module if, in addition to interpreting the style sheet as defined by the appropriate specifications, it supports all the features defined by CSS TEMPLATE Module by parsing them correctly and rendering the document accordingly. However, the inability of a UA to correctly render a document due to limitations of the device does not make the UA non-conformant. (For example, a UA is not required to render color on a monochrome monitor.)

An authoring tool is conformant to CSS TEMPLATE Module if it writes style sheets that are syntactically correct according to the generic CSS grammar and the individual grammars of each feature in this module, and meet all other conformance requirements of style sheets as described in this module.

Partial implementations

So that authors can exploit the forward-compatible parsing rules to assign fallback values, CSS renderers must treat as invalid (and ignore as appropriate) any at-rules, properties, property values, keywords, and other syntactic constructs for which they have no usable level of support. In particular, user agents must not selectively ignore unsupported component values and honor supported values in a single multi-value property declaration: if any value is considered invalid (as unsupported values must be), CSS requires that the entire declaration be ignored.

Experimental implementations

To avoid clashes with future CSS features, the CSS2.1 specification reserves a prefixed syntax for proprietary and experimental extensions to CSS.

Prior to a specification reaching the Candidate Recommendation stage in the W3C process, all implementations of a CSS feature are considered experimental. The CSS Working Group recommends that implementations use a vendor-prefixed syntax for such features, including those in W3C Working Drafts. This avoids incompatibilities with future changes in the draft.

Non-experimental implementations

Once a specification reaches the Candidate Recommendation stage, non-experimental implementations are possible, and implementors should release an unprefixed implementation of any CR-level feature they can demonstrate to be correctly implemented according to spec.

To establish and maintain the interoperability of CSS across implementations, the CSS Working Group requests that non-experimental CSS renderers submit an implementation report (and, if necessary, the testcases used for that implementation report) to the W3C before releasing an unprefixed implementation of any CSS features. Testcases submitted to W3C are subject to review and correction by the CSS Working Group.

Further information on submitting testcases and implementation reports can be found from on the CSS Working Group's website at http://www.w3.org/Style/CSS/Test/. Questions should be directed to the public-css-testsuite@w3.org mailing list.

CR exit criteria

[Change or remove the following CR exit criteria if the spec is not a module, but, e.g., a Note or a profile. This text was decided on 2008-06-04.]

For this specification to be advanced to Proposed Recommendation, there must be at least two independent, interoperable implementations of each feature. Each feature may be implemented by a different set of products, there is no requirement that all features be implemented by a single product. For the purposes of this criterion, we define the following terms:

independent
each implementation must be developed by a different party and cannot share, reuse, or derive from code used by another qualifying implementation. Sections of code that have no bearing on the implementation of this specification are exempt from this requirement.
interoperable
passing the respective test case(s) in the official CSS test suite, or, if the implementation is not a Web browser, an equivalent test. Every relevant test in the test suite should have an equivalent test created if such a user agent (UA) is to be used to claim interoperability. In addition if such a UA is to be used to claim interoperability, then there must one or more additional UAs which can also pass those equivalent tests in the same way for the purpose of interoperability. The equivalent tests must be made publicly available for the purposes of peer review.
implementation
a user agent which:
  1. implements the specification.
  2. is available to the general public. The implementation may be a shipping product or other publicly available version (i.e., beta version, preview release, or “nightly build”). Non-shipping product releases must have implemented the feature(s) for a period of at least one month in order to demonstrate stability.
  3. is not experimental (i.e., a version specifically designed to pass the test suite and is not intended for normal usage going forward).

The specification will remain Candidate Recommendation for at least six months.

Acknowledgments

[acknowledgments]

References

Normative references

Other references

Index

Property index