Copyright © 2010 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
CSS Grid Alignment Level 3 contains features that enable authors to align UI elements horizontally and vertically. By using the features in this module authors can position layout elements such as controls and application content into columns and rows, defining a grid structure with fixed, fractional, or automatic units. The elements can then be positioned and sized into the logical cells of the grid. Further, this module enables stacking and spanning of elements to build cohesive experiences out of a collection of modular UI pieces.
CSS Grid Alignment Level 3 also helps to manage changes in available space for layout. For example, the features in this module can help manage changes by allowing placement of elements in the grid independent of source order. Such management may be required when a browser window is resized or when a screen's aspect ratio changes, due to screen rotation.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This document was published by the CSS Working Group as an Editor's Draft. If you wish to make comments regarding this document, please send them to www-style@w3.org (subscribe, archives). All feedback is welcome.
Publication as a Editor's Draft does not imply endorsement by the W3C Membership. This is a draft document and 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.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
This CSS3 module depends on the following other CSS3 modules:
This CSS3 module has normative references to the following other CSS3 modules:
This CSS3 module has non-normative (informative) references to the following other CSS3 modules:
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 layout of applications. By using a combination of tables, JavaScript, or careful measurements on floated elements, authors discovered workarounds to achieve a desired layout. 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.
CSS Grid Alignment Level 3 provides layout capabilities to address these problems. The Grid element provides a mechanism for authors to divide available space for layout into regions by using a set of predictable sizing behaviors which are assigned to the columns and rows of the Grid. The regions defined by the columns and rows serve as anchor points for the author to place the building block elements of their application. These anchor points maintain their positions relative to other anchors in accordance with the sizing behaviors that the author assigned to the columns and rows of the Grid element. Figure 1 illustrates a basic layout of a Grid.
Five grid items arranged according to content size and available space.
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 allows the author to achieve all the sizing, placement, and alignment rules declaratively.
<style type="text/css"> #grid { grid-columns: auto minmax(min-content, 1fr); grid-rows: auto minmax(min-content, 1fr) auto } #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: 2; 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>
An arrangement suitable for 'portrait' orientation.
An arrangment suitable for 'landscape' orientation.
Continuing the prior example, the author also wants the game to be as enjoyable as possible for traditional computer monitors, handheld devices, or tablet computers. The game should therefore 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, the author is able to use the same HTML markup, but rearranged independent of its source order, to achieve the desired layout in both landscape and portrait modes. The following example shows the markup that achieves optimization for the different screen orientations.
<style type="text/css"> @media (orientation: landscape) { #grid { grid-columns: auto minmax(min-content, 1fr); grid-rows: auto minmax(min-content, 1fr) auto } #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: 2; grid-column-align: center } } @media (orientation: portrait) { #grid { grid-columns: auto minmax(min-content, 1fr); grid-rows: auto auto minmax(min-content, 1fr) auto } #title { grid-column: 1; grid-row: 1 } #score { grid-column: 1; grid-row: 2 } #stats { grid-column: 2; grid-row: 1; grid-row-span: 2 } #board { grid-column: 1; grid-row: 3; grid-column-span: 2 } #controls { grid-column: 1; grid-row: 4; grid-column-span: 2; 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>
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.
The z-index
CSS property would have been used to control element drawing order.
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-column
CSS property of the Grid element is updated.
The Grid element's grid-layer
CSS property provides capabilities which are analagous to z-index
.
<style type="text/css"> #grid { grid-columns: auto 0.5fr auto auto 0.5fr auto } #lower-label { grid-column: 1; grid-row-align: center } #upper-label { grid-column: 6; grid-row-align: center } #track { grid-column: 2; grid-row-align: center} #lower-fill { grid-column: 2; grid-column-span: 2; grid-row-align: center; grid-layer: 5 } #upper-fill { grid-column: 4; grid-column-span: 2; grid-row-align: center; grid-layer: 5 } #thumb { grid-column: 3; grid-column-span: 2; grid-layer: 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>
A Grid element is declared by setting the display property.
Name: | display |
Value: | [ ...existing values... | grid | inline-grid | |
Computed value: | specified value |
Grid Items are elements placed into the Grid element and which would have been considered a block-level element in the normal flow. All children of Grid elements are block-level. If inline-level elements are nested inside grids, they get wrapped in an anonymous block which then takes part in the grid layout.
The wrapping behavior for anonymous blocks is intended to match that of the Flexible Box Layout Module (work in progress). [FLEXBOX]
The integer values specified with the grid-column
and grid-row
properties on a Grid Item element are not required to refer to a column or row that was defined
by using the grid-columns
or grid-rows
properties
on the Grid element.
Similarly, grid-column-span
and grid-row-span
properties
may not refer to an explicit definition.
In cases where the specified column or row position is outside those explicitly specified on the Grid element,
implicit auto-sized columns and rows are added as needed, including all those spanned by the Grid Item.
The following example produces two Grid Items: the first Grid Item is created by the anonymous block box
wrapping the anonymous inline box for A
and the following <span>
; the second Grid Item is created by the C
<div>
.
<div style="display:grid;">A<span>B</span><div>C</div></div>
Grid Items are placed into a Grid element by using its rows and columns as a coordinate system.
Rows and columns may be explicitly defined for the Grid element by using the grid-rows
and grid-columns
properties.
Each row or column is expressed as a distance from the previous row or column.
The distance may be an absolute length or relative value.
Relative values are relative to the intrinsic size of the row or column's contents.
The distance may also be expressed as an acceptable range of sizes using a minmax
function.
Each distance value defines a row or column which can be referred to by a number in accordance with its position in the list. The first distance value specified defines a row or column 1, the second 2, and so on.
Name: | grid-columns |
Value: |
[ 'auto' | <length> | <fraction> | 'min-content' | 'max-content' |
'fit-content' | <minmax> ]+ | none |
Initial: | none |
Applies to: | non-replaced block-level elements |
Inherited: | no |
Percentages: | n/a |
Media: | visual, paged |
Computed value: | see text |
Name: | grid-rows |
Value: |
[ 'auto' | <length> | <fraction> | 'min-content' | 'max-content' |
'fit-content' | <minmax> ]+ | none |
Initial: | none |
Applies to: | non-replaced block-level elements |
Inherited: | no |
Percentages: | n/a |
Media: | visual, paged |
Computed value: | see text |
fraction
value takes a share of the remaining space proportional to
its number. See fraction values.min
and less than or equal to max
, where min
and max
may be one of the following: [ <length> | 'max-content' | 'min-content' | <fraction> ].
There may be white space around min
and max
. If max
< min
,
then max
is ignored and minmax(min,max)
is treated as minmax(min,min)
.minmax(min-content, max-content)
.fit-content
.The following example:
div { grid-columns: 100px 1fr max-content minmax(min-content, 1fr) }
Fraction values are new units applicable to the grid-rows and grid-columns properties:
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>
.
Note that 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 0px
.
Four Grid Items sized according to markup shown in Example VII.
Grid Items are placed into a space in the Grid element defined by four properties:
grid-row
, grid-column
, grid-row-span
, and grid-column-span
.
The four properties define a rectangular region referred to as the Grid Item's Cell.
The width of the Grid Item's Cell is defined as the sum of the width of column i
through j
;
where i
is the value specified by grid-column
and j
is i
plus the value specified by
grid-column-span - 1
.
The height of the Grid Item's Cell can be determined in the same fashion by using the height of the
grid rows referred to by the grid-row
and grid-row-span
properties.
The Grid Item's Cell defines an origin for the Grid Item within the Grid element, and can affect the size of the Grid Item's box depending on the values of the Grid Item's alignment properties. See Grid Item Alignment for more details.
The float
and clear
properties do not apply to grid items.
The markup shown in the following example produces four Grid Items having the following sizes, as shown in Figure 7.
<style type="text/css"> #grid { grid-columns: 20px 30px 20px; grid-rows: 20px 30px } #A { grid-column: 1; grid-row: 1 } #B { grid-column: 2; grid-row: 1 } #C { grid-column: 3; grid-row: 1; grid-row-span: 2 } #D { grid-column: 1; grid-row: 2; grid-column-span: 2 } </style> <div id="grid"> <div id="A">A</div> <div id="B">B</div> <div id="C">C</div> <div id="D">D</div> </div>
Name: | grid-column |
Value: | <integer> |
Initial: | 1 |
Applies to: | Grid Item elements |
Inherited: | no |
Percentages: | n/a |
Media: | visual, paged |
Computed value: | specified value |
Name: | grid-row |
Value: | <integer> |
Initial: | 1 |
Applies to: | Grid Item elements |
Inherited: | no |
Percentages: | n/a |
Media: | visual, paged |
Computed value: | specified value |
Name: | grid-column-span |
Value: | <integer> |
Initial: | 1 |
Applies to: | Grid Item elements |
Inherited: | no |
Percentages: | n/a |
Media: | visual, paged |
Computed value: | specified value |
Name: | grid-row-span |
Value: | <integer> |
Initial: | 1 |
Applies to: | Grid Item elements |
Inherited: | no |
Percentages: | n/a |
Media: | visual, paged |
Computed value: | specified value |
A Grid with an implicit row and two implicit columns.
The <integer>
values specified with the grid-column
and
grid-row
properties
on a Grid Item element are not required to refer to a column or row that was defined using the
grid-columns
or grid-rows
properties
on the Grid element.
Similarly, grid-column-span
and grid-row-span
properties may not refer to an explicit definition.
In cases where the specified column or row position is outside those explicitly specified on the Grid element,
implicit auto-sized columns and rows are added as needed, including all those spanned by the Grid Item.
Figure 8 illustrates the placement of Grid Items resulting from the markup shown in the following example. Note that Grid Item 'B' defines its placement in column 5. Columns 3 and 4 are implicit auto-width columns without content resulting in a used column width of 0px.
grid-columns
and grid-rows
on the Grid element.
<style type="text/css"> #grid { grid-columns: 20px; grid-rows: 20px } #A { grid-column: 1; grid-row: 1; grid-column-align: start; grid-row-align: start } #B { grid-column: 5; grid-row: 1; grid-row-span: 2; } #C { grid-column: 1; grid-row: 2; grid-column-span: 2; } </style> <div id="grid"> <div id="A">A</div> <div id="B">B</div> <div id="C">C</div> </div>
Latin-based language row and column orientation.
Arabic language row and column orientation.
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 Cell.
The start
edge of a column is defined by the text flow 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 Cell 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. [CSS3WRITINGMODES]
Figures 9, 10, and 11 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 { 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>
Name: | grid-column-align |
Value: | 'start' | 'end' | 'center' | 'stretch' |
Initial: | 'stretch' |
Applies to: | Grid Item elements |
Inherited: | no |
Percentages: | n/a |
Media: | visual, paged |
Computed value: | specified value |
Name: | grid-row-align |
Value: | 'start' | 'end' | 'center' | 'stretch' |
Initial: | 'stretch' |
Applies to: | Grid Item elements |
Inherited: | no |
Percentages: | n/a |
Media: | visual, paged |
Computed value: | specified value |
The values start
, end
, and center
all cause the Grid Item
to produce a box sized shrink-to-fit for its cell.
If the min-content
size of the Grid Item's box is greater than the size of its Cell,
it will overflow the bounds of its Cell in a direction determined by its alignment.
A value of stretch
causes the Grid Item's box model to shrink or grow to satisfy the following equations:
margin-left + border-left + content-width + border-right + margin-right = <cell width>
margin-top + border-top + content-height + border-bottom + margin-bottom = <cell height>
When stretching a Grid Item box, negative margins can produce a box which is larger than the Grid Item's Cell.
Also, stretching can produce a Grid Item box that is smaller than the min-content
size of the Grid Item.
In such cases the contents of the Grid Item element will overflow its box in accordance with its overflow
property.
Drawing order controlled by grid-layer and source order.
Grid Items do not directly affect each other's placement in the Grid element. A Grid Item may affect the position of a Grid line in a column or row that uses a contents-based relative size, which in turn affects the position or size of another Grid Item, but there is no direct interaction between Grid Items. Grid Items may overlap because the Grid Item's Cell is defined to intersect with the Cell of another Grid Item. Grid Item boxes in non-intersecting Cells may also overlap because of negative margins.
In cases where boxes overlap, a new property, grid-layer
, is introduced to provide control over the drawing order of Grid Items.
Grid-layer is similar in concept to z-index
, but avoids overloading the meaning of the z-index
property,
which is applicable only to positioned elements.
In cases where Grid Items occupy the same grid-layer, source order determines which item will be drawn first.
Figure 12 illustrates the drawing order of the markup shown in the following example.
<style type="text/css"> #grid { grid-columns: 1fr 1fr; grid-rows: 1fr 1fr } #A { grid-column: 1; grid-row: 2; grid-column-span: 2; grid-row-align: end } #B { grid-column: 1; grid-row: 1; grid-layer: 10 } #C { grid-column: 1; grid-row: 1; grid-row-align: start; margin-left: -20px } #D { grid-column: 2; grid-row: 2; grid-column-align: end; grid-row-align: start } #E { grid-column: 1; grid-row: 1; grid-column-span: 2; grid-row-span: 2; grid-layer: 5; grid-column-align: center; grid-row-align: center } </style> <div id="grid"> <div id="A">A</div> <div id="B">B</div> <div id="C">C</div> <div id="D">D</div> <div id="E">E</div> </div>
Name: | grid-layer |
Value: | <integer> |
Initial: | 0 |
Applies to: | Grid Item elements |
Inherited: | no |
Percentages: | n/a |
Media: | visual, paged |
Computed value: | specified value |
This specification is made possible by input from Kathy Kam, Chris Jones, Erik Anderson, and Eugene Veselov. Thanks to Eliot Graff for editorial input.