Fri, 28 Feb 2014 16:25:03 -0800
[css-grid] Add the translated layout algo too.
jackalmage@8856 | 1 | <h1>CSS Grid Layout Module Level 1</h1> |
jackalmage@8856 | 2 | |
jackalmage@8856 | 3 | <pre class='metadata'> |
bert@9771 | 4 | Status: ED |
jackalmage@9500 | 5 | Shortname: css-grid |
jackalmage@9500 | 6 | Level: 1 |
jackalmage@9500 | 7 | Group: csswg |
jackalmage@8856 | 8 | ED: http://dev.w3.org/csswg/css-grid/ |
bert@9770 | 9 | TR: http://www.w3.org/TR/css-grid-1/ |
jackalmage@9432 | 10 | Previous version: http://www.w3.org/TR/2013/WD-css3-grid-layout-20130402/ |
jackalmage@9432 | 11 | Previous version: http://www.w3.org/TR/2012/WD-css3-grid-layout-20121106/ |
jackalmage@8856 | 12 | Editor: Tab Atkins Jr., Google, http://www.xanthir.com/contact/ |
jackalmage@8856 | 13 | Editor: fantasai, Mozilla, http://fantasai.inkedblade.net/contact |
jackalmage@8856 | 14 | Editor: Rossen Atanassov, Microsoft, ratan@microsoft.com |
jackalmage@9369 | 15 | Former editor: <a href="mailto:alexmog@microsoft.com">Alex Mogilevsky</a>, Microsoft Corporation |
jackalmage@9369 | 16 | Former editor: <a href="mailto:pcupp@microsoft.com">Phil Cupp</a>, Microsoft Corporation |
jackalmage@9369 | 17 | !Issues list: <a href="https://www.w3.org/Bugs/Public/buglist.cgi?product=CSS&component=Grid+Layout&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED">In Bugzilla</a> |
jackalmage@8856 | 18 | Abstract: This CSS module defines a two-dimensional grid-based layout system, optimized for user interface design. In the grid layout model, the children of a grid container can be positioned into arbitrary slots in a flexible or fixed predefined layout grid. |
fantasai@10071 | 19 | Ignored Terms: containing block, <positive-integer>, <ident>, auto, grid-*-start, grid-*-end, flex factor, flex factors |
jackalmage@8932 | 20 | Link Defaults: css21 (property) margin, css-align-3 (dfn) alignment container/alignment subject |
jackalmage@9440 | 21 | At Risk: the ''grid-template-rows/subgrid'' value of 'grid-template-columns' and 'grid-template-rows', and its component parts individually |
jackalmage@8856 | 22 | </pre> |
jackalmage@8856 | 23 | |
jackalmage@8856 | 24 | <style type="text/css"> |
jackalmage@8856 | 25 | .example { |
jackalmage@8856 | 26 | clear:both |
jackalmage@8856 | 27 | } |
jackalmage@8856 | 28 | |
jackalmage@8856 | 29 | .pseudo-code { |
jackalmage@8856 | 30 | font-family:monospace |
jackalmage@8856 | 31 | } |
jackalmage@8856 | 32 | .pseudo-code > ol { |
jackalmage@8856 | 33 | list-style-type:decimal |
jackalmage@8856 | 34 | } |
jackalmage@8856 | 35 | .pseudo-code > ol > li > ol { |
jackalmage@8856 | 36 | list-style-type:lower-latin |
jackalmage@8856 | 37 | } |
jackalmage@8856 | 38 | .pseudo-code > ol > li > ol > li > ol { |
jackalmage@8856 | 39 | list-style-type:lower-roman |
jackalmage@8856 | 40 | } |
jackalmage@8856 | 41 | .pseudo-code ul { |
jackalmage@8856 | 42 | list-style-type:disc |
jackalmage@8856 | 43 | } |
jackalmage@8856 | 44 | |
jackalmage@8856 | 45 | dd > p:nth-child(1) { |
jackalmage@8856 | 46 | margin-top:0 |
jackalmage@8856 | 47 | } |
jackalmage@8856 | 48 | </style> |
jackalmage@7249 | 49 | |
jackalmage@7249 | 50 | <h2 id='intro'> |
jackalmage@7249 | 51 | Introduction and Overview</h2> |
jackalmage@7249 | 52 | |
jackalmage@7249 | 53 | <p> |
jackalmage@7249 | 54 | Grid layout contains features targeted at web application authors. |
jackalmage@7251 | 55 | The grid can be used to achieve many different layouts. |
jackalmage@7251 | 56 | It excels at dividing up space for major regions of an application, |
jackalmage@7251 | 57 | or defining the relationship in terms of size, position, and layer |
jackalmage@7249 | 58 | between parts of a control built from HTML primitives. |
jackalmage@7249 | 59 | |
jackalmage@7249 | 60 | <p> |
jackalmage@7251 | 61 | Like tables, |
jackalmage@7251 | 62 | grid layout enables an author to align elements into columns and rows, |
jackalmage@7251 | 63 | but unlike tables, |
jackalmage@7251 | 64 | grid layout doesn't have content structure, |
jackalmage@7251 | 65 | and thus enables a wide variety of layouts not possible with tables. |
fantasai@7258 | 66 | For example, the children of a grid container can position themselves |
jackalmage@7249 | 67 | such that they overlap and layer similar to positioned elements. |
jackalmage@7249 | 68 | |
jackalmage@7249 | 69 | <p> |
jackalmage@7251 | 70 | In addition, the absence of content structure in grid layout helps to manage changes to layout |
jackalmage@7251 | 71 | by using fluid and source order independent layout techniques. |
jackalmage@7251 | 72 | By combining media queries with the CSS properties that control layout of the grid container and its children, |
jackalmage@7251 | 73 | authors can adapt their layout to changes in device form factors, orientation, and available space, |
jackalmage@7249 | 74 | without needing to alter the semantic nature of their content. |
jackalmage@7249 | 75 | |
jackalmage@7256 | 76 | |
jackalmage@7249 | 77 | <h3 id='background'> |
jackalmage@7250 | 78 | Background and Motivation</h3> |
jackalmage@7249 | 79 | |
jackalmage@7249 | 80 | <div class="sidefigure"> |
fantasai@8909 | 81 | <img class="figure" alt="Image: Application layout example requiring horizontal and vertical alignment." src="images/basic-form.png" /> |
jackalmage@7249 | 82 | <p class="caption">Application layout example requiring horizontal and vertical alignment. |
jackalmage@7249 | 83 | </div> |
jackalmage@7249 | 84 | |
jackalmage@7249 | 85 | <p> |
jackalmage@7251 | 86 | As websites evolved from simple documents into complex, interactive applications, |
jackalmage@7249 | 87 | tools for document layout, e.g. floats, |
jackalmage@7251 | 88 | were not necessarily well suited for application layout. |
jackalmage@7251 | 89 | By using a combination of tables, JavaScript, or careful measurements on floated elements, |
jackalmage@7251 | 90 | authors discovered workarounds to achieve desired layouts. |
jackalmage@7251 | 91 | Layouts that adapted to the available space were often brittle |
jackalmage@7251 | 92 | and resulted in counter-intuitive behavior as space became constrained. |
jackalmage@7251 | 93 | As an alternative, authors of many web applications opted for a fixed layout |
jackalmage@7249 | 94 | that cannot take advantage of changes in the available rendering space on a screen. |
jackalmage@7251 | 95 | |
jackalmage@7249 | 96 | <p> |
jackalmage@7251 | 97 | The capabilities of grid layout address these problems. |
jackalmage@7251 | 98 | It provides a mechanism for authors to divide available space for layout into columns and rows |
jackalmage@7251 | 99 | using a set of predictable sizing behaviors. |
jackalmage@7251 | 100 | Authors can then precisely position and size the building block elements of their application |
jackalmage@8856 | 101 | by into <a>grid areas</a> defined by these columns and rows. |
jackalmage@7249 | 102 | Figure 1 illustrates a basic layout which can be achieved with grid layout. |
jackalmage@7249 | 103 | |
jackalmage@7249 | 104 | <h3 id='adapting-to-available-space'> |
jackalmage@7249 | 105 | Adapting Layouts to Available Space</h3> |
jackalmage@7249 | 106 | |
jackalmage@7249 | 107 | <div class="sidefigure"> |
jackalmage@7249 | 108 | <p> |
fantasai@8909 | 109 | <img alt="Image: Five grid items arranged according to content size and available space." src="images/game-smaller.png" /> |
jackalmage@7251 | 110 | |
jackalmage@7249 | 111 | <p class="caption"> |
jackalmage@7249 | 112 | Five grid items arranged according to content size and available space. |
jackalmage@7249 | 113 | </div> |
jackalmage@7249 | 114 | |
jackalmage@7249 | 115 | <div class="sidefigure"> |
jackalmage@7249 | 116 | <p> |
fantasai@8909 | 117 | <img alt="Image: Growth in the grid due to an increase in available space." src="images/game-larger.png" /> |
jackalmage@7251 | 118 | |
jackalmage@7249 | 119 | <p class="caption"> |
jackalmage@7249 | 120 | Growth in the grid due to an increase in available space. |
jackalmage@7249 | 121 | </div> |
jackalmage@7249 | 122 | |
jackalmage@7249 | 123 | <p> |
jackalmage@7249 | 124 | Grid layout can be used to intelligently reflow elements within a webpage. |
jackalmage@7251 | 125 | Figure 2 represents a game with five major areas in the layout: |
jackalmage@7251 | 126 | the game title, stats area, game board, score area, and control area. |
jackalmage@7249 | 127 | The author's intent is to divide the space for the game such that: |
jackalmage@7249 | 128 | |
jackalmage@7249 | 129 | <ul> |
jackalmage@7249 | 130 | <li> |
jackalmage@7249 | 131 | The stats area always appears immediately under the game title. |
jackalmage@7249 | 132 | <li> |
jackalmage@7249 | 133 | The game board appears to the right of the stats and title. |
jackalmage@7249 | 134 | <li> |
jackalmage@7249 | 135 | The top of the game title and the game board should always align. |
jackalmage@7249 | 136 | <li> |
jackalmage@7251 | 137 | The bottom of the game board and the stats area align when the game has reached its minimum height, |
jackalmage@7249 | 138 | but otherwise the game board will stretch to take advantage of all the screen real-estate available to it. |
jackalmage@7249 | 139 | <li> |
jackalmage@7251 | 140 | The score area should align into the column created by the game and stats area, |
jackalmage@7249 | 141 | while the controls are centered under the board. |
jackalmage@7251 | 142 | </ul> |
jackalmage@7251 | 143 | |
jackalmage@7249 | 144 | <p> |
jackalmage@7251 | 145 | As an alternative to using script to control the absolute position, width, and height of all elements, |
jackalmage@7251 | 146 | the author can use grid layout, |
jackalmage@7249 | 147 | as shown in Figure 3. |
jackalmage@7249 | 148 | The following example shows how an author might achieve all the sizing, placement, and alignment rules declaratively. |
jackalmage@7251 | 149 | |
jackalmage@7249 | 150 | <p> |
jackalmage@7251 | 151 | Note that there are multiple ways to specify the structure of the grid |
jackalmage@8856 | 152 | and to position and size <a>grid items</a>, |
jackalmage@7249 | 153 | each optimized for different scenarios. |
jackalmage@8856 | 154 | This example illustrates one that an author may use to define the position and space for each <a>grid item</a> |
jackalmage@8856 | 155 | using the 'grid-template-rows' and 'grid-template-columns' properties on the <a>grid container</a>, |
jackalmage@8856 | 156 | and the 'grid-row' and 'grid-column' properties on each <a>grid item</a>. |
jackalmage@7251 | 157 | |
jackalmage@7251 | 158 | |
jackalmage@7249 | 159 | <pre class="example"> |
jackalmage@7249 | 160 | <style type="text/css"> |
jackalmage@7771 | 161 | #grid { |
jackalmage@7771 | 162 | display: grid; |
jackalmage@7771 | 163 | |
jackalmage@7771 | 164 | /* Two columns: the first sized to content, the second receives |
jackalmage@9432 | 165 | * the remaining space, but is never smaller than the minimum |
jackalmage@9432 | 166 | * size of the board or the game controls, which occupy this |
jackalmage@7771 | 167 | * column. */ |
jackalmage@8786 | 168 | grid-template-columns: auto minmax(min-content, 1fr); |
jackalmage@7771 | 169 | |
jackalmage@9432 | 170 | /* Three rows: the first and last sized to content, the middle |
jackalmage@9432 | 171 | * row receives the remaining space, but is never smaller than |
jackalmage@7771 | 172 | * the minimum height of the board or stats areas. */ |
jackalmage@8786 | 173 | grid-template-rows: auto minmax(min-content, 1fr) auto |
jackalmage@7771 | 174 | } |
jackalmage@7771 | 175 | |
jackalmage@9432 | 176 | /* Each part of the game is positioned between grid lines by |
jackalmage@9432 | 177 | * referencing the starting grid line and then specifying, if more |
jackalmage@9432 | 178 | * than one, the number of rows or columns spanned to determine |
jackalmage@7771 | 179 | * the ending grid line, which establishes bounds for the part. */ |
jackalmage@7781 | 180 | #title { grid-column: 1; grid-row: 1 } |
jackalmage@7781 | 181 | #score { grid-column: 1; grid-row: 3 } |
jackalmage@7781 | 182 | #stats { grid-column: 1; grid-row: 2; justify-self: start } |
jackalmage@7781 | 183 | #board { grid-column: 2; grid-row: 1 / span 2; } |
jackalmage@7781 | 184 | #controls { grid-column: 2; grid-row: 3; align-self: center } |
jackalmage@7249 | 185 | </style> |
jackalmage@7249 | 186 | |
jackalmage@7249 | 187 | <div id="grid"> |
jackalmage@7771 | 188 | <div id="title">Game Title</div> |
jackalmage@7771 | 189 | <div id="score">Score</div> |
jackalmage@7771 | 190 | <div id="stats">Stats</div> |
jackalmage@7771 | 191 | <div id="board">Board</div> |
jackalmage@7771 | 192 | <div id="controls">Controls</div> |
jackalmage@7249 | 193 | </div></pre> |
jackalmage@7251 | 194 | |
jackalmage@7249 | 195 | <h3 id='source-independence'> |
jackalmage@7249 | 196 | Source Independence</h3> |
jackalmage@7249 | 197 | |
jackalmage@7249 | 198 | <div class="sidefigure"> |
jackalmage@7249 | 199 | <p> |
fantasai@8909 | 200 | <img alt="Image: An arrangement suitable for portrait orientation." src="images/game-portrait.png" /> |
jackalmage@7251 | 201 | |
jackalmage@7249 | 202 | <p class="caption">An arrangement suitable for ''portrait'' orientation. |
jackalmage@7249 | 203 | </div> |
jackalmage@7249 | 204 | |
jackalmage@7249 | 205 | <div class="sidefigure"> |
jackalmage@7249 | 206 | <p> |
fantasai@8909 | 207 | <img alt="Image: An arrangement suitable for landscape orientation." src="images/game-landscape.png" /> |
jackalmage@7251 | 208 | |
jackalmage@7249 | 209 | <p class="caption">An arrangement suitable for ''landscape'' orientation. |
jackalmage@7249 | 210 | </div> |
jackalmage@7249 | 211 | |
jackalmage@7249 | 212 | <p> |
jackalmage@7251 | 213 | Continuing the prior example, |
jackalmage@7251 | 214 | the author also wants the game to adapt to the space available on traditional computer monitors, handheld devices, or tablet computers. |
jackalmage@7251 | 215 | Also, the game should optimize the placement of the components when viewed either in landscape or portrait orientation (Figures 4 and 5). |
jackalmage@7251 | 216 | By combining grid layout with media queries, |
jackalmage@7251 | 217 | the author is able to use the same semantic markup, |
jackalmage@7251 | 218 | but rearrange the layout of elements independent of their source order, |
jackalmage@7249 | 219 | to achieve the desired layout in both orientations. |
jackalmage@7251 | 220 | |
jackalmage@7249 | 221 | <p> |
jackalmage@8856 | 222 | The following example leverages grid layout’s ability to name the space which will be occupied by a <a>grid item</a>. |
jackalmage@8856 | 223 | This allows the author to avoid rewriting rules for <a>grid items</a> |
jackalmage@8046 | 224 | as the grid’s definition changes. |
jackalmage@7251 | 225 | |
jackalmage@7249 | 226 | <pre class="example"> |
jackalmage@7249 | 227 | <style type="text/css"> |
jackalmage@7771 | 228 | @media (orientation: portrait) { |
jackalmage@7771 | 229 | #grid { |
jackalmage@7771 | 230 | display: grid; |
jackalmage@7771 | 231 | |
jackalmage@7773 | 232 | /* The rows, columns and areas of the grid are defined visually |
jackalmage@8786 | 233 | * using the grid-template-areas property. Each string is a row, and |
jackalmage@9432 | 234 | * each word an area. The number of words in a string |
jackalmage@9432 | 235 | * determines the number of columns. Note the number of words |
jackalmage@7773 | 236 | * in each string must be identical. */ |
jackalmage@8786 | 237 | grid-template-areas: "title stats" |
jackalmage@8786 | 238 | "score stats" |
jackalmage@8786 | 239 | "board board" |
jackalmage@8786 | 240 | "ctrls ctrls"; |
jackalmage@7773 | 241 | |
jackalmage@9432 | 242 | /* Columns and rows created with the template property can be |
jackalmage@9432 | 243 | * assigned a sizing function with the grid-template-columns |
jackalmage@8786 | 244 | * and grid-template-rows properties. */ |
jackalmage@8786 | 245 | grid-template-columns: auto minmax(min-content, 1fr); |
jackalmage@8786 | 246 | grid-template-rows: auto auto minmax(min-content, 1fr) auto |
jackalmage@7771 | 247 | } |
jackalmage@7771 | 248 | } |
jackalmage@7771 | 249 | |
jackalmage@7771 | 250 | @media (orientation: landscape) { |
jackalmage@7771 | 251 | #grid { |
jackalmage@7771 | 252 | display: grid; |
jackalmage@7771 | 253 | |
jackalmage@9432 | 254 | /* Again the template property defines areas of the same name, |
jackalmage@9432 | 255 | * but this time positioned differently to better suit a |
jackalmage@7773 | 256 | * landscape orientation. */ |
jackalmage@8786 | 257 | grid-template-areas: "title board" |
jackalmage@8786 | 258 | "stats board" |
jackalmage@8786 | 259 | "score ctrls"; |
jackalmage@8786 | 260 | |
jackalmage@8786 | 261 | grid-template-columns: auto minmax(min-content, 1fr); |
jackalmage@8786 | 262 | grid-template-rows: auto minmax(min-content, 1fr) auto |
jackalmage@7771 | 263 | } |
jackalmage@7771 | 264 | } |
jackalmage@7771 | 265 | |
jackalmage@9432 | 266 | /* The grid-area property places a grid item into a named |
jackalmage@7773 | 267 | * region (area) of the grid. */ |
jackalmage@7771 | 268 | #title { grid-area: title } |
jackalmage@7771 | 269 | #score { grid-area: score } |
jackalmage@7771 | 270 | #stats { grid-area: stats } |
jackalmage@7771 | 271 | #board { grid-area: board } |
jackalmage@7771 | 272 | #controls { grid-area: ctrls } |
jackalmage@7249 | 273 | </style> |
jackalmage@7249 | 274 | |
jackalmage@7249 | 275 | <div id="grid"> |
jackalmage@7771 | 276 | <div id="title">Game Title</div> |
jackalmage@7771 | 277 | <div id="score">Score</div> |
jackalmage@7771 | 278 | <div id="stats">Stats</div> |
jackalmage@7771 | 279 | <div id="board">Board</div> |
jackalmage@7771 | 280 | <div id="controls">Controls</div> |
jackalmage@7249 | 281 | </div></pre> |
jackalmage@7251 | 282 | |
jackalmage@7249 | 283 | |
jackalmage@7772 | 284 | <h3 id='grid-layering'> |
jackalmage@7249 | 285 | Grid Layering of Elements</h3> |
jackalmage@7249 | 286 | |
jackalmage@7249 | 287 | <div class="sidefigure"> |
jackalmage@7249 | 288 | <p> |
fantasai@8909 | 289 | <img alt="Image: A control composed of layered HTML elements." src="images/control-layering-and-alignment.png" /> |
jackalmage@7251 | 290 | |
jackalmage@7249 | 291 | <p class="caption">A control composed of layered HTML elements. |
jackalmage@7249 | 292 | </div> |
jackalmage@7249 | 293 | |
jackalmage@7249 | 294 | <p> |
jackalmage@7251 | 295 | In the example shown in Figure 6, |
jackalmage@7251 | 296 | the author is creating a custom slider control. |
jackalmage@7251 | 297 | The control has six parts. |
jackalmage@7251 | 298 | The lower and upper labels align to the left and right edges of the control. |
jackalmage@7251 | 299 | The track of the slider spans the area between the labels. |
jackalmage@7251 | 300 | The lower and upper fill parts touch beneath the thumb, |
jackalmage@7251 | 301 | and the thumb is a fixed width and height that can be moved along the track |
jackalmage@7742 | 302 | by updating the two flex-sized columns. |
jackalmage@7251 | 303 | |
jackalmage@7249 | 304 | <p> |
jackalmage@7251 | 305 | Prior to the introduction of grid layout, |
jackalmage@7251 | 306 | the author would have likely used absolute positioning to control the top and left coordinates, |
jackalmage@7251 | 307 | along with the width and height of each HTML element that comprises the control. |
jackalmage@7251 | 308 | By leveraging grid layout, |
jackalmage@7251 | 309 | the author can instead limit script usage to handling mouse events on the thumb, |
jackalmage@7251 | 310 | which snaps to various positions along the track |
jackalmage@8856 | 311 | as the 'grid-template-columns' property of the <a>grid container</a> is updated. |
jackalmage@7251 | 312 | |
jackalmage@7249 | 313 | <pre class="example"> |
jackalmage@7249 | 314 | <style type="text/css"> |
jackalmage@7771 | 315 | #grid { |
jackalmage@7771 | 316 | display: grid; |
jackalmage@7771 | 317 | |
jackalmage@9432 | 318 | /* The grid-template-columns and rows properties also support |
jackalmage@9432 | 319 | * naming grid lines which can then be used to position grid |
jackalmage@7773 | 320 | * items. The line names are assigned on either side of a column |
jackalmage@7773 | 321 | * or row sizing function where the line would logically exist. */ |
jackalmage@8786 | 322 | grid-template-columns: |
jackalmage@8787 | 323 | (start) auto |
jackalmage@8787 | 324 | (track-start) 0.5fr |
jackalmage@8787 | 325 | (thumb-start) auto |
jackalmage@8787 | 326 | (fill-split) auto |
jackalmage@8787 | 327 | (thumb-end) 0.5fr |
jackalmage@8787 | 328 | (track-end) auto |
jackalmage@8787 | 329 | (end); |
jackalmage@7771 | 330 | } |
jackalmage@7771 | 331 | |
jackalmage@7775 | 332 | /* The grid-placement properties accept named lines. Below the |
jackalmage@9432 | 333 | * lines are referred to by name. Beyond any |
jackalmage@9432 | 334 | * semantic advantage, the names also allow the author to avoid |
jackalmage@9432 | 335 | * renumbering the grid-column-start and grid-row-start properties of the |
jackalmage@9432 | 336 | * grid items. This is similar to the concept demonstrated in the |
jackalmage@9432 | 337 | * prior example with the grid-template-areas property during orientation |
jackalmage@9432 | 338 | * changes, but grid lines can also work with layered grid items |
jackalmage@9432 | 339 | * that have overlapping areas of different shapes like the thumb |
jackalmage@7773 | 340 | * and track parts in this example. */ |
jackalmage@8787 | 341 | #lower-label { grid-column-start: start } |
jackalmage@8787 | 342 | #track { grid-column: track-start / track-end; align-self: center } |
jackalmage@8787 | 343 | #upper-label { grid-column-end: end; } |
jackalmage@7771 | 344 | |
jackalmage@7771 | 345 | /* Fill parts are drawn above the track so set z-index to 5. */ |
jackalmage@9432 | 346 | #lower-fill { grid-column: track-start / fill-split; |
jackalmage@9432 | 347 | align-self: end; |
jackalmage@7775 | 348 | z-index: 5 } |
jackalmage@9432 | 349 | #upper-fill { grid-column: fill-split / track-end; |
jackalmage@9432 | 350 | align-self: start; |
jackalmage@7775 | 351 | z-index: 5 } |
jackalmage@7771 | 352 | |
jackalmage@7771 | 353 | /* Thumb is the topmost part; assign it the highest z-index value. */ |
jackalmage@8787 | 354 | #thumb { grid-column: thumb-start / thumb-end; z-index: 10 } |
jackalmage@7249 | 355 | </style> |
jackalmage@7249 | 356 | |
jackalmage@7249 | 357 | <div id="grid"> |
jackalmage@7771 | 358 | <div id="lower-label">Lower Label</div> |
jackalmage@7771 | 359 | <div id="upper-label">Upper Label</div> |
jackalmage@7771 | 360 | <div id="track">Track</div> |
jackalmage@7771 | 361 | <div id="lower-fill">Lower Fill</div> |
jackalmage@7771 | 362 | <div id="upper-fill">Upper Fill</div> |
jackalmage@7771 | 363 | <div id="thumb">Thumb</div> |
jackalmage@7249 | 364 | </div></pre> |
jackalmage@7249 | 365 | |
jackalmage@7249 | 366 | |
jackalmage@7257 | 367 | <h2 id='grid-concepts'> |
fantasai@7258 | 368 | Grid Layout Concepts and Terminology</h2> |
jackalmage@7249 | 369 | |
jackalmage@7249 | 370 | <p> |
jackalmage@8858 | 371 | In <dfn export>grid layout</dfn>, |
jackalmage@8856 | 372 | the content of a <a>grid container</a> is laid out |
jackalmage@8856 | 373 | by positioning and aligning it into a <a>grid</a>. |
jackalmage@8858 | 374 | The <dfn export>grid</dfn> is an intersecting set of horizontal and vertical <a>grid lines</a> |
jackalmage@8856 | 375 | that divides the <a>grid container</a>’s space into <a>grid areas</a>, |
jackalmage@9432 | 376 | into which <a>grid items</a> (representing the <a>grid container</a>’s content) can be placed. |
jackalmage@9432 | 377 | There are two sets of <a>grid lines</a>: |
jackalmage@8858 | 378 | one set defining <dfn export title="grid column | column">columns</dfn> |
bert@9770 | 379 | that run along the <a href="http://www.w3.org/TR/css3-writing-modes/#block-axis-">block axis</a> (the <dfn export>column axis</dfn>), |
jackalmage@8858 | 380 | and an orthogonal set defining <dfn export title="grid row | row">rows</dfn> |
bert@9770 | 381 | along the <a href="http://www.w3.org/TR/css3-writing-modes/#inline-axis-">inline axis</a> (the <dfn export>row axis</dfn>). |
fantasai@7258 | 382 | [[!CSS3-WRITING-MODES]] |
jackalmage@7257 | 383 | |
jackalmage@7257 | 384 | <!-- |
jackalmage@7249 | 385 | <div class="figure"> |
fantasai@8909 | 386 | <img class="figure" alt="Image: A diagram illustrating the relationship between the Grid Element and its Tracks, Lines, Areas and Items." src="images/grid-concepts.png" /> |
jackalmage@8856 | 387 | <p class="caption">A diagram illustrating the relationship between the <a>grid container</a> and its tracks, lines, areas and items. |
jackalmage@7249 | 388 | </div> |
jackalmage@7257 | 389 | --> |
jackalmage@7257 | 390 | |
jackalmage@7257 | 391 | <div class="figure"> |
fantasai@8909 | 392 | <img class="figure" alt="Image: Grid Lines." src="images/grid-lines.png" /> |
fantasai@7258 | 393 | <p class="caption">Grid lines: Three in the block axis and four in the inline axis. |
jackalmage@7249 | 394 | </div> |
jackalmage@7249 | 395 | |
fantasai@7258 | 396 | <h3 id="grid-track-concept"> |
jackalmage@8856 | 397 | Grid Tracks and Cells</h3> |
jackalmage@7257 | 398 | |
jackalmage@7249 | 399 | <p> |
jackalmage@8858 | 400 | <dfn export>Grid track</dfn> is a generic term for a <a>grid column</a> or <a>grid row</a>—in |
jackalmage@8856 | 401 | other words, it is the space between two adjacent <a>grid lines</a>. |
jackalmage@8856 | 402 | Each <a>grid track</a> is assigned a sizing function, |
fantasai@7258 | 403 | which controls how wide or tall the column or row may grow, |
jackalmage@8856 | 404 | and thus how far apart its bounding <a>grid lines</a> are. |
jackalmage@8856 | 405 | |
jackalmage@8856 | 406 | <p> |
jackalmage@8858 | 407 | A <dfn export>grid cell</dfn> is the similar term for the full grid—it |
jackalmage@8856 | 408 | is the space between two adjacent row and two adjacent column <a>grid lines</a>. |
jackalmage@8856 | 409 | It is the smallest unit of the grid that can be referenced when positioning <a>grid items</a>. |
jackalmage@7251 | 410 | |
jackalmage@7249 | 411 | <div class="example"> |
jackalmage@7249 | 412 | <p> |
jackalmage@7257 | 413 | In the following example there are two columns and three rows. |
jackalmage@7257 | 414 | The first column is fixed at 150px. |
jackalmage@7742 | 415 | The second column uses flexible sizing, which is a function of the unassigned space in the Grid, |
jackalmage@8856 | 416 | and thus will vary as the width of the <a>grid container</a> changes. |
jackalmage@8856 | 417 | If the used width of the <a>grid container</a> is 200px, then the second column 50px wide. |
jackalmage@8856 | 418 | If the used width of the <a>grid container</a> is 100px, then the second column is 0px |
jackalmage@8856 | 419 | and any content positioned in the column will overflow the <a>grid container</a>. |
jackalmage@7249 | 420 | |
jackalmage@7249 | 421 | <pre> |
jackalmage@7249 | 422 | <style type="text/css"> |
jackalmage@7251 | 423 | #grid { |
jackalmage@7251 | 424 | display: grid; |
jackalmage@8786 | 425 | grid-template-columns: 150px 1fr; /* two columns */ |
jackalmage@8786 | 426 | grid-template-rows: 50px 1fr 50px /* three rows */ |
jackalmage@7249 | 427 | } |
jackalmage@7249 | 428 | </style></pre> |
jackalmage@7249 | 429 | </div> |
jackalmage@7249 | 430 | |
fantasai@7258 | 431 | <h3 id="grid-line-concept"> |
fantasai@7258 | 432 | Grid Lines</h3> |
jackalmage@7249 | 433 | |
jackalmage@7249 | 434 | <p> |
jackalmage@8858 | 435 | <dfn id='grid-line' export title='grid line|grid row line|grid column line'>Grid lines</dfn> are the horizontal and vertical dividing lines of the <a>grid</a>. |
jackalmage@9432 | 436 | A <a>grid line</a> exists on either side of a column or row. |
fantasai@7258 | 437 | They can be referred to by numerical index, |
fantasai@7258 | 438 | or by an author-specified name. |
jackalmage@8856 | 439 | A <a>grid item</a> references the <a>grid lines</a> to determine its position within the <a>grid</a> |
fantasai@7258 | 440 | using the <a href="#placement">grid-placement properties</a>. |
jackalmage@7257 | 441 | |
jackalmage@7257 | 442 | <div class="example"> |
jackalmage@7257 | 443 | <p> |
jackalmage@8856 | 444 | The following two examples create three column <a>grid lines</a> and four row <a>grid lines</a>. |
jackalmage@8856 | 445 | The first example demonstrates how an author would position a <a>grid item</a> using <a>grid line</a> numbers. |
jackalmage@8856 | 446 | The second example uses explicitly named <a>grid lines</a>. |
jackalmage@7257 | 447 | |
jackalmage@7257 | 448 | <pre> |
jackalmage@7249 | 449 | <style type="text/css"> |
fantasai@7258 | 450 | #grid { |
fantasai@7258 | 451 | display: grid; |
jackalmage@8786 | 452 | grid-template-columns: 150px 1fr; |
jackalmage@8786 | 453 | grid-template-rows: 50px 1fr 50px |
fantasai@7258 | 454 | } |
fantasai@7258 | 455 | |
fantasai@7258 | 456 | #item1 { grid-column: 2; |
jackalmage@8107 | 457 | grid-column-start: 1; grid-column-end: 1; } |
jackalmage@7249 | 458 | </style></pre> |
jackalmage@7249 | 459 | |
fantasai@7258 | 460 | <pre> |
jackalmage@7249 | 461 | <style type="text/css"> |
fantasai@7258 | 462 | /* equivalent layout to the prior example, but using named lines */ |
fantasai@7258 | 463 | #grid { |
fantasai@7258 | 464 | display: grid; |
jackalmage@8787 | 465 | grid-template-columns: 150px (item1-start) 1fr (item1-end); |
jackalmage@8787 | 466 | grid-template-rows: (item1-start) 50px 1fr 50px (item1-end); |
fantasai@7258 | 467 | } |
fantasai@7258 | 468 | |
fantasai@7258 | 469 | #item1 { |
jackalmage@8787 | 470 | grid-column: item1-start / item1-end; |
jackalmage@8787 | 471 | grid-row: item1-start / item1-end |
fantasai@7258 | 472 | } |
jackalmage@7249 | 473 | </style></pre> |
jackalmage@7257 | 474 | </div> |
jackalmage@7249 | 475 | |
fantasai@7258 | 476 | |
fantasai@7258 | 477 | <h3 id="grid-area-concept"> |
fantasai@7258 | 478 | Grid Areas</h3> |
jackalmage@7249 | 479 | |
jackalmage@7249 | 480 | <p> |
jackalmage@8858 | 481 | A <dfn export>grid area</dfn> is the logical space used to lay out one or more <a>grid items</a>. |
jackalmage@8856 | 482 | It is bound by four <a>grid lines</a>, one on each side of the <a>grid area</a>, |
jackalmage@8856 | 483 | and participates in the sizing of the <a>grid tracks</a> it intersects. |
jackalmage@8856 | 484 | A <a>grid area</a> can be named explicitly using the 'grid-template-areas' property of the <a>grid container</a>, |
jackalmage@8856 | 485 | or referenced implicitly by its bounding <a>grid lines</a>. |
jackalmage@8856 | 486 | A <a>grid item</a> is assigned to a <a>grid area</a> |
fantasai@7258 | 487 | using the <a href="#placement">grid-placement properties</a>. |
jackalmage@7251 | 488 | |
jackalmage@7249 | 489 | <pre class="example"> |
jackalmage@7249 | 490 | <style type="text/css"> |
fantasai@7258 | 491 | /* using the template syntax */ |
fantasai@7258 | 492 | #grid { |
fantasai@7258 | 493 | display: grid; |
jackalmage@8786 | 494 | grid-template-areas: ". a" |
jackalmage@8786 | 495 | "b a" |
jackalmage@8786 | 496 | ". a"; |
jackalmage@8786 | 497 | grid-template-columns: 150px 1fr; |
jackalmage@8786 | 498 | grid-template-rows: 50px 1fr 50px |
fantasai@7258 | 499 | } |
fantasai@7258 | 500 | |
fantasai@7258 | 501 | #item1 { grid-area: a } |
fantasai@7258 | 502 | #item2 { grid-area: b } |
fantasai@7258 | 503 | #item3 { grid-area: b } |
fantasai@7258 | 504 | |
fantasai@7258 | 505 | /* Align items 2 and 3 at different points in the Grid Area "b". */ |
fantasai@7258 | 506 | /* By default, Grid Items are stretched to fit their Grid Area */ |
fantasai@7258 | 507 | /* and these items would layer one over the other. */ |
fantasai@7258 | 508 | #item2 { align-self: head } |
fantasai@7258 | 509 | #item3 { justify-self: end; align-self: foot } |
jackalmage@7249 | 510 | </style></pre> |
jackalmage@7249 | 511 | |
jackalmage@7650 | 512 | <p> |
jackalmage@8856 | 513 | A <a>grid item</a>’s <a>grid area</a> forms the containing block into which it is laid out. |
jackalmage@8856 | 514 | Percentage lengths specified on a <a>grid item</a> resolve against this containing block. |
jackalmage@8856 | 515 | Percentages specified for 'margin-top', 'padding-top', 'margin-bottom', and 'padding-bottom' on a <a>grid item</a> |
jackalmage@9432 | 516 | resolve against the height of its containing block, |
jackalmage@7651 | 517 | rather than the width (as for blocks). |
jackalmage@7651 | 518 | |
jackalmage@7651 | 519 | <p> |
jackalmage@8856 | 520 | <a>Grid items</a> placed into the same <a>grid area</a> do not directly affect each other's layout. |
jackalmage@8856 | 521 | Indirectly, a <a>grid item</a> can affect the position of a <a>grid line</a> in a column or row that uses a contents-based relative size, |
jackalmage@8856 | 522 | which in turn can affect the position or size of another <a>grid item</a>. |
jackalmage@7650 | 523 | |
fantasai@7258 | 524 | <h2 id="grid-model"> |
jackalmage@7770 | 525 | Grid Layout Box Model</h2> |
fantasai@7258 | 526 | |
fantasai@7258 | 527 | <h3 id='grid-containers'> |
jackalmage@8856 | 528 | Grid Containers: the <a value>grid</a> and ''inline-grid'' 'display' values</h3> |
jackalmage@8856 | 529 | |
jackalmage@8856 | 530 | <pre class='propdef'> |
jackalmage@8856 | 531 | Name: display |
jackalmage@8974 | 532 | New values: grid | inline-grid |
jackalmage@8856 | 533 | </pre> |
jackalmage@8856 | 534 | |
jackalmage@8856 | 535 | <dl dfn-for="display" dfn-type=value> |
jackalmage@8856 | 536 | <dt><dfn>grid</dfn> |
jackalmage@7249 | 537 | <dd> |
jackalmage@8856 | 538 | This value causes an element to generate a block-level <a>grid container</a> box. |
jackalmage@8856 | 539 | |
jackalmage@8856 | 540 | <dt><dfn>inline-grid</dfn> |
jackalmage@7249 | 541 | <dd> |
jackalmage@8856 | 542 | This value causes an element to generate an inline-level <a>grid container</a> box. |
jackalmage@7249 | 543 | </dl> |
jackalmage@7249 | 544 | |
jackalmage@7249 | 545 | <p> |
jackalmage@9432 | 546 | A <dfn export>grid container</dfn> establishes a new <dfn export>grid formatting context</dfn> for its contents. |
jackalmage@7753 | 547 | This is the same as establishing a block formatting context, |
jackalmage@9432 | 548 | except that grid layout is used instead of block layout: |
jackalmage@9432 | 549 | floats do not intrude into the grid container, |
jackalmage@9432 | 550 | and the grid container's margins do not collapse with the margins of its contents. |
jackalmage@8856 | 551 | <a>Grid containers</a> form a containing block for their contents |
jackalmage@7753 | 552 | <a href="http://www.w3.org/TR/CSS21/visudet.html#containing-block-details">exactly like block containers do</a>. [[!CSS21]] |
jackalmage@8856 | 553 | The 'overflow' property applies to <a>grid containers</a>. |
jackalmage@7753 | 554 | |
jackalmage@7753 | 555 | |
jackalmage@7753 | 556 | <p> |
jackalmage@9432 | 557 | Grid containers are not block containers, |
jackalmage@9432 | 558 | and so some properties that were designed with the assumption of block layout don't apply in the context of grid layout. |
jackalmage@7753 | 559 | In particular: |
jackalmage@7753 | 560 | |
jackalmage@7753 | 561 | <ul> |
jackalmage@7753 | 562 | <li> |
jackalmage@7753 | 563 | all of the 'column-*' properties in the Multicol module have no effect on a grid container. |
jackalmage@7753 | 564 | |
jackalmage@7753 | 565 | <li> |
jackalmage@8856 | 566 | 'float' and 'clear' have no effect on a <a>grid item</a>. |
jackalmage@7753 | 567 | (However, the 'float' property still affects the computed value of 'display' on children of a grid container, |
jackalmage@8856 | 568 | as this occurs <em title=''>before</em> <a>grid items</a> are determined.) |
jackalmage@7753 | 569 | |
jackalmage@7753 | 570 | <li> |
jackalmage@7753 | 571 | 'vertical-align' has no effect on a grid item. |
jackalmage@7753 | 572 | |
jackalmage@7753 | 573 | <li> |
jackalmage@8856 | 574 | the ''::first-line'' and ''::first-letter'' pseudo-elements do not apply to <a>grid containers</a>. |
jackalmage@7753 | 575 | </ul> |
jackalmage@7753 | 576 | |
jackalmage@7753 | 577 | <p> |
jackalmage@9432 | 578 | If an element's specified 'display' is ''inline-grid'' |
jackalmage@9432 | 579 | and the element is floated or absolutely positioned, |
jackalmage@8856 | 580 | the computed value of 'display' is <a value>grid</a>. |
jackalmage@9432 | 581 | The table in <a href="http://www.w3.org/TR/CSS2/visuren.html#dis-pos-flo">CSS 2.1 Chapter 9.7</a> is thus amended |
jackalmage@9432 | 582 | to contain an additional row, |
jackalmage@9432 | 583 | with ''inline-grid'' in the "Specified Value" column |
jackalmage@8856 | 584 | and <a>grid</a> in the "Computed Value" column. |
jackalmage@7753 | 585 | |
jackalmage@7249 | 586 | |
jackalmage@7249 | 587 | |
jackalmage@7772 | 588 | <h2 id="grid-items"> |
jackalmage@7772 | 589 | Grid Items</h2> |
jackalmage@7249 | 590 | |
jackalmage@7249 | 591 | <p> |
jackalmage@8858 | 592 | The contents of a <a>grid container</a> consists of zero or more <dfn export id="grid-item" title="grid item">grid items</dfn>: |
jackalmage@8856 | 593 | each child of a <a>grid container</a> |
jackalmage@8856 | 594 | becomes a <a>grid item</a>, |
jackalmage@8856 | 595 | and each contiguous run of text that is directly contained inside a <a>grid container</a> |
jackalmage@8856 | 596 | is wrapped in an anonymous <a>grid item</a>. |
jackalmage@7249 | 597 | However, an anonymous grid item that contains only |
jackalmage@7249 | 598 | <a href="http://www.w3.org/TR/CSS21/text.html#white-space-prop">white space</a> |
jackalmage@7249 | 599 | is not rendered, as if it were ''display:none''. |
jackalmage@7249 | 600 | |
jackalmage@7249 | 601 | <p> |
jackalmage@8856 | 602 | A <a>grid item</a> establishes a new formatting context for its contents. |
jackalmage@7249 | 603 | The type of this formatting context is determined by its 'display' value, as usual. |
jackalmage@8856 | 604 | The computed 'display' of a <a>grid item</a> |
jackalmage@7249 | 605 | is determined by applying the table in |
jackalmage@7249 | 606 | <a href="http://www.w3.org/TR/CSS2/visuren.html#dis-pos-flo">CSS 2.1 Chapter 9.7</a>. |
jackalmage@7249 | 607 | However, grid items are grid-level boxes, not block-level boxes: |
jackalmage@8856 | 608 | they participate in their container's <a>grid formatting context</a>, |
jackalmage@7249 | 609 | not in a block formatting context. |
jackalmage@7249 | 610 | |
jackalmage@7249 | 611 | <div class="example"> |
jackalmage@7249 | 612 | <p> |
jackalmage@7249 | 613 | Examples of grid items: |
jackalmage@7249 | 614 | <pre> |
jackalmage@7249 | 615 | <div style="display:grid"> |
jackalmage@7249 | 616 | |
jackalmage@7249 | 617 | <!-- grid item: block child --> |
jackalmage@7249 | 618 | <div id="item1">block</div> |
jackalmage@7249 | 619 | |
jackalmage@7249 | 620 | <!-- grid item: floated element; floating is ignored --> |
jackalmage@7249 | 621 | <div id="item2" style="float: left;">float</div> |
jackalmage@7249 | 622 | |
jackalmage@7249 | 623 | <!-- grid item: anonymous block box around inline content --> |
jackalmage@7249 | 624 | anonymous item 3 |
jackalmage@7249 | 625 | |
jackalmage@7249 | 626 | <!-- grid item: inline child --> |
jackalmage@7249 | 627 | <span> |
jackalmage@7249 | 628 | item 4 |
jackalmage@7249 | 629 | <!-- grid items do not split around blocks --> |
jackalmage@7249 | 630 | <div id=not-an-item>item 4</div> |
jackalmage@7249 | 631 | item 4 |
jackalmage@7249 | 632 | </span> |
jackalmage@7249 | 633 | </div></pre> |
jackalmage@7249 | 634 | </div> |
jackalmage@7249 | 635 | |
jackalmage@7249 | 636 | <p> |
jackalmage@7251 | 637 | Some values of 'display' trigger the generation of anonymous boxes. |
jackalmage@7249 | 638 | For example, a misparented ''table-cell'' child is fixed up |
jackalmage@7249 | 639 | by <a href="http://www.w3.org/TR/CSS21/tables.html#anonymous-boxes">generating anonymous ''table'' and ''table-row'' elements</a> around it. [[!CSS21]] |
jackalmage@8856 | 640 | This fixup must occur <em>before</em> a <a>grid container</a>’s children are promoted to <a>grid items</a>. |
jackalmage@7251 | 641 | For example, given two contiguous child elements with ''display:table-cell'', |
jackalmage@8856 | 642 | an anonymous table wrapper box around them becomes the <a>grid item</a>. |
jackalmage@7249 | 643 | |
jackalmage@7249 | 644 | <p class='note'> |
jackalmage@7249 | 645 | Future display types may generate anonymous containers (e.g. ruby) or otherwise mangle the box tree (e.g. run-ins). |
jackalmage@7249 | 646 | It is intended that grid item determination run after these operations. |
jackalmage@7249 | 647 | |
jackalmage@8889 | 648 | <!-- |
jackalmage@7772 | 649 | <h3 id="position-grid"> |
jackalmage@7772 | 650 | Non-children Grid Items</h3> |
jackalmage@7249 | 651 | |
jackalmage@7249 | 652 | <p class="issue"> |
jackalmage@7249 | 653 | This is a proposal to create the ability to have descendants of a grid item participate in a grid layout, |
jackalmage@7249 | 654 | similar to the behavior defined by the Template Layout module. |
jackalmage@7249 | 655 | |
jackalmage@7249 | 656 | <p> |
jackalmage@7249 | 657 | A descendant of the grid can be pulled out of flow and participate directly in the grid |
jackalmage@7249 | 658 | by assigning it ''position: grid''. |
jackalmage@7249 | 659 | An element with ''position: grid'' is pulled out of flow and participates as a grid item |
jackalmage@7249 | 660 | belonging to the first ancestor with ''display: grid''. |
jackalmage@7249 | 661 | If the element is positioned using named lines or slots, |
jackalmage@7249 | 662 | it belongs to the first ancestor with ''display: grid'' that has all of the corresponding named lines/slots. |
jackalmage@7249 | 663 | If no such ancestor exists, the item remains in flow. |
jackalmage@7249 | 664 | |
jackalmage@7249 | 665 | <p class="issue"> |
jackalmage@7249 | 666 | Alternatively, the item can just go into the first grid, |
jackalmage@8856 | 667 | and missing names are treated as <a value for="<grid-line>">auto</a>. |
jackalmage@8889 | 668 | --> |
jackalmage@8889 | 669 | |
fantasai@8948 | 670 | <h3 id="visibility-collapse"> |
fantasai@8948 | 671 | Collapsed Grid Items: the 'visibility' property</h3> |
fantasai@8948 | 672 | |
fantasai@8948 | 673 | <p class='issue'> |
fantasai@8948 | 674 | We want the ability to collapse grid tracks |
fantasai@8948 | 675 | (similar to <a href="http://www.w3.org/TR/css3-flexbox/#visibility-collapse">collapsing flex items</a> |
fantasai@8948 | 676 | or <a href="http://www.w3.org/TR/CSS21/tables.html#dynamic-effects">table rows/columns</a>), |
fantasai@8948 | 677 | but we're not sure exactly how to do it. |
fantasai@8948 | 678 | Ideas welcome, please <a href="mailto:www-style@w3.org?Subject=%5Bcss-grid%5D%20Collapsing%20Grid%20Tracks">post them to www-style@w3.org</a>. |
fantasai@8948 | 679 | |
jackalmage@7832 | 680 | <h3 id='order-property'> |
jackalmage@7832 | 681 | Reordered Grid Items: the 'order' property</h3> |
jackalmage@7832 | 682 | |
jackalmage@7832 | 683 | <p> |
jackalmage@8858 | 684 | The 'order' property also applies to <a>grid items</a>. |
jackalmage@7832 | 685 | It affects their <a href="#grid-auto-flow-property">auto-placement</a> and <a href="#z-order">painting order</a>. |
jackalmage@7832 | 686 | |
jackalmage@7832 | 687 | |
fantasai@8947 | 688 | <h3 id="static-position"> |
fantasai@8947 | 689 | Static Position of Grid Container Children</h3> |
fantasai@8947 | 690 | |
fantasai@8947 | 691 | <p> |
fantasai@8947 | 692 | The <a href="http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width">static position</a> [[!CSS21]] |
fantasai@8947 | 693 | of an absolutely-positioned child of a <a>grid container</a> |
fantasai@8947 | 694 | is determined as if it were the sole grid item |
fantasai@8947 | 695 | in a fixed-size <i>grid area</i> |
fantasai@8947 | 696 | whose edges coincide with the padding edges of the <i>grid container</i>. |
fantasai@8947 | 697 | |
fantasai@8947 | 698 | <p class="note"> |
fantasai@8947 | 699 | Note that this position is affected by the values of 'justify-self' and 'align-self' on the child, |
fantasai@8947 | 700 | and that, as in most other layout models, |
fantasai@8947 | 701 | the absolutely-positioned child has no effect on the size of the containing block |
fantasai@8947 | 702 | or layout of its contents. |
fantasai@8947 | 703 | |
jackalmage@7772 | 704 | <h2 id='grid-definition'> |
jackalmage@8844 | 705 | The Explicit Grid</h2> |
jackalmage@7249 | 706 | |
jackalmage@7830 | 707 | <p> |
jackalmage@8786 | 708 | The three properties 'grid-template-rows', 'grid-template-columns', and 'grid-template-areas' |
jackalmage@8858 | 709 | together define the <dfn export>explicit grid</dfn> of a <a>grid container</a>. |
jackalmage@8786 | 710 | The 'grid-template' property is a shorthand that sets all three at the same time. |
jackalmage@8856 | 711 | The final grid may end up larger due to <a>grid items</a> placed outside the <a>explicit grid</a>; |
jackalmage@7830 | 712 | in this case, any implicit tracks are sized by the 'grid-auto-rows' and 'grid-auto-columns' properties. |
jackalmage@7830 | 713 | |
jackalmage@7830 | 714 | <p> |
jackalmage@9432 | 715 | The size of the <a>explicit grid</a> is determined by the larger of |
jackalmage@8786 | 716 | the number of rows/columns defined by 'grid-template-areas' |
jackalmage@8786 | 717 | and the number of rows/columns sized by 'grid-template-rows'/'grid-template-columns'. |
jackalmage@8786 | 718 | Any rows/columns defined by 'grid-template-areas' but not sized by 'grid-template-rows'/'grid-template-columns' |
jackalmage@7830 | 719 | take their size from the 'grid-auto-rows'/'grid-auto-columns' properties. |
jackalmage@7830 | 720 | |
jackalmage@7830 | 721 | <p> |
jackalmage@8856 | 722 | Numeric indexes in the <a>grid-placement properties</a> |
jackalmage@8856 | 723 | count from the edges of the <a>explicit grid</a>, |
jackalmage@8847 | 724 | starting from 1. |
jackalmage@7830 | 725 | Positive indexes count from the before/start side, |
jackalmage@7830 | 726 | while negative indexes count from the after/end side. |
jackalmage@7830 | 727 | |
jackalmage@7249 | 728 | <h3 id='track-sizing'> |
jackalmage@8786 | 729 | Track Sizing: the 'grid-template-rows' and 'grid-template-columns' properties</h3> |
jackalmage@7249 | 730 | |
jackalmage@8856 | 731 | <pre class='propdef'> |
jackalmage@8856 | 732 | Name: grid-template-columns, grid-template-rows |
jackalmage@8933 | 733 | Value: none | <<track-list>> | subgrid <<line-name-list>>? |
jackalmage@8856 | 734 | Initial: none |
jackalmage@8856 | 735 | Applies to: <a>grid containers</a> |
jackalmage@8856 | 736 | Inherited: no |
jackalmage@9762 | 737 | Percentages: see prose |
jackalmage@8856 | 738 | Media: visual |
jackalmage@9786 | 739 | Computed value: As specified, except for ''grid-template-columns/auto'' (see prose), with lengths made absolute |
jackalmage@8856 | 740 | </pre> |
jackalmage@7249 | 741 | |
jackalmage@7661 | 742 | <p> |
jackalmage@9432 | 743 | These properties specify, |
jackalmage@8858 | 744 | as a space-separated <dfn export>track list</dfn>, |
jackalmage@8856 | 745 | the line names and track <a>sizing functions</a> of the <a>grid</a>. |
jackalmage@8858 | 746 | Each <dfn export>sizing function</dfn> can be specified as a length, |
jackalmage@8856 | 747 | a percentage of the <a>grid container</a>’s size, |
fantasai@7258 | 748 | a measurement of the contents occupying the column or row, |
jackalmage@7739 | 749 | or a fraction of the free space in the grid. |
fantasai@7258 | 750 | It can also be specified as a range using the ''minmax()'' notation, |
fantasai@7258 | 751 | which can combine any of the previously mentioned mechanisms to define a min and max size for the column or row. |
fantasai@7258 | 752 | |
jackalmage@7249 | 753 | <p> |
jackalmage@8856 | 754 | The 'grid-template-columns' property specifies the <a>track list</a> for the grid's columns, |
jackalmage@8856 | 755 | while 'grid-template-rows' specifies the <a>track list</a> for the grid's rows. |
jackalmage@8856 | 756 | The syntax of a <a>track list</a> is: |
jackalmage@7251 | 757 | |
jackalmage@7249 | 758 | <pre> |
jackalmage@8933 | 759 | <dfn><track-list></dfn> = [ <<line-names>>? [ <<track-size>> | <<repeat()>> ] ]+ <<line-names>>? |
jackalmage@8933 | 760 | <dfn><track-size></dfn> = minmax( <<track-breadth>> , <<track-breadth>> ) | auto | <<track-breadth>> |
jackalmage@8933 | 761 | <dfn><track-breadth></dfn> = <<length>> | <<percentage>> | <<flex>> | min-content | max-content |
jackalmage@9649 | 762 | <dfn><line-names></dfn> = ( <<custom-ident>>* ) |
fantasai@8937 | 763 | <dfn><line-name-list></dfn> = [ <<line-names>> | repeat(<<positive-integer>>, <<line-names>>) ]+ |
jackalmage@8856 | 764 | </pre> |
jackalmage@7251 | 765 | |
jackalmage@7249 | 766 | <p>Where: |
jackalmage@7249 | 767 | |
jackalmage@8856 | 768 | <dl dfn-for="grid-template-columns grid-template-rows" dfn-type=value> |
jackalmage@8856 | 769 | <dt><dfn><<length>></dfn> |
jackalmage@7661 | 770 | <dd> |
jackalmage@8723 | 771 | A non-negative length, as defined by CSS3 Values. [[!CSS3VAL]] |
jackalmage@7661 | 772 | |
jackalmage@8856 | 773 | <dt><dfn><<percentage>></dfn> |
jackalmage@7661 | 774 | <dd> |
jackalmage@8723 | 775 | A non-negative percentage, as defined by CSS3 Values. [[!CSS3VAL]] |
jackalmage@8856 | 776 | <<percentage>> values are relative to the measure (logical width) of the <a>grid container</a> in column <a>grid tracks</a>, |
jackalmage@8856 | 777 | and the extent (logical height) of the <a>grid container</a> in row <a>grid tracks</a>. |
jackalmage@8856 | 778 | If the measure or extent of the <a>grid container</a> is an <a href="http://www.w3.org/TR/css3-sizing/#indefinite-size">indefinite size</a>, |
jackalmage@8856 | 779 | <<percentage>> values relative to that size are treated as <a value for=width>auto</a>. |
jackalmage@8856 | 780 | |
jackalmage@8856 | 781 | <dt><dfn><<flex>></dfn> |
jackalmage@7661 | 782 | <dd> |
fantasai@10071 | 783 | A non-negative dimension with the unit ''fr'' specifying the track's <dfn noexport>flex factor</dfn>. |
jackalmage@9432 | 784 | Each <<flex>> value takes a share of the remaining space in proportion to its value. |
jackalmage@7741 | 785 | See <a href="#fr-unit">Flexible Lengths</a> for more details. |
jackalmage@7741 | 786 | |
jackalmage@7741 | 787 | <dt><dfn>max-content</dfn> |
jackalmage@7661 | 788 | <dd> |
jackalmage@9432 | 789 | Represents the largest <a href="http://www.w3.org/TR/css3-sizing/#max-size-contribution">max size contribution</a> |
jackalmage@8856 | 790 | of the <a>grid items</a> occupying the <a>grid track</a>. |
jackalmage@7661 | 791 | |
jackalmage@7741 | 792 | <dt><dfn>min-content</dfn> |
jackalmage@7661 | 793 | <dd> |
jackalmage@9432 | 794 | Represents the largest <a href="http://www.w3.org/TR/css3-sizing/#min-size-contribution">min size contribution</a> |
jackalmage@8856 | 795 | of the <a>grid items</a> occupying the <a>grid track</a>. |
jackalmage@8856 | 796 | |
jackalmage@8856 | 797 | <dt><dfn title="minmax()">minmax(min, max)</dfn> |
jackalmage@7661 | 798 | <dd> |
jackalmage@7661 | 799 | Defines a size range |
jackalmage@7661 | 800 | greater than or equal to <var>min</var> |
jackalmage@7661 | 801 | and less than or equal to <var>max</var>. |
jackalmage@9432 | 802 | If <var>max</var> < <var>min</var>, |
jackalmage@7661 | 803 | then <var>max</var> is ignored and ''minmax(min,max)'' is treated as <var>min</var>. |
jackalmage@7661 | 804 | |
jackalmage@8856 | 805 | <dt><dfn>auto</dfn> |
jackalmage@7661 | 806 | <dd> |
jackalmage@7661 | 807 | Computes to ''minmax(min-content, max-content)''. |
jackalmage@7661 | 808 | </dl> |
jackalmage@7249 | 809 | |
jackalmage@7739 | 810 | <p> |
jackalmage@8856 | 811 | The <dfn value for="grid-template-rows grid-template-columns">none</dfn> value indicates that there is no <a>explicit grid</a>; |
jackalmage@7739 | 812 | any rows/columns will be implicitly generated, |
jackalmage@7739 | 813 | and their size will be determined by the 'grid-auto-rows' and 'grid-auto-columns' properties. |
jackalmage@7739 | 814 | |
jackalmage@8841 | 815 | <p> |
jackalmage@8856 | 816 | The <dfn value for="grid-template-rows grid-template-columns">subgrid</dfn> value indicates that the grid will align to its parent grid in that axis. |
jackalmage@8841 | 817 | Rather than specifying the sizes of rows/columns explicitly, |
jackalmage@8841 | 818 | they'll be taken from the parent grid's definition. |
jackalmage@8856 | 819 | If the <a>grid container</a> is not a <a>grid item</a>, |
jackalmage@9786 | 820 | this value computes to ''grid-template-rows/none''. |
jackalmage@8841 | 821 | See the <a href="#subgrids">Subgrids</a> section for more detail. |
jackalmage@8841 | 822 | |
jackalmage@7249 | 823 | <div class='example'> |
jackalmage@7249 | 824 | <p> |
jackalmage@8786 | 825 | Given the following 'grid-template-columns' declaration: |
jackalmage@8786 | 826 | |
jackalmage@8786 | 827 | <pre>grid-template-columns: 100px 1fr max-content minmax(min-content, 1fr);</pre> |
jackalmage@7251 | 828 | |
jackalmage@7249 | 829 | <p> |
jackalmage@7661 | 830 | Five grid lines are created: |
jackalmage@7661 | 831 | |
jackalmage@7661 | 832 | <ol> |
jackalmage@7661 | 833 | <li> |
jackalmage@8856 | 834 | At the start edge of the <a>grid container</a>. |
jackalmage@7661 | 835 | |
jackalmage@7661 | 836 | <li> |
jackalmage@8856 | 837 | 100px from the start edge of the <a>grid container</a>. |
jackalmage@7661 | 838 | |
jackalmage@7661 | 839 | <li> |
jackalmage@8856 | 840 | A distance from the previous line equal to half the <a>free space</a> |
jackalmage@8856 | 841 | (the width of the <a>grid container</a>, minus the width of the non-flexible <a>grid tracks</a>). |
jackalmage@7661 | 842 | |
jackalmage@7661 | 843 | <li> |
jackalmage@8856 | 844 | A distance from the previous line equal to the maximum size of any <a>grid items</a> |
jackalmage@7661 | 845 | belonging to the column between these two lines. |
jackalmage@7661 | 846 | |
jackalmage@7661 | 847 | <li> |
jackalmage@8856 | 848 | A distance from the previous line at least as large as the largest minimum size of any <a>grid items</a> |
jackalmage@7661 | 849 | belonging to the column between these two lines, |
jackalmage@8856 | 850 | but no larger than the other half of the <a>free space</a>. |
jackalmage@7661 | 851 | </ol> |
jackalmage@7661 | 852 | |
jackalmage@7661 | 853 | <p> |
jackalmage@7661 | 854 | If the non-flexible sizes |
jackalmage@7661 | 855 | (''100px'', ''max-content'', and ''min-content'') |
jackalmage@8856 | 856 | sum to larger than the <a>grid container</a>’s width, |
jackalmage@8856 | 857 | the final <a>grid line</a> will be a distance equal to their sum away from the start edge of the <a>grid container</a> |
jackalmage@7661 | 858 | (the ''1fr'' sizes both resolve to ''0''). |
jackalmage@8856 | 859 | If the sum is less than the <a>grid container</a>’s width, |
jackalmage@8856 | 860 | the final <a>grid line</a> will be exactly at the end edge of the <a>grid container</a>. |
jackalmage@8856 | 861 | This is true in general whenever there's at least one <<flex>> value among the <a>grid track</a> sizes. |
jackalmage@7661 | 862 | </div> |
jackalmage@7661 | 863 | |
jackalmage@7661 | 864 | <div class='example'> |
jackalmage@7661 | 865 | <p> |
jackalmage@8856 | 866 | Additional examples of valid <a>grid track</a> definitions: |
jackalmage@7249 | 867 | |
jackalmage@7249 | 868 | <pre> |
jackalmage@7661 | 869 | /* examples of valid track definitions */ |
jackalmage@8786 | 870 | grid-template-rows: 1fr minmax(min-content, 1fr); |
jackalmage@8786 | 871 | grid-template-rows: 10px repeat(2, 1fr auto minmax(30%, 1fr)); |
jackalmage@8786 | 872 | grid-template-rows: calc(4em - 5px)</pre> |
jackalmage@7249 | 873 | </div> |
jackalmage@7249 | 874 | |
jackalmage@7249 | 875 | |
jackalmage@7772 | 876 | <h4 id='named-lines'> |
jackalmage@9649 | 877 | Named Grid Lines: the ''(<<custom-ident>>*)'' syntax</h4> |
jackalmage@9649 | 878 | |
jackalmage@9649 | 879 | While <a>grid lines</a> can always be referred to by their numerical index, |
jackalmage@9649 | 880 | <dfn export title="named line">named lines</dfn> |
jackalmage@9649 | 881 | can make the <a>grid-placement properties</a> easier to understand and maintain. |
jackalmage@9649 | 882 | Lines can be explicitly named in the 'grid-template-rows' and 'grid-template-columns' properties, |
jackalmage@9649 | 883 | or <a href="#implicit-named-lines">implicitly named</a> by creating <a>named grid areas</a> with the 'grid-template-areas' property. |
jackalmage@7736 | 884 | |
jackalmage@7736 | 885 | <div class='example'> |
jackalmage@7736 | 886 | <p> |
jackalmage@7736 | 887 | For example, |
jackalmage@7736 | 888 | the following code gives meaningful names to all of the lines in the grid. |
jackalmage@7736 | 889 | Note that some of the lines have multiple names. |
jackalmage@7736 | 890 | |
jackalmage@7737 | 891 | <pre><style> |
jackalmage@7736 | 892 | #grid { |
jackalmage@7736 | 893 | display: grid; |
jackalmage@8787 | 894 | grid-template-columns: (first nav) 150px (main) 1fr (last); |
jackalmage@8787 | 895 | grid-template-rows: (first header) 50px (main) 1fr (footer) 50px (last); |
jackalmage@7736 | 896 | } |
jackalmage@7736 | 897 | </style></pre> |
jackalmage@7736 | 898 | |
jackalmage@7736 | 899 | <div class="figure"> |
fantasai@8909 | 900 | <img class="figure" alt="Image: Named Grid Lines." src="images/grid-named-lines.png" /> |
jackalmage@7736 | 901 | <p class="caption">Named Grid Lines. |
jackalmage@7736 | 902 | </div> |
jackalmage@7249 | 903 | </div> |
jackalmage@7251 | 904 | |
jackalmage@7249 | 905 | |
jackalmage@7249 | 906 | <h4 id='repeat-notation'> |
jackalmage@7249 | 907 | Repeating Rows and Columns: the ''repeat()'' notation</h4> |
jackalmage@7249 | 908 | |
jackalmage@7249 | 909 | <p> |
jackalmage@8856 | 910 | The ''repeat()'' notation represents a repeated fragment of the <a>track list</a>. |
jackalmage@7737 | 911 | This is just a syntactic shorthand that allows writing a large number of columns or rows that exhibit a recurring pattern in a more compact form. |
jackalmage@7737 | 912 | The syntax of the ''repeat()'' notation is: |
jackalmage@7737 | 913 | |
jackalmage@8888 | 914 | <pre class='prod'><dfn>repeat()</dfn> = repeat( <<positive-integer>> , [ <<line-names>>? <<track-size>> ]+ <<line-names>>? )</pre> |
jackalmage@7251 | 915 | |
jackalmage@7249 | 916 | <p> |
jackalmage@7737 | 917 | The first argument specifies the number of repetitions. |
jackalmage@8856 | 918 | The second argument is a <a>track list</a>, |
jackalmage@7737 | 919 | which is repeated that number of times. |
jackalmage@7737 | 920 | The ''repeat()'' notation cannot be nested; |
jackalmage@7737 | 921 | doing so makes the declaration invalid. |
jackalmage@7737 | 922 | |
jackalmage@7737 | 923 | <div class='example'> |
jackalmage@7737 | 924 | <p> |
jackalmage@7737 | 925 | This example shows two equivalent ways of writing the same grid definition. |
jackalmage@7737 | 926 | Both ways produce a grid with a single row and four "main" columns, each 250px wide, |
jackalmage@7737 | 927 | surrounded by 10px "gutter" columns. |
jackalmage@7737 | 928 | |
jackalmage@7737 | 929 | <pre> |
jackalmage@7737 | 930 | <style> |
jackalmage@7737 | 931 | #grid { |
jackalmage@7737 | 932 | display: grid; |
jackalmage@9432 | 933 | grid-template-columns: 10px (col-start) 250px (col-end) |
jackalmage@9432 | 934 | 10px (col-start) 250px (col-end) |
jackalmage@9432 | 935 | 10px (col-start) 250px (col-end) |
jackalmage@8787 | 936 | 10px (col-start) 250px (col-end) 10px; |
jackalmage@8786 | 937 | grid-template-rows: 1fr; |
jackalmage@7737 | 938 | } |
jackalmage@7737 | 939 | |
jackalmage@7737 | 940 | /* Equivalent definition. */ |
jackalmage@7737 | 941 | #grid { |
jackalmage@7737 | 942 | display: grid; |
jackalmage@8787 | 943 | grid-template-columns: repeat(4, 10px (col-start) 250px (col-end)) 10px; |
jackalmage@8786 | 944 | grid-template-rows: 1fr; |
jackalmage@7737 | 945 | } |
jackalmage@7249 | 946 | </style></pre> |
jackalmage@7737 | 947 | </div> |
jackalmage@7249 | 948 | |
jackalmage@9736 | 949 | <p class='issue'> |
jackalmage@9736 | 950 | François suggests adding an optional third argument with the same syntax as the second, |
jackalmage@9736 | 951 | as a joiner between repetitions. |
jackalmage@9736 | 952 | |
jackalmage@7249 | 953 | <h4 id='fr-unit'> |
jackalmage@7249 | 954 | Flexible Lengths: the ''fr'' unit</h4> |
jackalmage@7249 | 955 | |
jackalmage@7249 | 956 | <p> |
jackalmage@8858 | 957 | A <dfn export>flexible length</dfn> or <dfn><<flex>></dfn> is a dimension with the ''fr'' unit, |
jackalmage@8856 | 958 | which represents a fraction of the <a>free space</a> in the <a>grid container</a>. |
jackalmage@7251 | 959 | |
jackalmage@7249 | 960 | <p> |
jackalmage@8856 | 961 | The distribution of <a>free space</a> occurs after all non-flexible <a>sizing functions</a> have reached their maximum. |
jackalmage@8858 | 962 | The total size of such rows or columns is subtracted from the available space, yielding the <dfn export>free space</dfn>, |
fantasai@10071 | 963 | which is then divided among the flex-sized rows and columns in proportion to their <i>flex factor</i>. |
jackalmage@7741 | 964 | |
jackalmage@7741 | 965 | <p class='note'> |
jackalmage@8856 | 966 | Flexible lengths in a <a>track list</a> work similarly to flexible lengths with a zero base size in [[CSS3-FLEXBOX]]. |
jackalmage@7251 | 967 | |
jackalmage@7249 | 968 | <p> |
jackalmage@8856 | 969 | Each column or row's share of the <a>free space</a> can be computed as the column or row's |
fantasai@10071 | 970 | <code><flex> * <free space> / <sum of all <i>flex factors</i></code>. |
jackalmage@7741 | 971 | For the purpose of this calculation, |
jackalmage@7741 | 972 | a flexible length in the <var>min</var> position of a ''minmax()'' function is treated as ''0'' (an inflexible length). |
jackalmage@7251 | 973 | |
jackalmage@7249 | 974 | <p> |
jackalmage@7741 | 975 | When the available space is infinite |
jackalmage@8856 | 976 | (which happens when the <a>grid container</a>’s width or height is <a>indefinite</a>), |
jackalmage@8856 | 977 | flex-sized <a>grid tracks</a> are sized to their contents while retaining their respective proportions. |
jackalmage@9432 | 978 | The used size of each flex-sized <a>grid track</a> is computed by |
jackalmage@9432 | 979 | determining the ''max-content'' size of each flex-sized <a>grid track</a> |
fantasai@10071 | 980 | and dividing that size by the respective <i>flex factor</i> |
fantasai@10071 | 981 | to determine a “hypothetical ''1fr'' size”. |
fantasai@10071 | 982 | The maximum of those is used as the resolved ''1fr'' length (the <dfn>flex fraction</dfn>), |
fantasai@10071 | 983 | which is then multiplied by each <a>grid track</a>’s <i>flex factor</i> to determine its final size. |
jackalmage@7249 | 984 | |
jackalmage@8843 | 985 | |
jackalmage@8843 | 986 | <h4 id="subgrids"> |
jackalmage@9443 | 987 | Subgrids: the ''grid-template-rows/subgrid'' keyword</h4> |
jackalmage@8843 | 988 | |
jackalmage@8843 | 989 | <p> |
jackalmage@9432 | 990 | A <a>grid item</a> can itself be a <a>grid container</a> by giving it ''display: grid''; |
jackalmage@8843 | 991 | in this case the layout of its contents will be independent of the layout of the grid it participates in. |
jackalmage@8843 | 992 | |
jackalmage@8843 | 993 | <p> |
jackalmage@8856 | 994 | In some cases it might be necessary for the contents of multiple <a>grid items</a> to align to each other. |
jackalmage@8856 | 995 | A <a>grid container</a> that is itself a <a>grid item</a> |
jackalmage@8856 | 996 | can defer the definition of its rows or columns to its parent <a>grid container</a> |
jackalmage@9443 | 997 | by using the ''grid-template-rows/subgrid'' keyword in 'grid-template-rows' and/or 'grid-template-columns', |
jackalmage@8858 | 998 | making it a <dfn export>subgrid</dfn> in that dimension. |
jackalmage@8856 | 999 | In this case, the <a>grid items</a> of the <a>subgrid</a> |
jackalmage@8856 | 1000 | participate in sizing the <a>grid</a> of the parent <a>grid container</a>, |
jackalmage@8843 | 1001 | allowing the contents of both grids to align. |
jackalmage@8843 | 1002 | |
jackalmage@8843 | 1003 | <div class="example"> |
jackalmage@8843 | 1004 | <p> |
jackalmage@8843 | 1005 | For example, suppose we have a form consisting of a list of inputs with labels: |
jackalmage@8843 | 1006 | <pre> |
jackalmage@8843 | 1007 | <ul> |
jackalmage@8843 | 1008 | <li><label>Name:</label> <input name=fn> |
jackalmage@8843 | 1009 | <li><label>Address:</label> <input name=address> |
jackalmage@8843 | 1010 | <li><label>Phone:</label> <input name=phone> |
jackalmage@8843 | 1011 | </ul></pre> |
jackalmage@8843 | 1012 | |
jackalmage@8843 | 1013 | <p> |
jackalmage@8843 | 1014 | We want the labels and inputs to align, and we want to style each list item with a border. |
jackalmage@8843 | 1015 | This can be accomplished with subgrid layout: |
jackalmage@8843 | 1016 | |
jackalmage@8843 | 1017 | <pre> |
jackalmage@8843 | 1018 | ul { |
jackalmage@8843 | 1019 | display: grid; |
jackalmage@9786 | 1020 | grid-auto-flow: row; |
jackalmage@8843 | 1021 | grid-template-columns: auto 1fr; |
jackalmage@8843 | 1022 | } |
jackalmage@8843 | 1023 | li { |
fantasai@8977 | 1024 | display: grid; |
jackalmage@9443 | 1025 | grid: subgrid; |
jackalmage@8843 | 1026 | margin: 0.5em; |
jackalmage@8843 | 1027 | border: solid; |
jackalmage@8843 | 1028 | padding: 0.5em; |
jackalmage@8843 | 1029 | } |
jackalmage@8843 | 1030 | label { |
jackalmage@8843 | 1031 | grid-column: 1; |
jackalmage@8843 | 1032 | } |
jackalmage@8843 | 1033 | input { |
jackalmage@8843 | 1034 | grid-column: 2; |
jackalmage@8843 | 1035 | }</pre> |
jackalmage@8843 | 1036 | </div> |
jackalmage@8843 | 1037 | |
fantasai@9027 | 1038 | <p> |
fantasai@9027 | 1039 | A <a>subgrid</a> behaves just like a normal <a>grid container</a> except that: |
fantasai@9027 | 1040 | |
fantasai@9027 | 1041 | <ul style="list-style-type: lower-alpha"> |
fantasai@9027 | 1042 | <li> |
fantasai@9027 | 1043 | The number of explicit tracks is given by its <a>grid span</a>, |
fantasai@9027 | 1044 | rather than by 'grid-template-rows'/'grid-template-columns'. |
fantasai@9027 | 1045 | If the grid has an <a>automatic grid span</a>, |
fantasai@9027 | 1046 | the number of tracks is determined by the size of the <a>subgrid</a>’s <a>implicit grid</a>. |
fantasai@9027 | 1047 | |
fantasai@9027 | 1048 | <li> |
fantasai@9027 | 1049 | The <a>grid-placement properties</a> of the <a>subgrid</a>’s <a>grid items</a> |
fantasai@9027 | 1050 | are scoped to the lines covered by the subgrid. |
fantasai@9027 | 1051 | E.g., numeric indices count starting from the first line of the subgrid |
fantasai@9027 | 1052 | rather than the first line of the parent grid. |
fantasai@9027 | 1053 | |
fantasai@9027 | 1054 | <li> |
fantasai@9027 | 1055 | The <a>subgrid</a>'s own grid items participate in the sizing of its parent grid and are aligned to it. |
fantasai@9027 | 1056 | In this process, the sum of the item's margin, padding, and borders are applied as an extra layer of margin to the items at those edges. |
fantasai@9027 | 1057 | |
fantasai@9027 | 1058 | <div class="example"> |
fantasai@9027 | 1059 | <p>For example, if we have a 3×3 grid with the following tracks: |
fantasai@9027 | 1060 | <pre>#parent-grid { grid-template-columns: 300px auto 300px; }</pre> |
fantasai@9027 | 1061 | <p>If a subgrid covers the last two tracks, its first two columns correspond to the parent grid's last two columns, |
fantasai@9027 | 1062 | and any items positioned into those tracks participate in sizing the parent grid. |
fantasai@9027 | 1063 | Specifically, an item positioned in the first track of the subgrid |
fantasai@9027 | 1064 | influences the auto-sizing of the parent grid's middle track. |
fantasai@9027 | 1065 | <pre> |
fantasai@9027 | 1066 | #subgrid { grid-column: 2 / span 2; } /* cover parent's 2nd and 3rd tracks */ |
fantasai@9027 | 1067 | #subgrid :first-child { grid-column: 1; } /* subgrid's 1st track, parent grid's 2nd track */</pre> |
fantasai@9027 | 1068 | <p>If the subgrid has margins/borders/padding, |
fantasai@9027 | 1069 | the the size of those margins/borders/padding also influence sizing. |
fantasai@9027 | 1070 | For example, if the subgrid has 100px padding: |
fantasai@9027 | 1071 | <pre>#subgrid { padding: 100px; }</pre> |
fantasai@9027 | 1072 | Then when the parent grid auto-sizes its second track, |
fantasai@9027 | 1073 | it will be at least 100px wider than any items in the subgrid's first track, |
fantasai@9027 | 1074 | and any items in the subgrid's second track will be sized to fit a slot 200px wide (instead of 300px wide). |
fantasai@9027 | 1075 | </div> |
fantasai@9027 | 1076 | |
fantasai@9027 | 1077 | However, any overflow tracks |
fantasai@9027 | 1078 | (i.e. those outside the <i>explicit grid</i> when the <i>subgrid</i> has a <i>definite grid span</i>) |
fantasai@9027 | 1079 | do not correspond to any tracks in the parent grid; |
fantasai@9027 | 1080 | they effectively extend in a third dimension. |
fantasai@9027 | 1081 | <div class="example"> |
fantasai@9027 | 1082 | <p>For example, if a parent grid has adjacent tracks <var>A</var>, <var>B</var>, and <var>C</var>, |
fantasai@9027 | 1083 | and a ''span 1'' subgrid with an extra <i>implicit grid track</i> is placed in track <var>B</var>, |
fantasai@9027 | 1084 | the items in that <i>implicit grid track</i> are not considered part of track <var>B</var>. |
fantasai@9027 | 1085 | </div> |
fantasai@9027 | 1086 | |
fantasai@9027 | 1087 | <li> |
fantasai@9027 | 1088 | The <a>subgrid</a> is always stretched; |
fantasai@9027 | 1089 | the 'align-self'/'justify-self' properties on it are ignored. |
fantasai@9027 | 1090 | Any specified width/height constraints are also ignored. |
fantasai@9027 | 1091 | |
fantasai@9027 | 1092 | <li> |
fantasai@9027 | 1093 | Layoutwise, the <a>subgrid</a>’s <a>explicit grid</a> is always aligned with the corresponding section of the parent <a>grid</a>; |
fantasai@9027 | 1094 | the 'align-content'/'justify-content' properties on it are ignored. |
fantasai@9027 | 1095 | However, 'overflow' does apply, |
fantasai@9027 | 1096 | so the contents of the subgrid can be scrolled aside. |
fantasai@9027 | 1097 | (Note: the act of scrolling does not affect layout.) |
fantasai@9027 | 1098 | |
fantasai@9027 | 1099 | <li> |
jackalmage@9443 | 1100 | Explicit named lines can also be specified together with the ''grid-template-rows/subgrid'' keyword; |
fantasai@9027 | 1101 | these names apply (within the <a>subgrid</a>) to the corresponding lines of the parent <a>grid</a>. |
fantasai@9027 | 1102 | If the <a>subgrid</a> has an explicit <a>grid span</a>, |
fantasai@9027 | 1103 | any names specified for lines beyond the span are ignored. |
fantasai@9027 | 1104 | |
fantasai@9027 | 1105 | <div class="example"> |
fantasai@9027 | 1106 | <p>For example, if the subgrid above were specified with 5 names: |
fantasai@9027 | 1107 | <pre>#subgrid { grid-template-columns: subgrid (first) (second) (third) (fourth) (fifth); }</pre> |
fantasai@9027 | 1108 | <p>Items within the subgrid could be positioned using the first four line names; |
fantasai@9027 | 1109 | the last name would be ignored (as if it didn't exist), |
fantasai@9027 | 1110 | since the subgrid only covers four lines. |
fantasai@9027 | 1111 | </div> |
fantasai@9027 | 1112 | |
fantasai@9027 | 1113 | If the <a>subgrid</a> has an explicit <a>grid position</a> as well as an explicit <a>grid span</a>, |
fantasai@9027 | 1114 | it also automatically receives the line names specified for its parent <a>grid</a>. |
fantasai@9027 | 1115 | (In such cases the author can rely on the names specified in the parent grid, |
fantasai@9027 | 1116 | and does not need to duplicate those names in each subgrid declaration.) |
fantasai@9027 | 1117 | </ul> |
fantasai@9027 | 1118 | |
jackalmage@7743 | 1119 | <h4 id='resolved-track-list'> |
jackalmage@7249 | 1120 | Resolved Values</h4> |
jackalmage@7249 | 1121 | |
jackalmage@7249 | 1122 | <p> |
jackalmage@8786 | 1123 | The <a href="http://www.w3.org/TR/cssom/#resolved-values">resolved value</a> of the 'grid-template-rows' and 'grid-template-columns' properties is the used value, |
jackalmage@7743 | 1124 | serialized as follows: |
jackalmage@7743 | 1125 | |
jackalmage@7743 | 1126 | <ul> |
jackalmage@7743 | 1127 | <li> |
jackalmage@7743 | 1128 | Every track listed, |
jackalmage@7743 | 1129 | whether implicitly or explicitly created. |
jackalmage@7743 | 1130 | |
jackalmage@7743 | 1131 | <li> |
jackalmage@9432 | 1132 | Every track size given as a length in pixels, |
jackalmage@7743 | 1133 | regardless of sizing function. |
jackalmage@7743 | 1134 | |
jackalmage@7743 | 1135 | <li> |
jackalmage@7743 | 1136 | A contiguous run of two or more tracks that have the same size and associated line names |
jackalmage@7743 | 1137 | may be serialized with the ''repeat()'' notation. |
jackalmage@7743 | 1138 | </ul> |
jackalmage@7743 | 1139 | |
jackalmage@7743 | 1140 | <div class="example"> |
jackalmage@7743 | 1141 | <pre> |
jackalmage@7743 | 1142 | <style> |
jackalmage@7743 | 1143 | #grid { |
jackalmage@7743 | 1144 | width: 500px; |
jackalmage@8786 | 1145 | grid-template-columns: |
jackalmage@8787 | 1146 | (a) auto |
jackalmage@8787 | 1147 | (b) minmax(min-content, 1fr) |
jackalmage@8787 | 1148 | (b c d) repeat(2, (e) 40px) |
jackalmage@8787 | 1149 | repeat(5, auto); |
jackalmage@7743 | 1150 | } |
jackalmage@7249 | 1151 | </style> |
jackalmage@7249 | 1152 | <div id="grid"> |
jackalmage@8107 | 1153 | <div style="grid-column-start:1; width:50px"></div> |
jackalmage@8107 | 1154 | <div style="grid-column-start:9; width:50px"></div> |
jackalmage@7249 | 1155 | </div> |
jackalmage@7743 | 1156 | <script> |
jackalmage@7743 | 1157 | var gridElement = document.getElementById("grid"); |
jackalmage@7743 | 1158 | getComputedStyle(gridElement).gridDefinitionColumns; |
jackalmage@8787 | 1159 | // (a) 50px (b) 320px (b c d) repeat(2, (e) 40px) repeat(4, 0px) 50px |
jackalmage@7249 | 1160 | </script></pre> |
jackalmage@7743 | 1161 | </div> |
jackalmage@7743 | 1162 | |
jackalmage@8934 | 1163 | Note: In general, resolved values are the computed values, |
jackalmage@8934 | 1164 | except for a small list of legacy 2.1 properties. |
jackalmage@8934 | 1165 | However, compatibility with early implementations of this module |
jackalmage@8934 | 1166 | requires us to define 'grid-template-rows' and 'grid-template-columns' as returning used values. |
jackalmage@9432 | 1167 | Authors are recommended to use the |
jackalmage@8934 | 1168 | <a href="http://dev.w3.org/csswg/cssom/#the-getstyleutils-interface"><code>.rawComputedStyle</code> and <code>.usedStyle</code> attributes</a> |
jackalmage@8934 | 1169 | instead of <code>getComputedStyle()</code>. |
jackalmage@7249 | 1170 | |
jackalmage@7249 | 1171 | |
jackalmage@8786 | 1172 | <h3 id="grid-template-areas-property"> |
jackalmage@8786 | 1173 | Named Areas: the 'grid-template-areas' property</h3> |
jackalmage@7249 | 1174 | |
jackalmage@8856 | 1175 | <pre class='propdef'> |
jackalmage@8856 | 1176 | Name: grid-template-areas |
jackalmage@8856 | 1177 | Value: none | <<string>>+ |
jackalmage@8856 | 1178 | Initial: none |
jackalmage@8856 | 1179 | Applies to: <a>grid containers</a> |
jackalmage@8856 | 1180 | Inherited: no |
jackalmage@8856 | 1181 | Percentages: n/a |
jackalmage@8856 | 1182 | Media: visual |
jackalmage@8856 | 1183 | Computed value: specified value |
jackalmage@8856 | 1184 | </pre> |
jackalmage@7249 | 1185 | |
jackalmage@7249 | 1186 | <p> |
jackalmage@8858 | 1187 | This property specifies <dfn export title="named grid area">named grid areas</dfn>, |
jackalmage@8856 | 1188 | which are not associated with any particular <a>grid item</a>, |
jackalmage@8856 | 1189 | but can be referenced from the <a>grid-placement properties</a>. |
jackalmage@8786 | 1190 | The syntax of the 'grid-template-areas' property also provides a visualization |
jackalmage@8856 | 1191 | of the structure of the <a>grid</a>, |
jackalmage@8856 | 1192 | making the overall layout of the <a>grid container</a> easier to understand. |
jackalmage@7251 | 1193 | |
jackalmage@7249 | 1194 | <p> |
jackalmage@7660 | 1195 | Values have the following meanings: |
jackalmage@7660 | 1196 | |
jackalmage@8856 | 1197 | <dl dfn-for="grid-template-areas" dfn-type=value> |
jackalmage@8856 | 1198 | <dt><dfn>none</dfn> |
jackalmage@7660 | 1199 | <dd> |
jackalmage@8856 | 1200 | The <a>grid container</a> doesn't define any <a>named grid areas</a>. |
jackalmage@8856 | 1201 | |
jackalmage@8856 | 1202 | <dt><dfn><<string>>+</dfn> |
jackalmage@7660 | 1203 | <dd> |
jackalmage@8786 | 1204 | A row is created for every separate string listed for the 'grid-template-areas' property, |
jackalmage@9652 | 1205 | and a column is created for each cell in the string, |
jackalmage@9651 | 1206 | when parsed as follows: |
jackalmage@9651 | 1207 | |
jackalmage@9652 | 1208 | Tokenize the string into a list of the following tokens, |
jackalmage@9652 | 1209 | using longest-match semantics: |
jackalmage@9652 | 1210 | |
jackalmage@9652 | 1211 | <ul dfn-type="dfn"> |
jackalmage@9651 | 1212 | <li> |
jackalmage@9652 | 1213 | A sequence of <a>name code points</a>, |
jackalmage@9652 | 1214 | representing a <dfn>named cell token</dfn> |
jackalmage@9652 | 1215 | with a name consisting of its code points. |
jackalmage@9651 | 1216 | <li> |
jackalmage@9652 | 1217 | A "." (U+002E FULL STOP), |
jackalmage@9652 | 1218 | representing a <dfn>null cell token</dfn>. |
jackalmage@9652 | 1219 | |
jackalmage@9652 | 1220 | <li> |
jackalmage@9653 | 1221 | A sequence of <a>whitespace</a>, |
jackalmage@9652 | 1222 | representing nothing |
jackalmage@9652 | 1223 | (do not produce a token). |
jackalmage@9652 | 1224 | |
jackalmage@9652 | 1225 | <li> |
jackalmage@9652 | 1226 | A sequence of any other characters, |
jackalmage@9652 | 1227 | representing a <dfn>trash token</dfn>. |
jackalmage@9652 | 1228 | </ul> |
jackalmage@9651 | 1229 | |
jackalmage@9653 | 1230 | Note: These rules can produce cell names that do not match the <<ident>> syntax, |
jackalmage@9651 | 1231 | such as "1st 2nd 3rd", |
jackalmage@9651 | 1232 | which requires escaping when referencing those areas by name in other properties, |
jackalmage@9651 | 1233 | like ''grid-row: \31st;'' to reference the area named ''1st''. |
jackalmage@7660 | 1234 | |
jackalmage@7660 | 1235 | <ul> |
jackalmage@7660 | 1236 | <li> |
jackalmage@9651 | 1237 | A <a>null cell token</a> represents an unnamed area in the <a>grid container</a>. |
jackalmage@7660 | 1238 | |
jackalmage@7660 | 1239 | <li> |
jackalmage@9651 | 1240 | A <a>named cell token</a> creates a <a>named grid area</a> with the same name. |
jackalmage@9651 | 1241 | Multiple <a>named cell tokens</a> within and between rows |
jackalmage@8856 | 1242 | create a single <a>named grid area</a> that spans the corresponding <a>grid cells</a>. |
jackalmage@9652 | 1243 | |
jackalmage@9652 | 1244 | <li> |
jackalmage@9652 | 1245 | A <a>trash token</a> is a syntax error, |
jackalmage@9652 | 1246 | and makes the declaration invalid. |
jackalmage@7660 | 1247 | </ul> |
jackalmage@7660 | 1248 | |
jackalmage@9651 | 1249 | All strings must have the same number of columns, |
jackalmage@9651 | 1250 | or else the declaration is invalid. |
jackalmage@9651 | 1251 | If a <a>named grid area</a> spans multiple <a>grid cells</a>, |
jackalmage@9651 | 1252 | but those cells do not form a single filled-in rectangle, |
jackalmage@9651 | 1253 | the declaration is invalid. |
jackalmage@9651 | 1254 | |
jackalmage@9651 | 1255 | Note: Non-rectangular or disconnected regions may be permitted in a future version of this module. |
jackalmage@7660 | 1256 | </dl> |
jackalmage@7660 | 1257 | |
jackalmage@7660 | 1258 | |
jackalmage@7660 | 1259 | <div class='example'> |
jackalmage@7660 | 1260 | <p> |
jackalmage@9432 | 1261 | In this example, the 'grid-template-areas' property is used to create a page layout |
jackalmage@7660 | 1262 | where areas are defined for header content (<code>head</code>), |
jackalmage@7660 | 1263 | navigational content (<code>nav</code>), |
jackalmage@7660 | 1264 | footer content (<code>foot</code>), |
jackalmage@9432 | 1265 | and main content (<code>main</code>). |
jackalmage@7660 | 1266 | Accordingly, the template creates three rows and two columns, |
jackalmage@8856 | 1267 | with four <a>named grid areas</a>. |
jackalmage@9432 | 1268 | The <code>head</code> area spans both columns and the first row of the grid. |
jackalmage@7660 | 1269 | |
jackalmage@7660 | 1270 | <pre> |
jackalmage@7249 | 1271 | <style type="text/css"> |
jackalmage@7660 | 1272 | #grid { |
jackalmage@7660 | 1273 | display: grid; |
jackalmage@8786 | 1274 | grid-template-areas: "head head" |
jackalmage@8786 | 1275 | "nav main" |
jackalmage@8786 | 1276 | "foot . " |
jackalmage@7660 | 1277 | } |
jackalmage@7660 | 1278 | #grid > header { grid-area: head; } |
jackalmage@7660 | 1279 | #grid > nav { grid-area: nav; } |
jackalmage@7660 | 1280 | #grid > main { grid-area: main; } |
jackalmage@7660 | 1281 | #grid > footer { grid-area: foot; } |
jackalmage@7249 | 1282 | </style></pre> |
jackalmage@7660 | 1283 | </div> |
jackalmage@7249 | 1284 | |
jackalmage@8837 | 1285 | <h4 id="implicit-named-lines"> |
jackalmage@8837 | 1286 | Implicit Named Lines</h4> |
jackalmage@8837 | 1287 | |
jackalmage@8837 | 1288 | <p> |
jackalmage@8858 | 1289 | The 'grid-template-areas' property creates <dfn export title="implicit named line">implicit named lines</dfn> from the <a>named grid areas</a> in the template. |
jackalmage@8856 | 1290 | For each <a>named grid area</a> <var>foo</var>, four <a>implicit named lines</a> are created: |
jackalmage@8856 | 1291 | two named ''<var>foo</var>-start'', naming the row-start and column-start lines of the <a>named grid area</a>, |
jackalmage@8856 | 1292 | and two named ''<var>foo</var>-end'', naming the row-end and column-end lines of the <a>named grid area</a>. |
jackalmage@8837 | 1293 | |
jackalmage@8837 | 1294 | <p> |
jackalmage@8837 | 1295 | These named lines behave just like any other named line, |
jackalmage@8837 | 1296 | except that they do not appear in the value of 'grid-template-rows'/'grid-template-columns'. |
jackalmage@8837 | 1297 | Even if an explicit line of the same name is defined, |
jackalmage@8837 | 1298 | the implicit named lines are just more lines with the same name. |
jackalmage@8788 | 1299 | |
jackalmage@9434 | 1300 | <h4 id="implicit-named-areas"> |
jackalmage@9434 | 1301 | Implicit Named Areas</h4> |
jackalmage@9434 | 1302 | |
jackalmage@9434 | 1303 | <p> |
jackalmage@9434 | 1304 | Since a <i>named grid area</i> is referenced by the <i>implicit named lines</i> it produces, |
jackalmage@9434 | 1305 | explicitly adding named lines of the same form (''foo-start''/''foo-end'') |
jackalmage@9434 | 1306 | effectively creates a <i>named grid area</i>. |
jackalmage@9434 | 1307 | Such <dfn export title="implicit named area">implicit named areas</dfn> do not appear in the value of 'grid-template-areas', |
jackalmage@9434 | 1308 | but can still be referenced by the <a>grid-placement properties</a>. |
jackalmage@9434 | 1309 | |
jackalmage@8883 | 1310 | <h3 id='explicit-grid-shorthand'> |
fantasai@8943 | 1311 | Explicit Grid Shorthand: the 'grid-template' property</h3> |
jackalmage@8788 | 1312 | |
jackalmage@8856 | 1313 | <pre class='propdef'> |
jackalmage@8856 | 1314 | Name: grid-template |
jackalmage@9914 | 1315 | Value: none | subgrid | <<'grid-template-columns'>> / <<'grid-template-rows'>> |<br> [ <<track-list>> / ]? [ <<line-names>>? <<string>> <<track-size>>? <<line-names>>? ]+ |
jackalmage@8856 | 1316 | Initial: see individual properties |
jackalmage@8856 | 1317 | Applies to: <a>grid containers</a> |
jackalmage@8856 | 1318 | Inherited: see individual properties |
jackalmage@8856 | 1319 | Percentages: see individual properties |
jackalmage@8856 | 1320 | Media: visual |
jackalmage@8856 | 1321 | Computed value: see individual properties |
jackalmage@8856 | 1322 | </pre> |
jackalmage@8788 | 1323 | |
jackalmage@8788 | 1324 | <p> |
jackalmage@8788 | 1325 | The 'grid-template' property is a shorthand for setting |
jackalmage@8788 | 1326 | 'grid-template-columns', 'grid-template-rows', and 'grid-template-areas' in a single declaration. |
jackalmage@9443 | 1327 | It has several distinct syntax forms: |
jackalmage@8788 | 1328 | |
jackalmage@8856 | 1329 | <dl dfn-for=grid-template dfn-type=value> |
jackalmage@8856 | 1330 | <dt><dfn>none</dfn> |
jackalmage@8788 | 1331 | <dd> |
jackalmage@8856 | 1332 | Sets all three properties to their initial values (<a value for=grid-template-rows>none</a>). |
jackalmage@8856 | 1333 | |
jackalmage@9443 | 1334 | <dt><dfn>subgrid</dfn> |
jackalmage@9443 | 1335 | <dd> |
jackalmage@9443 | 1336 | Sets 'grid-template-rows' and 'grid-template-columns' to ''grid-template-rows/subgrid'', |
jackalmage@9443 | 1337 | and 'grid-template-areas' to its initial value. |
jackalmage@9443 | 1338 | |
jackalmage@8856 | 1339 | <dt><dfn><<'grid-template-columns'>> / <<'grid-template-rows'>></dfn> |
jackalmage@8788 | 1340 | <dd> |
jackalmage@8788 | 1341 | Sets 'grid-template-columns' and 'grid-template-rows' to the specified values, respectively, |
jackalmage@8856 | 1342 | and sets 'grid-template-areas' to <a value for=grid-template-areas>none</a>. |
jackalmage@8788 | 1343 | |
jackalmage@8788 | 1344 | <div class='example'> |
jackalmage@8788 | 1345 | <pre>grid-template: auto 1fr auto / auto 1fr;</pre> |
jackalmage@8788 | 1346 | |
jackalmage@8788 | 1347 | <p> |
jackalmage@8788 | 1348 | is equivalent to |
jackalmage@8788 | 1349 | |
jackalmage@8788 | 1350 | <pre> |
jackalmage@8788 | 1351 | grid-template-columns: auto 1fr auto; |
jackalmage@8788 | 1352 | grid-template-rows: auto 1fr; |
jackalmage@8788 | 1353 | grid-template-areas: none;</pre> |
jackalmage@8788 | 1354 | </div> |
jackalmage@8788 | 1355 | |
jackalmage@8856 | 1356 | <dt><dfn>[ <<track-list>> / ]?<br> |
jackalmage@8856 | 1357 | [ <<line-names>>? <<string>> [ <<track-size>> <<line-names>> ]? ]+</dfn> |
jackalmage@8788 | 1358 | <dd> |
jackalmage@8788 | 1359 | <ul> |
jackalmage@8788 | 1360 | <li> |
jackalmage@8788 | 1361 | Sets 'grid-template-columns' to the track listing specified before the slash |
jackalmage@8856 | 1362 | (or <a value for=grid-template-columns>none</a>, if not specified). |
jackalmage@8788 | 1363 | |
jackalmage@8788 | 1364 | <li> |
jackalmage@8788 | 1365 | Sets 'grid-template-areas' to the strings listed after the slash. |
jackalmage@8788 | 1366 | |
jackalmage@8788 | 1367 | <li> |
jackalmage@8856 | 1368 | Sets 'grid-template-rows' to the <<track-size>>s following each string |
jackalmage@8856 | 1369 | (filling in <a value for=grid-template-rows>auto</a> for any missing sizes), |
jackalmage@8788 | 1370 | and splicing in the named lines defined before/after each size. |
jackalmage@8788 | 1371 | </ul> |
jackalmage@8788 | 1372 | |
jackalmage@8788 | 1373 | <p> |
jackalmage@8789 | 1374 | This syntax allows the author to align track names and sizes inline with their respective grid areas. |
jackalmage@8788 | 1375 | |
jackalmage@8788 | 1376 | <div class='example'> |
jackalmage@8788 | 1377 | <pre> |
jackalmage@9432 | 1378 | grid-template: auto 1fr auto / |
jackalmage@8788 | 1379 | (header-top) "a a a" (header-bottom) |
jackalmage@8788 | 1380 | (main-top) "b b b" 1fr (main-bottom);</pre> |
jackalmage@8788 | 1381 | |
jackalmage@8788 | 1382 | <p> |
jackalmage@8788 | 1383 | is equivalent to |
jackalmage@8788 | 1384 | |
jackalmage@8788 | 1385 | <pre> |
jackalmage@8788 | 1386 | grid-template-columns: auto 1fr auto; |
jackalmage@8788 | 1387 | grid-template-rows: (header-top) auto (header-bottom main-top) 1fr (main-bottom); |
jackalmage@9432 | 1388 | grid-template-areas: "a a a" |
jackalmage@8788 | 1389 | "b b b";</pre> |
jackalmage@8788 | 1390 | </div> |
jackalmage@8788 | 1391 | </dl> |
jackalmage@8788 | 1392 | |
fantasai@8943 | 1393 | Note: The 'grid' shorthand accepts the same syntax, |
fantasai@8943 | 1394 | but also resets the implicit grid properties to their initial values. |
fantasai@8943 | 1395 | Unless authors want those to cascade in separately, |
fantasai@8943 | 1396 | it is therefore recommended to use 'grid' instead of 'grid-template'. |
jackalmage@8788 | 1397 | |
jackalmage@8844 | 1398 | <h2 id='implicit-grids'> |
jackalmage@8844 | 1399 | The Implicit Grid</h2> |
jackalmage@8844 | 1400 | |
jackalmage@8844 | 1401 | <p> |
jackalmage@8856 | 1402 | While 'grid-template' and its longhand properties define the <a>explicit grid</a>, |
jackalmage@8856 | 1403 | <a>grid items</a> can be positioned outside of these bounds. |
jackalmage@8856 | 1404 | This causes the <a>grid container</a> to generate <a>implicit grid tracks</a>, |
jackalmage@8858 | 1405 | forming the <dfn export>implicit grid</dfn>. |
jackalmage@8856 | 1406 | The 'grid-auto-rows' and 'grid-auto-columns' properties size these <a>implicit grid tracks</a>. |
jackalmage@8844 | 1407 | |
jackalmage@8844 | 1408 | <p> |
jackalmage@8856 | 1409 | The 'grid-auto-flow' property controls auto-placement of <a>grid items</a> |
jackalmage@8844 | 1410 | without an explicit position. |
jackalmage@8856 | 1411 | Once the <a>explicit grid</a> is filled |
jackalmage@8856 | 1412 | (or if there is no <a>explicit grid</a>) |
jackalmage@8856 | 1413 | auto-placement will also cause the generation of <a>implicit grid tracks</a>. |
jackalmage@8844 | 1414 | |
jackalmage@7249 | 1415 | <h3 id='auto-tracks'> |
jackalmage@8844 | 1416 | Sizing Auto-generated Rows and Columns: the 'grid-auto-rows' and 'grid-auto-columns' properties</h3> |
jackalmage@7249 | 1417 | |
jackalmage@8856 | 1418 | <pre class='propdef'> |
jackalmage@8856 | 1419 | Name: grid-auto-columns, grid-auto-rows |
jackalmage@8856 | 1420 | Value: <<track-size>> |
jackalmage@8856 | 1421 | Initial: auto |
jackalmage@8856 | 1422 | Applies to: <a>grid containers</a> |
jackalmage@8856 | 1423 | Inherited: no |
jackalmage@8856 | 1424 | Percentages: see <a href="#track-sizing">Track Sizing</a> |
jackalmage@8856 | 1425 | Media: visual |
jackalmage@8856 | 1426 | Computed value: see <a href="#track-sizing">Track Sizing</a> |
jackalmage@8856 | 1427 | </pre> |
jackalmage@7249 | 1428 | |
jackalmage@7249 | 1429 | <p> |
jackalmage@7659 | 1430 | If a grid item is positioned into a row or column that is not explicitly sized |
jackalmage@8792 | 1431 | by 'grid-template-rows' or 'grid-template-columns', |
jackalmage@8858 | 1432 | <dfn export title="implicit grid track|implicit grid row|implicit grid column">implicit grid tracks</dfn> are created to hold it. |
jackalmage@7659 | 1433 | This can happen either by explicitly positioning into a row or column that is out of range, |
jackalmage@8856 | 1434 | or by the <a>auto-placement algorithm</a> creating additional rows or columns. |
jackalmage@7659 | 1435 | The 'grid-auto-columns' and 'grid-auto-rows' properties specify the size of such implicitly-created tracks. |
jackalmage@7659 | 1436 | |
jackalmage@7659 | 1437 | <div class='example'> |
jackalmage@7249 | 1438 | <p> |
jackalmage@8856 | 1439 | This example illustrates the sizing of <a>implicit grid tracks</a>. |
jackalmage@8856 | 1440 | Note that <a>grid item</a> B is positioned on <a>grid line</a> 5, |
jackalmage@8856 | 1441 | which automatically creates <strong>four</strong> <a>implicit grid columns</a>. |
jackalmage@7659 | 1442 | However, only two of them |
jackalmage@9432 | 1443 | (the first and the last) |
jackalmage@8856 | 1444 | are occupied by any <a>grid items</a>, |
jackalmage@8856 | 1445 | so the two empty <a>grid tracks</a> |
jackalmage@7659 | 1446 | collapse to zero width. |
jackalmage@7659 | 1447 | |
jackalmage@7659 | 1448 | <div class="figure"> |
jackalmage@7659 | 1449 | <p> |
fantasai@8909 | 1450 | <img alt="" src="images/implicit-columns-and-rows.png" /> |
jackalmage@7659 | 1451 | |
jackalmage@7659 | 1452 | <p class="caption"> |
jackalmage@7659 | 1453 | A Grid with an implicit row and four implicit columns, two of which are zero-sized. |
jackalmage@7659 | 1454 | </div> |
jackalmage@7659 | 1455 | |
jackalmage@7659 | 1456 | <pre> |
jackalmage@7249 | 1457 | <style type="text/css"> |
jackalmage@9432 | 1458 | #grid { |
jackalmage@9432 | 1459 | display: grid; |
jackalmage@9432 | 1460 | grid-template-columns: 20px; |
jackalmage@8786 | 1461 | grid-template-rows: 20px } |
jackalmage@7659 | 1462 | #A { grid-column: 1; grid-row: 1; } |
jackalmage@7659 | 1463 | #B { grid-column: 5; grid-row: 1 / span 2; } |
jackalmage@7659 | 1464 | #C { grid-column: 1 / span 2; grid-row: 2; } |
jackalmage@7249 | 1465 | </style> |
jackalmage@7249 | 1466 | |
jackalmage@7249 | 1467 | <div id="grid"> |
jackalmage@7249 | 1468 | <div id="A">A</div> |
jackalmage@7249 | 1469 | <div id="B">B</div> |
jackalmage@7249 | 1470 | <div id="C">C</div> |
jackalmage@7249 | 1471 | </div></pre> |
jackalmage@7659 | 1472 | </div> |
jackalmage@7249 | 1473 | |
jackalmage@7249 | 1474 | <h3 id="grid-auto-flow-property"> |
jackalmage@7249 | 1475 | Automatic Placement: the 'grid-auto-flow' property</h3> |
jackalmage@7249 | 1476 | |
jackalmage@8856 | 1477 | <pre class='propdef'> |
jackalmage@8856 | 1478 | Name: grid-auto-flow |
jackalmage@9786 | 1479 | Value: none | [ [ row | column ] && dense? ] |
jackalmage@8939 | 1480 | Initial: none |
jackalmage@8856 | 1481 | Applies to: <a>grid containers</a> |
jackalmage@8856 | 1482 | Inherited: no |
jackalmage@8856 | 1483 | Percentages: n/a |
jackalmage@8856 | 1484 | Media: visual |
jackalmage@8856 | 1485 | Computed value: specified value |
jackalmage@8856 | 1486 | </pre> |
jackalmage@7249 | 1487 | |
jackalmage@7249 | 1488 | <p> |
jackalmage@8935 | 1489 | <a>Grid items</a> that aren't explicitly placed are automatically placed into an unoccupied space in the <a>grid container</a>. |
jackalmage@9432 | 1490 | The 'grid-auto-flow' property controls the direction in which the search for unoccupied space takes place, |
jackalmage@7656 | 1491 | and whether rows or columns are added as needed to accommodate the content. |
jackalmage@7656 | 1492 | |
jackalmage@8856 | 1493 | <dl dfn-for=grid-auto-flow dfn-type=value> |
jackalmage@8934 | 1494 | <dt><dfn>none</dfn> |
jackalmage@8934 | 1495 | <dd> |
jackalmage@8934 | 1496 | Rather than use the auto-placement algorithm, |
jackalmage@8934 | 1497 | auto-placed <a>grid items</a> are simply positioned according to the 'grid-auto-position' property. |
jackalmage@8934 | 1498 | |
jackalmage@9786 | 1499 | <dt><dfn>row</dfn> |
jackalmage@7656 | 1500 | <dd> |
jackalmage@8944 | 1501 | The <a>auto-placement algorithm</a> places items |
jackalmage@7656 | 1502 | by filling each row in turn, |
jackalmage@7656 | 1503 | adding new rows as necessary. |
jackalmage@7656 | 1504 | |
jackalmage@9786 | 1505 | <dt><dfn>column</dfn> |
jackalmage@7656 | 1506 | <dd> |
jackalmage@8944 | 1507 | The <a>auto-placement algorithm</a> places items |
jackalmage@7656 | 1508 | by filling each column in turn, |
jackalmage@7656 | 1509 | adding new columns as necessary. |
jackalmage@8835 | 1510 | |
jackalmage@8856 | 1511 | <dt><dfn>dense</dfn> |
jackalmage@8835 | 1512 | <dd> |
jackalmage@8835 | 1513 | If specified, the auto-placement algorithm uses a "dense" packing algorithm, |
jackalmage@8835 | 1514 | which attempts to fill in holes in the grid if smaller items come up later. |
jackalmage@8835 | 1515 | (By default, the auto-placement algorithm is "sparse", |
jackalmage@8944 | 1516 | permanently skipping spaces that it can't fill with the current <a>grid item</a>.) |
jackalmage@8835 | 1517 | |
jackalmage@8856 | 1518 | Note: This may cause items to appear out-of-order. |
jackalmage@7656 | 1519 | </dl> |
jackalmage@7249 | 1520 | |
jackalmage@8934 | 1521 | Note: A future level of this module is expected to add a value that flows auto-positioned items together into a single “default” cell. |
jackalmage@8791 | 1522 | |
jackalmage@8939 | 1523 | <p class='issue'> |
jackalmage@9786 | 1524 | Win8 compat might require the ''grid-auto-flow/none'' value to stay the initial value, |
fantasai@8942 | 1525 | but it's not a very good value, |
fantasai@8942 | 1526 | because by default the entire contents of a grid container will end up stacked on top of each other. |
fantasai@8942 | 1527 | See <a href="http://lists.w3.org/Archives/Public/www-archive/2013Aug/0024.html">proposals to address this</a> |
fantasai@8942 | 1528 | while addressing use cases and back-compat. |
jackalmage@8939 | 1529 | |
jackalmage@7832 | 1530 | <p> |
jackalmage@9752 | 1531 | Auto-placement takes <a>grid items</a> in <a>order-modified document order</a>. |
jackalmage@7249 | 1532 | |
jackalmage@7656 | 1533 | <div class='example'> |
jackalmage@7656 | 1534 | <p> |
jackalmage@7656 | 1535 | In the following example, there are three columns, each auto-sized to their contents. |
jackalmage@9432 | 1536 | No rows are explicitly defined. |
jackalmage@9786 | 1537 | The 'grid-auto-flow' property is ''grid-auto-flow/row'' |
jackalmage@9432 | 1538 | which instructs the grid to search across its three columns starting with the first row, |
jackalmage@9432 | 1539 | then the next, |
jackalmage@8856 | 1540 | adding rows as needed until sufficient space is located to accommodate the position of any auto-placed <a>grid item</a>. |
jackalmage@7656 | 1541 | |
jackalmage@7656 | 1542 | <div class="figure"> |
jackalmage@7656 | 1543 | <p> |
fantasai@8909 | 1544 | <img alt="Image: A form arranged using automatic placement." src="images/auto-placed-form.png" /> |
jackalmage@7656 | 1545 | |
jackalmage@7656 | 1546 | <p class="caption">A form arranged using automatic placement. |
jackalmage@7656 | 1547 | </div> |
jackalmage@7656 | 1548 | |
jackalmage@7656 | 1549 | <pre> |
jackalmage@7656 | 1550 | <style type="text/css"> |
jackalmage@7656 | 1551 | form { |
jackalmage@7656 | 1552 | display: grid; |
jackalmage@7656 | 1553 | /* Define three columns, all content-sized, |
jackalmage@7656 | 1554 | and name the corresponding lines. */ |
jackalmage@8787 | 1555 | grid-template-columns: (labels) auto (controls) auto (oversized) auto; |
jackalmage@9786 | 1556 | grid-auto-flow: row; |
jackalmage@7656 | 1557 | } |
jackalmage@7656 | 1558 | form > label { |
jackalmage@9432 | 1559 | /* Place all labels in the "labels" column and |
jackalmage@7656 | 1560 | automatically find the next available row. */ |
jackalmage@8787 | 1561 | grid-column: labels; |
jackalmage@7656 | 1562 | grid-row: auto; |
jackalmage@7656 | 1563 | } |
jackalmage@7656 | 1564 | form > input, form > select { |
jackalmage@9432 | 1565 | /* Place all controls in the "controls" column and |
jackalmage@7656 | 1566 | automatically find the next available row. */ |
jackalmage@8787 | 1567 | grid-column: controls; |
jackalmage@7656 | 1568 | grid-row: auto; |
jackalmage@7656 | 1569 | } |
jackalmage@7656 | 1570 | |
jackalmage@7656 | 1571 | #department { |
jackalmage@9432 | 1572 | /* Auto place this item in the "oversized" column |
jackalmage@9432 | 1573 | in the first row where an area that spans three rows |
jackalmage@9432 | 1574 | won't overlap other explicitly placed items or areas |
jackalmage@7656 | 1575 | or any items automatically placed prior to this area. */ |
jackalmage@8787 | 1576 | grid-column: oversized; |
jackalmage@7656 | 1577 | grid-row: span 3; |
jackalmage@7656 | 1578 | } |
jackalmage@7656 | 1579 | |
jackalmage@9432 | 1580 | /* Place all the buttons of the form |
jackalmage@7656 | 1581 | in the explicitly defined grid area. */ |
jackalmage@7656 | 1582 | #buttons { |
jackalmage@7656 | 1583 | grid-row: auto; |
jackalmage@7656 | 1584 | |
jackalmage@9432 | 1585 | /* Ensure the button area spans the entire grid element |
jackalmage@7656 | 1586 | in the row axis. */ |
jackalmage@8787 | 1587 | grid-column: 1 / -1; |
jackalmage@7656 | 1588 | text-align: end; |
jackalmage@7656 | 1589 | } |
jackalmage@7656 | 1590 | </style> |
jackalmage@7656 | 1591 | <form> |
jackalmage@7656 | 1592 | <label for="firstname">First name:</label> |
jackalmage@7656 | 1593 | <input type="text" id="firstname" name="firstname" /> |
jackalmage@7656 | 1594 | <label for="lastname">Last name:</label> |
jackalmage@7656 | 1595 | <input type="text" id="lastname" name="lastname" /> |
jackalmage@7656 | 1596 | <label for="address">Address:</label> |
jackalmage@7656 | 1597 | <input type="text" id="address" name="address" /> |
jackalmage@7656 | 1598 | <label for="address2">Address 2:</label> |
jackalmage@7656 | 1599 | <input type="text" id="address2" name="address2" /> |
jackalmage@7656 | 1600 | <label for="city">City:</label> |
jackalmage@7656 | 1601 | <input type="text" id="city" name="city" /> |
jackalmage@7656 | 1602 | <label for="state">State:</label> |
jackalmage@7656 | 1603 | <select type="text" id="state" name="state"> |
jackalmage@7656 | 1604 | <option value="WA">Washington</option> |
jackalmage@7656 | 1605 | </select> |
jackalmage@7656 | 1606 | <label for="zip">Zip:</label> |
jackalmage@7656 | 1607 | <input type="text" id="zip" name="zip" /> |
jackalmage@7656 | 1608 | |
jackalmage@7656 | 1609 | <div id="department"> |
jackalmage@7656 | 1610 | <label for="department">Department:</label> |
jackalmage@7656 | 1611 | <select id="department" name="department" multiple> |
jackalmage@7656 | 1612 | <option value="finance">Finance</option> |
jackalmage@7656 | 1613 | <option value="humanresources">Human Resources</option> |
jackalmage@7656 | 1614 | <option value="marketing">Marketing</option> |
jackalmage@7656 | 1615 | </select> |
jackalmage@7656 | 1616 | </div> |
jackalmage@7656 | 1617 | |
jackalmage@7656 | 1618 | <div id="buttons"> |
jackalmage@7656 | 1619 | <button id="cancel">Cancel</button> |
jackalmage@7656 | 1620 | <button id="back">Back</button> |
jackalmage@7656 | 1621 | <button id="next">Next</button> |
jackalmage@7656 | 1622 | </div> |
jackalmage@7656 | 1623 | </form></pre> |
jackalmage@7656 | 1624 | </div> |
jackalmage@7656 | 1625 | |
jackalmage@7249 | 1626 | <h4 id='auto-placement-algo'> |
jackalmage@7249 | 1627 | Automatic Grid Item Placement Algorithm</h4> |
jackalmage@8944 | 1628 | |
jackalmage@9434 | 1629 | The following <dfn export title="auto-placement|auto-placement algorithm">auto-placement algorithm</dfn> places <a>grid items</a> with <a>automatic grid positions</a> into a <a>definite grid position</a>. |
jackalmage@8944 | 1630 | |
jackalmage@8944 | 1631 | To aid in clarity, |
jackalmage@9786 | 1632 | this algorithm is written with the assumption that 'grid-auto-flow' is set to ''grid-auto-flow/row''. |
jackalmage@9786 | 1633 | If it is instead set to ''grid-auto-flow/column'', |
jackalmage@8944 | 1634 | swap all mentions of rows and columns in this algorithm. |
jackalmage@8944 | 1635 | |
jackalmage@8944 | 1636 | For the purpose of this algorithm, |
jackalmage@8944 | 1637 | an <dfn>occupied grid cell</dfn> |
jackalmage@8944 | 1638 | is any <a>grid cell</a> which is contained within |
jackalmage@8944 | 1639 | any <a>named grid area</a> |
jackalmage@8944 | 1640 | or the <a>grid area</a> of any previously-positioned <a>grid item</a>. |
jackalmage@7251 | 1641 | |
jackalmage@7249 | 1642 | <ol> |
jackalmage@7249 | 1643 | <li> |
jackalmage@8944 | 1644 | <b>Position anything that's not auto-positioned.</b> |
jackalmage@8944 | 1645 | |
jackalmage@9432 | 1646 | Before auto-positioning anything, |
jackalmage@8944 | 1647 | position every <a>grid item</a> |
fantasai@8956 | 1648 | with a <a>definite grid position</a> in both axes. |
jackalmage@7251 | 1649 | |
jackalmage@7249 | 1650 | <li> |
jackalmage@8944 | 1651 | <b>Process the items locked to a given row.</b> |
jackalmage@8944 | 1652 | |
jackalmage@8944 | 1653 | For each <a>grid item</a> with a <a>definite row position</a> |
jackalmage@8944 | 1654 | (that is, the 'grid-row-start' and 'grid-row-end' properties define a <a>definite grid position</a>), |
jackalmage@9752 | 1655 | in <a>order-modified document order</a>, |
jackalmage@8944 | 1656 | position its <a>inline-start</a> edge |
jackalmage@8944 | 1657 | to the earliest (smallest positive index) line index |
jackalmage@8944 | 1658 | that ensures this item’s <a>grid area</a> will not overlap any <a>occupied grid cells</a>. |
jackalmage@8944 | 1659 | |
jackalmage@7249 | 1660 | <li> |
jackalmage@8944 | 1661 | <b>Determine the number of columns in the implicit grid.</b> |
jackalmage@8944 | 1662 | |
jackalmage@8944 | 1663 | Set the number of columns in the <a>implicit grid</a> to the larger of: |
jackalmage@8944 | 1664 | |
jackalmage@8944 | 1665 | <ul> |
jackalmage@8944 | 1666 | <li> |
jackalmage@8944 | 1667 | The number of columns in the <a>explicit grid</a>. |
jackalmage@8944 | 1668 | |
jackalmage@8944 | 1669 | <li> |
jackalmage@8944 | 1670 | Among all the items with a <a>definite column position</a> |
jackalmage@8944 | 1671 | (explicitly positioned items, items positioned in the previous step, and items not yet positioned but with a definite column) |
jackalmage@8944 | 1672 | the largest positive line index that an item’s <a>inline-end</a> edge is positioned to, |
jackalmage@8944 | 1673 | minus 1. |
jackalmage@8944 | 1674 | |
jackalmage@8944 | 1675 | <li> |
jackalmage@8944 | 1676 | Among all items with a <a>definite column span</a>, |
jackalmage@8944 | 1677 | the largest such span. |
jackalmage@8944 | 1678 | </ul> |
jackalmage@8944 | 1679 | |
jackalmage@8944 | 1680 | <div class='example'> |
jackalmage@8944 | 1681 | For example, in the following style fragment: |
jackalmage@8944 | 1682 | |
jackalmage@8944 | 1683 | <pre class=css> |
jackalmage@8944 | 1684 | #grid { |
jackalmage@8944 | 1685 | display: grid; |
jackalmage@8944 | 1686 | grid-template-columns: repeat(5, 100px); |
jackalmage@9786 | 1687 | grid-auto-flow: row; |
jackalmage@8944 | 1688 | } |
jackalmage@8944 | 1689 | #grid-item { |
jackalmage@8944 | 1690 | grid-column: 4 / span 3; |
jackalmage@8944 | 1691 | } |
jackalmage@8944 | 1692 | </pre> |
jackalmage@8944 | 1693 | |
jackalmage@8944 | 1694 | The number of columns needed is 6. |
jackalmage@8944 | 1695 | The <code>#grid-item</code> element’s <a>inline-start</a> edge is positioned at index 4, |
jackalmage@8944 | 1696 | so its span ensures that it’s <a>inline-end</a> edge will be positioned at index 7. |
jackalmage@8944 | 1697 | This requires <code>7 - 1 = 6</code> columns to hold, |
jackalmage@8944 | 1698 | which is larger than the <a>explicit grid</a>’s 5 columns. |
jackalmage@8944 | 1699 | </div> |
jackalmage@8944 | 1700 | |
jackalmage@8944 | 1701 | |
jackalmage@7249 | 1702 | <li> |
jackalmage@8944 | 1703 | <b>Position the remaining grid items.</b> |
jackalmage@8944 | 1704 | |
jackalmage@8944 | 1705 | The <dfn export>auto-placement cursor</dfn> defines the current "insertion point" in the grid, |
jackalmage@8944 | 1706 | specified as a pair of row and column <a>grid lines</a>. |
jackalmage@8944 | 1707 | Initially the <a>auto-placement cursor</a> at is specified with a row and column position both equal to 1. |
jackalmage@8944 | 1708 | |
jackalmage@8944 | 1709 | For each <a>grid item</a> that hasn't been positioned by the previous steps, |
jackalmage@9752 | 1710 | in <a>order-modified document order</a>: |
jackalmage@8944 | 1711 | |
jackalmage@8944 | 1712 | <dl> |
jackalmage@8944 | 1713 | <dt>If the item has a <a>definite column position</a>: |
jackalmage@8944 | 1714 | <dd> |
jackalmage@7249 | 1715 | <ol> |
jackalmage@7249 | 1716 | <li> |
jackalmage@8944 | 1717 | Set the column position of the cursor to be equal to the <a>inline-start</a> index of the <a>grid item</a>. |
jackalmage@8944 | 1718 | |
jackalmage@7249 | 1719 | <li> |
jackalmage@8944 | 1720 | Increment the <a>auto-placement cursor</a>’s row position until a value is found |
jackalmage@8944 | 1721 | where the <a>grid item</a> does not overlap any <a>occupied grid cells</a> |
jackalmage@8944 | 1722 | (creating new rows in the <a>implicit grid</a> as necessary). |
jackalmage@8944 | 1723 | Position the item's <a>block-start</a> edge to the <a>auto-placement cursor</a>’s row position. |
jackalmage@7249 | 1724 | </ol> |
jackalmage@7251 | 1725 | |
fantasai@8956 | 1726 | <dt>If the item has an <a>automatic grid position</a> in both axes: |
jackalmage@8944 | 1727 | <dd> |
jackalmage@7249 | 1728 | <ol> |
jackalmage@7249 | 1729 | <li> |
jackalmage@9432 | 1730 | Increment the column position of the <a>auto-placement cursor</a> |
jackalmage@8944 | 1731 | until this item’s <a>grid area</a> does not overlap any <a>occupied grid cells</a> |
jackalmage@8944 | 1732 | or overflow the number of columns determined in the previous step. |
jackalmage@8944 | 1733 | |
jackalmage@7249 | 1734 | <li> |
jackalmage@8944 | 1735 | If a non-overlapping position was found in the previous step, |
jackalmage@8944 | 1736 | position the item’s <a>inline-start</a> and <a>block-start</a> edges |
jackalmage@8944 | 1737 | to the <a>auto-placement cursor</a>’s column and row position, respectively |
jackalmage@8944 | 1738 | Otherwise, |
jackalmage@8944 | 1739 | increment the <a>auto-placement cursor</a>’s row position |
jackalmage@8944 | 1740 | (creating new rows in the <a>implicit grid</a> as necessary), |
jackalmage@8944 | 1741 | set its column position to 1, |
jackalmage@8944 | 1742 | and return to the previous step. |
jackalmage@7249 | 1743 | </ol> |
jackalmage@8944 | 1744 | </dl> |
jackalmage@8946 | 1745 | |
jackalmage@8946 | 1746 | If 'grid-auto-flow' specifies the ''dense'' keyword, |
jackalmage@8946 | 1747 | reset the <a>auto-placement cursor</a> to 1/1 each time an item is placed. |
jackalmage@7249 | 1748 | </ol> |
jackalmage@7249 | 1749 | |
jackalmage@8935 | 1750 | <h3 id="grid-auto-position-property"> |
jackalmage@8938 | 1751 | Default Position: the 'grid-auto-position' property</h3> |
jackalmage@8935 | 1752 | |
jackalmage@8935 | 1753 | <pre class='propdef'> |
jackalmage@8935 | 1754 | Name: grid-auto-position |
jackalmage@8935 | 1755 | Value: <<grid-line>> / <<grid-line>> |
jackalmage@8935 | 1756 | Initial: 1 / 1 |
jackalmage@8935 | 1757 | Applies to: <a>grid containers</a> |
jackalmage@8935 | 1758 | Inherited: no |
jackalmage@9762 | 1759 | Percentages: n/a |
jackalmage@8935 | 1760 | Media: visual |
jackalmage@8935 | 1761 | Computed value: specified value |
jackalmage@8935 | 1762 | </pre> |
jackalmage@8935 | 1763 | |
jackalmage@8935 | 1764 | If a <a>grid container</a> doesn't specify an automatic-placement strategy through 'grid-auto-flow', |
jackalmage@8935 | 1765 | any grid items with an <a>automatic grid position</a> are instead all placed at the default position |
jackalmage@8935 | 1766 | specified by 'grid-auto-position'. |
jackalmage@8935 | 1767 | |
jackalmage@8935 | 1768 | Interpret the two <<grid-line>>s as if they were specified in 'grid-column-start' and 'grid-row-start', respectively, |
jackalmage@8935 | 1769 | of a hypothetical <a>grid item</a>, |
jackalmage@8936 | 1770 | treating <a value for=grid-row-start>auto</a> as ''1'' for this purpose. |
jackalmage@8935 | 1771 | The resulting lines of the <a>grid container</a> |
fantasai@8956 | 1772 | become a <a>definite grid position</a> in both axes |
jackalmage@8935 | 1773 | for the auto-placed <a>grid items</a>. |
jackalmage@8935 | 1774 | |
fantasai@8949 | 1775 | <p class="issue"> |
fantasai@8949 | 1776 | These properties might not be necessary in this level, |
fantasai@8949 | 1777 | if we can provide a more reasonable default behavior |
fantasai@8949 | 1778 | by, e.g., searching for an empty slot to stack items into |
fantasai@8949 | 1779 | instead of always using 1,1 by default. |
jackalmage@8935 | 1780 | |
fantasai@8943 | 1781 | <h2 id='grid-shorthand'> |
fantasai@8943 | 1782 | Grid Definition Shorthand: the 'grid' property</h2> |
jackalmage@8844 | 1783 | |
jackalmage@8856 | 1784 | <pre class='propdef'> |
fantasai@8943 | 1785 | Name: grid |
jackalmage@9914 | 1786 | Value: <<'grid-template'>> | [ <<'grid-auto-flow'>> [ <<'grid-auto-columns'>> [ / <<'grid-auto-rows'>> ]? ]? ] |
jackalmage@8856 | 1787 | Initial: see individual properties |
jackalmage@8856 | 1788 | Applies to: <a>grid containers</a> |
jackalmage@8856 | 1789 | Inherited: see individual properties |
jackalmage@8856 | 1790 | Percentages: see individual properties |
jackalmage@8856 | 1791 | Media: visual |
jackalmage@8856 | 1792 | Computed value: see individual properties |
jackalmage@8856 | 1793 | </pre> |
jackalmage@8844 | 1794 | |
jackalmage@8844 | 1795 | <p> |
fantasai@8943 | 1796 | The 'grid' property is a shorthand that sets |
fantasai@8943 | 1797 | all of the explicit grid properties |
fantasai@8943 | 1798 | ('grid-template-rows', 'grid-template-columns', and 'grid-template-areas') |
fantasai@8943 | 1799 | as well as all the implicit grid properties |
fantasai@8943 | 1800 | ('grid-auto-rows', 'grid-auto-columns', and 'grid-auto-flow') |
fantasai@8943 | 1801 | in a single declaration. |
jackalmage@8856 | 1802 | If <<'grid-auto-rows'>> value is omitted, |
jackalmage@8844 | 1803 | it is set to the value specified for 'grid-auto-columns'. |
jackalmage@8844 | 1804 | Other omitted values are set to their initial values. |
jackalmage@8844 | 1805 | |
jackalmage@8844 | 1806 | <div class='example'> |
fantasai@8943 | 1807 | <p>In addition to accepting the 'grid-template' shorthand syntax for setting up the <i>explicit grid</i>, |
fantasai@8943 | 1808 | the 'grid' shorthand can also easily set up parameters for an auto-formatted grid. |
fantasai@8978 | 1809 | For example, ''grid: rows 1fr;'' is equivalent to |
jackalmage@8844 | 1810 | <pre> |
fantasai@8943 | 1811 | grid-template: none; |
jackalmage@8844 | 1812 | grid-auto-columns: 1fr; |
jackalmage@8844 | 1813 | grid-auto-rows: 1fr; |
jackalmage@9786 | 1814 | grid-auto-flow: row;</pre> |
fantasai@8943 | 1815 | <p>Similarly, ''grid: columns 1fr / auto'' is equivalent to |
jackalmage@8844 | 1816 | <pre> |
fantasai@8943 | 1817 | grid-template: none; |
jackalmage@8844 | 1818 | grid-auto-columns: 1fr; |
jackalmage@8844 | 1819 | grid-auto-rows: auto; |
jackalmage@9786 | 1820 | grid-auto-flow: column;</pre> |
jackalmage@8844 | 1821 | </div> |
jackalmage@8844 | 1822 | |
jackalmage@8844 | 1823 | <h2 id="placement"> |
jackalmage@8844 | 1824 | Placing Grid Items</h2> |
jackalmage@8844 | 1825 | |
jackalmage@9434 | 1826 | A <a>grid item</a>’s <dfn export title="grid placement|placement">placement</dfn> consists of a <a>grid position</a> and a <a>grid span</a>: |
jackalmage@9434 | 1827 | |
jackalmage@9434 | 1828 | <dl export> |
jackalmage@9434 | 1829 | <dt><dfn>grid position</dfn> |
jackalmage@9434 | 1830 | <dd> |
jackalmage@9434 | 1831 | The <a>grid item</a>’s location in the <a>grid</a>. |
jackalmage@9434 | 1832 | A <i>grid position</i> can be either |
jackalmage@9434 | 1833 | <dfn export title="definite grid position|definite row position|definite column position|definite position">definite</dfn> (explicitly specified) |
jackalmage@9434 | 1834 | or <dfn export title="automatic grid position|automatic row position|automatic column position|automatic position">automatic</dfn> (determined by <a>auto-placement</a>). |
jackalmage@9434 | 1835 | |
jackalmage@9434 | 1836 | <dt><dfn>grid span</dfn> |
jackalmage@9434 | 1837 | <dd> |
jackalmage@9434 | 1838 | How many <i>grid tracks</i> the <a>grid item</a> occupies. |
jackalmage@9434 | 1839 | A <i>subgrid</i>’s <i>grid span</i> can be <dfn title="automatic grid span|automatic row span|automatic column span|automatic span">automatic</dfn> |
jackalmage@9434 | 1840 | (determined by its <a>implicit grid</a>) if not specified or implied; |
jackalmage@9434 | 1841 | a <i>grid item</i>’s <i>grid span</i> is otherwise always <dfn export title="definite grid span|definite row span|definite column span|definite span">definite</dfn> (defaulting to 1). |
jackalmage@9434 | 1842 | </dl> |
jackalmage@9434 | 1843 | |
jackalmage@9434 | 1844 | |
jackalmage@9434 | 1845 | |
jackalmage@9479 | 1846 | The <dfn export title="grid-placement property">grid-placement properties</dfn>-- |
jackalmage@9479 | 1847 | the longhands 'grid-row-start', 'grid-row-end', 'grid-column-start', 'grid-column-end', and their shorthands 'grid-row', 'grid-column', and 'grid-area'-- |
jackalmage@9479 | 1848 | allow the author to specify a <i>grid item</i>’s <i>placement</i> |
jackalmage@9434 | 1849 | by providing any (or none) of the following six pieces of information: |
jackalmage@9432 | 1850 | |
jackalmage@9432 | 1851 | <table class=data style="width: auto"> |
jackalmage@9432 | 1852 | <thead> |
jackalmage@9432 | 1853 | <tr> |
jackalmage@9432 | 1854 | <td> |
jackalmage@9432 | 1855 | <th>Row |
jackalmage@9432 | 1856 | <th>Column |
jackalmage@9432 | 1857 | <tbody> |
jackalmage@9432 | 1858 | <tr> |
jackalmage@9432 | 1859 | <th>Start |
jackalmage@9432 | 1860 | <td>row-start line |
jackalmage@9432 | 1861 | <td>column-start line |
jackalmage@9432 | 1862 | <tr> |
jackalmage@9432 | 1863 | <th>End |
jackalmage@9432 | 1864 | <td>row-end line |
jackalmage@9432 | 1865 | <td>column-end line |
jackalmage@9432 | 1866 | <tr> |
jackalmage@9432 | 1867 | <th>Span |
jackalmage@9432 | 1868 | <td>row span |
jackalmage@9432 | 1869 | <td>column span |
jackalmage@9432 | 1870 | </table> |
jackalmage@9432 | 1871 | |
jackalmage@9434 | 1872 | A definite value for any two of <var>Start</var>, <var>End</var>, and <var>Span</var> in a given dimension implies a definite value for the third. |
jackalmage@9434 | 1873 | |
jackalmage@9480 | 1874 | The following table summarizes the conditions under which a grid position or span is <i title=''>definite</i> or <i title=''>automatic</i>: |
jackalmage@9432 | 1875 | |
jackalmage@9432 | 1876 | <table class='data'> |
jackalmage@9432 | 1877 | <thead> |
jackalmage@9432 | 1878 | <tr> |
jackalmage@9432 | 1879 | <td> |
jackalmage@9432 | 1880 | <th>Position |
jackalmage@9432 | 1881 | <th>Span |
jackalmage@9432 | 1882 | <tbody> |
jackalmage@9432 | 1883 | <tr> |
jackalmage@9432 | 1884 | <th>Definite |
jackalmage@9432 | 1885 | <td>At least one specified line |
jackalmage@9432 | 1886 | <td>Explicit, implicit, or defaulted span. <br> <span class="note">Note: Non-<a>subgrids</a> default to 1.</span> |
jackalmage@9432 | 1887 | <tr> |
jackalmage@9432 | 1888 | <th>Automatic |
jackalmage@9432 | 1889 | <td>No lines explicitly specified |
jackalmage@9432 | 1890 | <td><a>Subgrid</a> without an explicit or implied span |
jackalmage@9432 | 1891 | </table> |
jackalmage@9432 | 1892 | |
jackalmage@9436 | 1893 | <h3 id='common-uses'> |
jackalmage@9438 | 1894 | Common Patterns for Grid Placement</h3> |
jackalmage@9436 | 1895 | |
jackalmage@9436 | 1896 | <em>This section is informative.</em> |
jackalmage@9436 | 1897 | |
jackalmage@9436 | 1898 | The <a>grid-placement property</a> longhands are organized into three shorthands: |
jackalmage@9436 | 1899 | |
jackalmage@9753 | 1900 | <table class=data id="grid-property-breakdown"> |
jackalmage@9436 | 1901 | <tr> |
jackalmage@9436 | 1902 | <td colspan=4>'grid-area' |
jackalmage@9436 | 1903 | <tr> |
jackalmage@9436 | 1904 | <td colspan=2>'grid-column' |
jackalmage@9436 | 1905 | <td colspan=2>'grid-row' |
jackalmage@9436 | 1906 | <tr> |
jackalmage@9753 | 1907 | <td>'grid-column-start' |
jackalmage@9753 | 1908 | <td>'grid-column-end' |
jackalmage@9753 | 1909 | <td>'grid-row-start' |
jackalmage@9753 | 1910 | <td>'grid-row-end' |
jackalmage@9436 | 1911 | </table> |
jackalmage@8844 | 1912 | |
jackalmage@9753 | 1913 | <style scoped> |
jackalmage@9753 | 1914 | #grid-property-breakdown tr:nth-child(3) td { |
jackalmage@9753 | 1915 | width: 25%; |
jackalmage@9753 | 1916 | border-style: solid; |
jackalmage@9753 | 1917 | } |
jackalmage@9753 | 1918 | </style> |
jackalmage@9753 | 1919 | |
jackalmage@9438 | 1920 | <h4 id='common-uses-named-areas'> |
jackalmage@9438 | 1921 | Named Areas</h4> |
jackalmage@9438 | 1922 | |
jackalmage@9438 | 1923 | An item can be placed into a <a>named grid area</a> |
jackalmage@9438 | 1924 | (such as those produced by the template in 'grid-template-areas') |
jackalmage@9438 | 1925 | by specifying the area’s name in 'grid-area': |
jackalmage@9438 | 1926 | |
jackalmage@9438 | 1927 | <div class='example'> |
jackalmage@9438 | 1928 | <pre> |
jackalmage@9438 | 1929 | article { |
jackalmage@9438 | 1930 | grid-area: main; |
jackalmage@9438 | 1931 | /* Places item into the named area "main". */ |
jackalmage@9438 | 1932 | } |
jackalmage@9438 | 1933 | </pre> |
jackalmage@9438 | 1934 | </div> |
jackalmage@9438 | 1935 | |
jackalmage@9438 | 1936 | An item can also be <em>partially</em> aligned with a <a>named grid area</a>, |
jackalmage@9438 | 1937 | with other edges aligned to some other line: |
jackalmage@9438 | 1938 | |
jackalmage@9438 | 1939 | <div class='example'> |
jackalmage@9438 | 1940 | <pre> |
jackalmage@9438 | 1941 | .one { |
jackalmage@9438 | 1942 | grid-row-start: main; |
jackalmage@9438 | 1943 | /* Align the row-start edge to the start edge of the "main" named area. */ |
jackalmage@9438 | 1944 | } |
jackalmage@9438 | 1945 | </pre> |
jackalmage@9438 | 1946 | </div> |
jackalmage@9438 | 1947 | |
jackalmage@9438 | 1948 | <h4 id='common-uses-numeric'> |
jackalmage@9438 | 1949 | Numeric Indexes and Spans</h4> |
jackalmage@9438 | 1950 | |
jackalmage@9438 | 1951 | Grid items can be positioned and sized by number, |
jackalmage@9438 | 1952 | which is particularly helpful for script-driven layouts: |
jackalmage@9438 | 1953 | |
jackalmage@9438 | 1954 | <div class='example'> |
jackalmage@9438 | 1955 | <pre> |
jackalmage@9438 | 1956 | .two { |
jackalmage@9438 | 1957 | grid-row: 2; /* Place item in the second row. */ |
jackalmage@9438 | 1958 | grid-column: 3; /* Place item in the third column. */ |
jackalmage@9438 | 1959 | /* Equivalent to grid-area: 2 / 3; |
jackalmage@9438 | 1960 | } |
jackalmage@9438 | 1961 | </pre> |
jackalmage@9438 | 1962 | </div> |
jackalmage@9438 | 1963 | |
jackalmage@9438 | 1964 | By default, a grid item has a span of 1. |
jackalmage@9438 | 1965 | Different spans can be given explicitly: |
jackalmage@9438 | 1966 | |
jackalmage@9438 | 1967 | <div class='example'> |
jackalmage@9438 | 1968 | <pre> |
jackalmage@9438 | 1969 | .three { |
jackalmage@9438 | 1970 | grid-row: 2 / span 5; |
jackalmage@9438 | 1971 | /* Starts in the 2nd row, |
jackalmage@9438 | 1972 | spans 5 rows down (ending in the 7th row). */ |
jackalmage@9438 | 1973 | } |
jackalmage@9438 | 1974 | |
jackalmage@9438 | 1975 | .four { |
jackalmage@9438 | 1976 | grid-row: span 5 / 7; |
jackalmage@9438 | 1977 | /* <em>Ends</em> in the 7th row, |
jackalmage@9438 | 1978 | spans 5 rows up (starting in the 2nd row). */ |
jackalmage@9438 | 1979 | } |
jackalmage@9438 | 1980 | </pre> |
jackalmage@9438 | 1981 | </div> |
jackalmage@9438 | 1982 | |
jackalmage@9438 | 1983 | Note: Note that grid indexes are <a>writing mode</a> relative. |
jackalmage@9438 | 1984 | For example, in a right-to-left language like Arabic, |
jackalmage@9438 | 1985 | the first column is the rightmost column. |
jackalmage@9438 | 1986 | |
jackalmage@9438 | 1987 | <h4 id='common-uses-named-lines'> |
jackalmage@9438 | 1988 | Named Lines and Spans</h4> |
jackalmage@9438 | 1989 | |
jackalmage@9438 | 1990 | Instead of counting lines by number, |
jackalmage@9438 | 1991 | <a>named lines</a> can be referenced by their name: |
jackalmage@9438 | 1992 | |
jackalmage@9438 | 1993 | <div class='example'> |
jackalmage@9438 | 1994 | <pre> |
jackalmage@9438 | 1995 | .five { |
jackalmage@9438 | 1996 | grid-column: first / middle; |
jackalmage@9438 | 1997 | /* Span from line "first" to line "middle". */ |
jackalmage@9438 | 1998 | } |
jackalmage@9438 | 1999 | </pre> |
jackalmage@9438 | 2000 | </div> |
jackalmage@9438 | 2001 | |
jackalmage@9438 | 2002 | Note: Note that if a <a>named grid area</a> and a <a>named line</a> have the same name, |
jackalmage@9438 | 2003 | the placement algorithm will prefer to use <a>named grid area</a>’s edge instead. |
jackalmage@9438 | 2004 | |
jackalmage@9438 | 2005 | If there are multiple lines of the same name, |
jackalmage@9438 | 2006 | they effectively establish a named set of grid lines, |
jackalmage@9438 | 2007 | which can be exclusively indexed by filtering the placement by name: |
jackalmage@9438 | 2008 | |
jackalmage@9438 | 2009 | <div class='example'> |
jackalmage@9438 | 2010 | <pre> |
jackalmage@9438 | 2011 | .six { |
jackalmage@9438 | 2012 | grid-row: text 5 / text 7; |
jackalmage@9438 | 2013 | /* Span between the 5th and 7th lines named "text". */ |
jackalmage@9438 | 2014 | grid-row: text 5 / span text 2; |
jackalmage@9438 | 2015 | /* Same as above. */ |
jackalmage@9438 | 2016 | } |
jackalmage@9438 | 2017 | </pre> |
jackalmage@9438 | 2018 | </div> |
jackalmage@9438 | 2019 | |
jackalmage@9438 | 2020 | <h4 id='common-uses-auto-placement'> |
jackalmage@9438 | 2021 | Auto Placement</h4> |
jackalmage@9438 | 2022 | |
jackalmage@9438 | 2023 | A <a>grid item</a> can be automatically placed into the next available empty <a>grid cell</a>, |
jackalmage@9438 | 2024 | growing the <a>grid</a> if there's no space left. |
jackalmage@9438 | 2025 | |
jackalmage@9438 | 2026 | <div class='example'> |
jackalmage@9438 | 2027 | <pre> |
jackalmage@9438 | 2028 | .eight { |
jackalmage@9438 | 2029 | grid-area: auto; /* Initial value */ |
jackalmage@9438 | 2030 | } |
jackalmage@9438 | 2031 | </pre> |
jackalmage@9438 | 2032 | </div> |
jackalmage@9438 | 2033 | |
jackalmage@9438 | 2034 | This can be used, for example, to list a number of sale items on a catalog site |
jackalmage@9438 | 2035 | in a grid pattern. |
jackalmage@9438 | 2036 | |
jackalmage@9438 | 2037 | Auto-placement can be combined with an explicit span, |
jackalmage@9438 | 2038 | if the item should take up more than one cell: |
jackalmage@9438 | 2039 | |
jackalmage@9438 | 2040 | <div class='example'> |
jackalmage@9438 | 2041 | <pre> |
jackalmage@9438 | 2042 | .nine { |
jackalmage@9438 | 2043 | grid-area: span 2 / span 3; |
jackalmage@9438 | 2044 | /* Auto-placed item, covering two rows and three columns. */ |
jackalmage@9438 | 2045 | } |
jackalmage@9438 | 2046 | </pre> |
jackalmage@9438 | 2047 | </div> |
jackalmage@9438 | 2048 | |
jackalmage@9438 | 2049 | Whether the <a>auto-placement algorithm</a> searchs across and adds rows, |
jackalmage@9438 | 2050 | or searches across and adds columns, |
jackalmage@9438 | 2051 | is controlled by the 'grid-auto-flow' property. |
jackalmage@9438 | 2052 | |
jackalmage@9438 | 2053 | Note: By default, the <a>auto-placement algorithm</a> looks linearly through the grid without backtracking; |
jackalmage@9438 | 2054 | if it has to skip some empty spaces to place a larger item, |
jackalmage@9438 | 2055 | it will not return to fill those spaces. |
jackalmage@9438 | 2056 | To change this behavior, |
jackalmage@9438 | 2057 | specify the ''dense'' keyword in 'grid-auto-flow'. |
jackalmage@9438 | 2058 | |
jackalmage@9438 | 2059 | <h4 id='common-uses-auto-sizing'> |
jackalmage@9438 | 2060 | Auto Sizing Subgrids</h4> |
jackalmage@9438 | 2061 | |
jackalmage@9438 | 2062 | A subgrid without a <a>definite grid span</a> is sized to its <a>implicit grid</a>, |
jackalmage@9438 | 2063 | i.e. all of its items within it are first placed into its own grid, |
jackalmage@9438 | 2064 | and its span is the resulting size of its grid. |
jackalmage@9438 | 2065 | |
jackalmage@9438 | 2066 | <div class='example'> |
jackalmage@9438 | 2067 | For example, a subgrid spanning two columns can be given an auto-spanning <i>extent</i>: |
jackalmage@9438 | 2068 | <pre> |
jackalmage@9438 | 2069 | .adverts { |
jackalmage@9438 | 2070 | grid: subgrid; |
jackalmage@9438 | 2071 | grid-column: span 2; |
jackalmage@9438 | 2072 | } |
jackalmage@9438 | 2073 | </pre> |
jackalmage@9438 | 2074 | |
jackalmage@9438 | 2075 | If it contains 10 auto-placed items, it will span 5 rows in its parent grid. |
jackalmage@9438 | 2076 | </div> |
jackalmage@9438 | 2077 | |
jackalmage@9438 | 2078 | Note: Since auto-spanning <a>subgrids</a> determine their span before being positioned, |
jackalmage@9438 | 2079 | they can also be auto-positioned. |
jackalmage@9438 | 2080 | The above example would auto-place the <code>.adverts</code> block, |
jackalmage@9438 | 2081 | if no further rules specified its position. |
jackalmage@9438 | 2082 | |
jackalmage@8844 | 2083 | <h3 id='line-placement'> |
jackalmage@8844 | 2084 | Line-based Placement: the 'grid-row-start', 'grid-column-start', 'grid-row-end', and 'grid-column-end' properties</h3> |
jackalmage@8844 | 2085 | |
jackalmage@8856 | 2086 | <pre class='propdef'> |
jackalmage@8856 | 2087 | Name: grid-row-start, grid-column-start, grid-row-end, grid-column-end |
jackalmage@8856 | 2088 | Value: <<grid-line>> |
jackalmage@8856 | 2089 | Initial: auto |
jackalmage@8856 | 2090 | Applies to: <a>grid items</a> |
jackalmage@8856 | 2091 | Inherited: no |
jackalmage@8856 | 2092 | Percentages: n/a |
jackalmage@8856 | 2093 | Media: visual |
jackalmage@9654 | 2094 | Computed value: specified value |
jackalmage@8856 | 2095 | </pre> |
jackalmage@8844 | 2096 | |
jackalmage@8844 | 2097 | <pre> |
jackalmage@9432 | 2098 | <dfn for="grid-row-start grid-column-start grid-row-end grid-column-end"><<grid-line>></dfn> = |
jackalmage@8856 | 2099 | auto | |
jackalmage@9649 | 2100 | <<custom-ident>> | |
jackalmage@9649 | 2101 | [ <<integer>> && <<custom-ident>>? ] | |
jackalmage@9649 | 2102 | [ span && [ <<integer>> || <<custom-ident>> ] ] |
jackalmage@8856 | 2103 | </pre> |
jackalmage@8844 | 2104 | |
jackalmage@9434 | 2105 | The 'grid-row-start', 'grid-column-start', 'grid-row-end', and 'grid-column-end' properties |
jackalmage@9434 | 2106 | determine a <a>grid item</a>’s size and location within the <i>grid</i> |
jackalmage@9434 | 2107 | by contributing a line, a span, or nothing (automatic) |
jackalmage@9434 | 2108 | to its <a>grid placement</a>, |
jackalmage@9434 | 2109 | thereby specifying the <i>inline-start</i>, <i>block-start</i>, <i>inline-end</i>, and <i>block-end</i> edges of its <i>grid area</i>. |
jackalmage@9434 | 2110 | |
jackalmage@9434 | 2111 | Values have the following meanings: |
jackalmage@8844 | 2112 | |
jackalmage@8856 | 2113 | <dl dfn-for="<grid-line>" dfn-type=value> |
jackalmage@9649 | 2114 | <dt><dfn id='grid-placement-slot'><<custom-ident>></dfn> |
jackalmage@8844 | 2115 | <dd> |
jackalmage@9434 | 2116 | First attempts to match the <i>grid area</i>’s edge to a <i>named grid area</i>: |
jackalmage@9649 | 2117 | if there is a <a>named line</a> with the name ''<<custom-ident>>-start'' (for 'grid-*-start') / ''<<custom-ident>>-end'' (for 'grid-*-end'), |
jackalmage@9432 | 2118 | contributes the first such line to the <a>grid item</a>’s <a>placement</a>. |
jackalmage@9432 | 2119 | |
jackalmage@9432 | 2120 | Note: <a>Named grid areas</a> automatically generate <a>implicit named lines</a> of this form, |
jackalmage@9432 | 2121 | so specifying ''grid-row-start: foo'' will choose the start edge of that <a>named grid area</a> |
jackalmage@9432 | 2122 | (unless another line named ''foo-start'' was explicitly specified before it). |
jackalmage@8847 | 2123 | |
jackalmage@9434 | 2124 | Otherwise, if there is a <a>named line</a> with the specified name, |
jackalmage@9434 | 2125 | contributes the first such line to the <a>grid item</a>’s <a>placement</a>. |
jackalmage@9434 | 2126 | |
jackalmage@9434 | 2127 | Otherwise, |
jackalmage@9434 | 2128 | the property contributes nothing (just as if <a value for="<grid-line>">auto</a> were specified). |
jackalmage@8856 | 2129 | |
jackalmage@9649 | 2130 | <dt><dfn id='grid-placement-int'><<integer>> && <<custom-ident>>?</dfn> |
jackalmage@8847 | 2131 | <dd> |
jackalmage@9434 | 2132 | Contributes the <var>N</var>th <a>grid line</a> to the <a>grid item</a>’s <a>placement</a> |
jackalmage@8844 | 2133 | If a negative integer is given, |
jackalmage@8844 | 2134 | it instead counts in reverse, |
jackalmage@8856 | 2135 | starting from the end edge of the <a>explicit grid</a>. |
jackalmage@8847 | 2136 | |
jackalmage@9649 | 2137 | If a name is given as a <<custom-ident>>, |
jackalmage@9434 | 2138 | only lines with that name are counted. |
jackalmage@9434 | 2139 | (If no line with that name exists, |
jackalmage@9434 | 2140 | it instead specifies the first grid line; |
jackalmage@9434 | 2141 | or the last, if the <<integer>> is negative. |
jackalmage@9434 | 2142 | If not enough lines of that name exist, |
jackalmage@9434 | 2143 | it specifies the <em>last</em> such named line; |
jackalmage@9434 | 2144 | or the first, if the <<integer>> is negative.) |
jackalmage@9434 | 2145 | |
jackalmage@9434 | 2146 | If the <<integer>> is omitted, it defaults to ''1''. |
jackalmage@9434 | 2147 | A value of zero makes the declaration invalid. |
jackalmage@8847 | 2148 | |
jackalmage@9649 | 2149 | <dt><dfn id='grid-placement-span-int'>span && [ <<integer>> || <<custom-ident>> ]</var></dfn> |
jackalmage@8844 | 2150 | <dd> |
jackalmage@8856 | 2151 | Contributes a <a>grid span</a> to the <a>grid item</a>’s <a>placement</a> |
jackalmage@9434 | 2152 | such that the corresponding edge of the <i>grid item</i>’s <a>grid area</a> is <var>N</var> lines from its opposite edge. |
jackalmage@9434 | 2153 | |
jackalmage@9649 | 2154 | If a name is given as a <<custom-ident>>, |
jackalmage@9434 | 2155 | only lines with that name are counted. |
jackalmage@9434 | 2156 | (If no line with that name exists, |
jackalmage@9434 | 2157 | the name is ignored. |
jackalmage@9434 | 2158 | If not enough lines of that name exist, |
jackalmage@9434 | 2159 | it spans to the last such named line in the spanning direction.) |
jackalmage@9434 | 2160 | |
jackalmage@9434 | 2161 | If the <<integer>> is omitted, it defaults to ''1''. |
jackalmage@9434 | 2162 | Negative integers or zero are invalid. |
jackalmage@8844 | 2163 | |
jackalmage@8856 | 2164 | <dt><dfn id='grid-placement-auto'>auto</dfn> |
jackalmage@8844 | 2165 | <dd> |
jackalmage@9434 | 2166 | The property contributes nothing to the <a>grid item</a>’s <a>placement</a>, |
jackalmage@9434 | 2167 | indicating <i>auto-placement</i>, an <i>automatic span</i>, or a default span of one. |
jackalmage@9434 | 2168 | (See <a href="#placement">Placing Grid Items</a>, above.) |
jackalmage@8847 | 2169 | </dl> |
jackalmage@8844 | 2170 | |
jackalmage@8844 | 2171 | <div class='example'> |
jackalmage@8844 | 2172 | <p> |
jackalmage@8844 | 2173 | Given a single-row, 8-column grid and the following 9 named lines: |
jackalmage@8844 | 2174 | |
jackalmage@9432 | 2175 | <pre> |
jackalmage@9434 | 2176 | 1 2 3 4 5 6 7 8 9 |
jackalmage@9434 | 2177 | +--+--+--+--+--+--+--+--+ |
jackalmage@9434 | 2178 | | | | | | | | | | |
jackalmage@9434 | 2179 | A B C A B C A B C |
jackalmage@9434 | 2180 | | | | | | | | | | |
jackalmage@9434 | 2181 | +--+--+--+--+--+--+--+--+ |
jackalmage@9434 | 2182 | </pre> |
jackalmage@8844 | 2183 | |
jackalmage@8844 | 2184 | <p> |
jackalmage@8844 | 2185 | The following declarations place the grid item between the lines indicated by index: |
jackalmage@8844 | 2186 | |
jackalmage@8844 | 2187 | <pre> |
jackalmage@9434 | 2188 | grid-column-start: 4; grid-column-end: auto; |
jackalmage@9434 | 2189 | /* Line 4 to line 5 */ |
jackalmage@9434 | 2190 | |
jackalmage@9434 | 2191 | grid-column-start: auto; grid-column-end: 6; |
jackalmage@9434 | 2192 | /* Line 5 to line 6 */ |
jackalmage@9434 | 2193 | |
jackalmage@9434 | 2194 | grid-column-start: C; grid-column-end: C -1; |
jackalmage@9434 | 2195 | /* Line 3 to line 9 */ |
jackalmage@9434 | 2196 | |
jackalmage@9434 | 2197 | grid-column-start: C; grid-column-end: span C; |
jackalmage@9434 | 2198 | /* Line 3 to line 6 */ |
jackalmage@9434 | 2199 | |
jackalmage@9434 | 2200 | grid-column-start: span C; grid-column-end: C -1; |
jackalmage@9434 | 2201 | /* Line 6 to line 9 */ |
jackalmage@9434 | 2202 | |
jackalmage@9434 | 2203 | grid-column-start: span C; grid-column-end: span C; |
jackalmage@9434 | 2204 | /* Error: both properties compute to <a value for="<grid-line>">auto</a> */ |
jackalmage@9434 | 2205 | |
jackalmage@9434 | 2206 | grid-column-start: 5; grid-column-end: C -1; |
jackalmage@9434 | 2207 | /* Line 5 to line 9 */ |
jackalmage@9434 | 2208 | |
jackalmage@9434 | 2209 | grid-column-start: 5; grid-column-end: span C; |
jackalmage@9434 | 2210 | /* Line 5 to line 6 */ |
jackalmage@9434 | 2211 | |
jackalmage@9434 | 2212 | grid-column-start: 8; grid-column-end: 8; |
jackalmage@9434 | 2213 | /* Error: line 8 to line 9 */ |
jackalmage@9434 | 2214 | |
jackalmage@9434 | 2215 | grid-column-start: B 2; grid-column-end: span 1; |
jackalmage@9434 | 2216 | /* Line 5 to line 6 */ |
jackalmage@9434 | 2217 | </pre> |
jackalmage@8844 | 2218 | </div> |
jackalmage@8844 | 2219 | |
jackalmage@9434 | 2220 | <h4 id='grid-placement-errors'> |
jackalmage@9434 | 2221 | Grid Placement Error Handling</h4> |
jackalmage@9434 | 2222 | |
jackalmage@9434 | 2223 | If 'grid-row-end'/'grid-column-end' specifies a line at or before that specified by 'grid-row-start'/'grid-column-start', |
jackalmage@9434 | 2224 | it instead contributes nothing. |
jackalmage@9434 | 2225 | |
jackalmage@9434 | 2226 | If both 'grid-row-start' and 'grid-row-end', or 'grid-column-start' and 'grid-column-end', |
jackalmage@9434 | 2227 | specify a span, |
jackalmage@9434 | 2228 | the <a>end</a> span is ignored. |
jackalmage@9434 | 2229 | |
jackalmage@9434 | 2230 | If the <a>grid item</a> has an automatic position |
jackalmage@9434 | 2231 | and a <a>grid span</a> for a named line |
jackalmage@9434 | 2232 | in a given dimension, |
jackalmage@9434 | 2233 | instead treat the <a>grid span</a> as one. |
jackalmage@9434 | 2234 | |
jackalmage@8844 | 2235 | <h3 id='placement-shorthands'> |
jackalmage@8844 | 2236 | Placement Shorthands: the 'grid-column', 'grid-row', and 'grid-area' properties</h3> |
jackalmage@8844 | 2237 | |
jackalmage@8856 | 2238 | <pre class='propdef'> |
jackalmage@9438 | 2239 | Name: grid-row, grid-column |
jackalmage@8856 | 2240 | Value: <<grid-line>> [ / <<grid-line>> ]? |
jackalmage@8856 | 2241 | Initial: see individual properties |
jackalmage@8856 | 2242 | Applies to: <a>grid items</a> |
jackalmage@8856 | 2243 | Inherited: see individual properties |
jackalmage@8856 | 2244 | Percentages: see individual properties |
jackalmage@8856 | 2245 | Media: visual |
jackalmage@8856 | 2246 | Computed value: see individual properties |
jackalmage@8856 | 2247 | </pre> |
jackalmage@8844 | 2248 | |
jackalmage@8844 | 2249 | <p> |
jackalmage@8856 | 2250 | The 'grid-row' and 'grid-column' properties are shorthands for 'grid-row-start'/'grid-row-end' and 'grid-column-start'/'grid-column-end', respectively. |
jackalmage@8844 | 2251 | |
jackalmage@8844 | 2252 | <p> |
jackalmage@8856 | 2253 | If two <<grid-line>> values are specified, |
jackalmage@8856 | 2254 | the 'grid-row-start'/'grid-column-start' longhand is set to the value before the slash, |
jackalmage@8856 | 2255 | and the 'grid-row-end'/'grid-column-end' longhand is set to the value after the slash. |
jackalmage@9432 | 2256 | |
jackalmage@8844 | 2257 | <p> |
jackalmage@8844 | 2258 | When the second value is omitted, |
jackalmage@9649 | 2259 | if the first value is a <<custom-ident>>, |
jackalmage@9649 | 2260 | the 'grid-row-end'/'grid-column-end' longhand is also set to that <<custom-ident>>; |
jackalmage@8856 | 2261 | otherwise, it is set to <a value for="<grid-line>">auto</a>. |
jackalmage@8856 | 2262 | |
jackalmage@8856 | 2263 | |
jackalmage@8856 | 2264 | <pre class='propdef'> |
jackalmage@8856 | 2265 | Name: grid-area |
jackalmage@8856 | 2266 | Value: <<grid-line>> [ / <<grid-line>> ]{0,3} |
jackalmage@8856 | 2267 | Initial: see individual properties |
jackalmage@8856 | 2268 | Applies to: <a>grid items</a> |
jackalmage@8856 | 2269 | Inherited: see individual properties |
jackalmage@8856 | 2270 | Percentages: see individual properties |
jackalmage@8856 | 2271 | Media: visual |
jackalmage@8856 | 2272 | Computed value: see individual properties |
jackalmage@8856 | 2273 | </pre> |
jackalmage@8844 | 2274 | |
jackalmage@8844 | 2275 | <p> |
jackalmage@8856 | 2276 | If four <<grid-line>> values are specified, |
jackalmage@8844 | 2277 | 'grid-row-start' is set to the first value, |
jackalmage@8844 | 2278 | 'grid-column-start' is set to the second value, |
jackalmage@8844 | 2279 | 'grid-row-end' is set to the third value, |
jackalmage@8844 | 2280 | and 'grid-column-end' is set to the fourth value. |
jackalmage@8844 | 2281 | |
jackalmage@8844 | 2282 | <p> |
jackalmage@8844 | 2283 | When 'grid-column-end' is omitted, |
jackalmage@9649 | 2284 | if 'grid-column-start' is a <<custom-ident>>, |
jackalmage@9649 | 2285 | 'grid-column-end' is set to that <<custom-ident>>; |
jackalmage@8856 | 2286 | otherwise, it is set to <a value for="<grid-line>">auto</a>. |
jackalmage@8844 | 2287 | |
jackalmage@8844 | 2288 | <p> |
jackalmage@8844 | 2289 | When 'grid-row-end' is omitted, |
jackalmage@9649 | 2290 | if 'grid-row-start' is a <<custom-ident>>, |
jackalmage@9649 | 2291 | 'grid-row-end' is set to that <<custom-ident>>; |
jackalmage@8856 | 2292 | otherwise, it is set to <a value for="<grid-line>">auto</a>. |
jackalmage@8844 | 2293 | |
jackalmage@8844 | 2294 | <p> |
jackalmage@8844 | 2295 | When 'grid-column-start' is omitted, |
jackalmage@9649 | 2296 | if 'grid-row-start' is a <<custom-ident>>, |
jackalmage@8844 | 2297 | all four longhands are set to that value. |
jackalmage@8856 | 2298 | Otherwise, it is set to <a value for="<grid-line>">auto</a>. |
jackalmage@8844 | 2299 | |
jackalmage@8844 | 2300 | <p class='note'> |
jackalmage@8844 | 2301 | The resolution order for this shorthand is row-start/column-start/row-end/column-end, |
jackalmage@8844 | 2302 | which goes CCW for LTR pages, |
jackalmage@8844 | 2303 | the opposite direction of the related 4-edge properties using physical directions, like 'margin'. |
jackalmage@8844 | 2304 | |
jackalmage@8844 | 2305 | |
jackalmage@9442 | 2306 | <h3 id="abspos-items"> |
jackalmage@9442 | 2307 | Absolutely-positioned Grid Items</h3> |
jackalmage@9442 | 2308 | |
jackalmage@9442 | 2309 | If an absolutely positioned element's <a>containing block</a> |
jackalmage@9442 | 2310 | is generated by a <a>grid container</a>, |
jackalmage@9731 | 2311 | its containing block edges are the edges of the element's <a>grid area</a> |
jackalmage@9731 | 2312 | as given by its <a>grid-placement properties</a>. |
jackalmage@9442 | 2313 | In this case, an <a value for="<grid-line>">auto</a> value for a <a>grid-placement property</a> |
jackalmage@9731 | 2314 | contributes the corresponding padding edge of the <a>grid container</a> as a line. |
jackalmage@9731 | 2315 | (Thus, by default, the <a>containing block</a> will correspond to the padding edges of the <a>grid container</a>.) |
jackalmage@9731 | 2316 | The offset properties ('top'/'right'/'bottom'/'left') |
jackalmage@9731 | 2317 | then indicate offsets inwards from the corresponding edges |
jackalmage@9731 | 2318 | of the resulting <a>containing block</a>, as normal. |
jackalmage@9442 | 2319 | |
jackalmage@9442 | 2320 | Note: Note that, while absolutely-positioning an element to a <i>grid container</i> |
jackalmage@9442 | 2321 | does allow it to align to that container's <i>grid lines</i>, |
jackalmage@9442 | 2322 | such elements |
jackalmage@9442 | 2323 | do not take up space or otherwise participate in the layout of the grid. |
jackalmage@9442 | 2324 | |
jackalmage@9442 | 2325 | <div class='example'> |
jackalmage@9444 | 2326 | <pre> |
jackalmage@9442 | 2327 | .grid { |
jackalmage@9731 | 2328 | grid: 10rem 10rem 10rem 10rem / 1fr 1fr 1fr 1fr; |
jackalmage@9731 | 2329 | /* 4 columns of ''10rem'' each, |
jackalmage@9731 | 2330 | 4 equal-height rows filling the <a>grid container</a> */ |
jackalmage@9731 | 2331 | justify-content: center; |
jackalmage@9731 | 2332 | /* center the grid horizontally within the <a>grid container</a> */ |
jackalmage@9731 | 2333 | position: relative; |
jackalmage@9731 | 2334 | /* Establish abspos <a>containing block</a> */ |
jackalmage@9442 | 2335 | } |
jackalmage@9731 | 2336 | |
jackalmage@9442 | 2337 | .abspos { |
jackalmage@9731 | 2338 | grid-row-start: 1; /* 1st grid row line = top of grid container */ |
jackalmage@9731 | 2339 | grid-row-end: span 2; /* 3rd grid row line */ |
jackalmage@9731 | 2340 | grid-column-start: 3; /* 3rd grid col line */ |
jackalmage@9731 | 2341 | grid-column-end: auto; /* right padding edge */ |
jackalmage@9731 | 2342 | /* <a>Containing block</a> covers the top right quadrant of the <a>grid container</a> */ |
jackalmage@9731 | 2343 | |
jackalmage@9442 | 2344 | position: absolute; |
jackalmage@9731 | 2345 | top: 70px; |
jackalmage@9731 | 2346 | bottom: 40px; |
jackalmage@9731 | 2347 | left: 100px; |
jackalmage@9731 | 2348 | right: 30px; |
jackalmage@9442 | 2349 | } |
jackalmage@9442 | 2350 | </pre> |
jackalmage@9731 | 2351 | |
jackalmage@9731 | 2352 | <figure> |
jackalmage@9752 | 2353 | <img src="images/abspos-grid.svg" width="702" height="402" alt=''> |
jackalmage@9731 | 2354 | </figure> |
jackalmage@9733 | 2355 | |
jackalmage@9733 | 2356 | Note: Note that grids and the <a>grid-placement properties</a> are <a>flow-relative</a>, |
jackalmage@9733 | 2357 | while abspos offsets are <a>physical</a>, |
jackalmage@9733 | 2358 | so if the 'direction' or 'writing-mode' properties change, |
jackalmage@9733 | 2359 | the grid will transform to match, |
jackalmage@9733 | 2360 | but the offsets won't. |
jackalmage@9444 | 2361 | </div> |
jackalmage@8886 | 2362 | |
jackalmage@7651 | 2363 | <h2 id='alignment'> |
jackalmage@7651 | 2364 | Alignment</h2> |
jackalmage@7249 | 2365 | |
jackalmage@7249 | 2366 | <p> |
jackalmage@8856 | 2367 | After a <a>grid container</a>’s <a>grid tracks</a> have been sized, |
jackalmage@9432 | 2368 | and the dimensions of all <a>grid items</a> are finalized, |
jackalmage@8856 | 2369 | <a>grid items</a> can be aligned within their <a>grid areas</a>. |
jackalmage@8047 | 2370 | |
jackalmage@8047 | 2371 | <p> |
jackalmage@9432 | 2372 | The 'margin' properties can be used to align items in a manner similar to, |
jackalmage@9432 | 2373 | but more powerful than, |
jackalmage@8047 | 2374 | what margins can do in block layout. |
jackalmage@8856 | 2375 | <a>Grid items</a> also respect the alignment properties from the Box Alignment spec, |
jackalmage@8856 | 2376 | which allow easy keyword-based alignment of items in both the <a>row axis</a> and <a>column axis</a>. |
jackalmage@7249 | 2377 | |
jackalmage@7249 | 2378 | <p> |
jackalmage@7651 | 2379 | By default, |
jackalmage@8856 | 2380 | <a>grid items</a> stretch to fill their <a>grid area</a>. |
jackalmage@7651 | 2381 | However, if 'justify-self' or 'align-self' compute to a value other than ''stretch'' |
jackalmage@8856 | 2382 | or margins are <a value for="margin">auto</a>, |
jackalmage@8856 | 2383 | <a>grid items</a> will auto-size to fit their contents. |
jackalmage@7651 | 2384 | |
jackalmage@7651 | 2385 | |
jackalmage@7651 | 2386 | <h3 id='auto-margins'> |
jackalmage@8856 | 2387 | Aligning with <a value for="margin">auto</a> margins</h3> |
jackalmage@7651 | 2388 | |
jackalmage@7651 | 2389 | <p> |
jackalmage@9432 | 2390 | <em>This section is non-normative. |
jackalmage@8020 | 2391 | The normative definition of how margins affect grid items is in the <a href="#layout-algorithm">Grid Layout Algorithm</a> section.</em> |
jackalmage@7651 | 2392 | |
jackalmage@7651 | 2393 | <p> |
jackalmage@8856 | 2394 | Auto margins on <a>grid items</a> have an effect very similar to auto margins in block flow: |
jackalmage@7651 | 2395 | |
jackalmage@7651 | 2396 | <ul> |
jackalmage@7651 | 2397 | <li> |
jackalmage@8856 | 2398 | During calculations of <a>grid track</a> sizes, auto margins are treated as ''0''. |
jackalmage@7651 | 2399 | |
jackalmage@7651 | 2400 | <li> |
jackalmage@7651 | 2401 | Auto margins absorb positive free space |
jackalmage@7651 | 2402 | prior to alignment via the alignment properties |
jackalmage@7651 | 2403 | (defined in the next sections). |
jackalmage@7651 | 2404 | |
jackalmage@7651 | 2405 | <li> |
jackalmage@8856 | 2406 | Overflowing elements ignore their auto margins and overflow in the <a>end</a> directions. |
jackalmage@7651 | 2407 | </ul> |
jackalmage@7651 | 2408 | |
jackalmage@7651 | 2409 | <p class='note'> |
jackalmage@9432 | 2410 | Note that, if free space is distributed to auto margins, |
jackalmage@7651 | 2411 | the alignment properties will have no effect in that dimension |
jackalmage@7651 | 2412 | because the margins will have stolen all the free space |
jackalmage@8048 | 2413 | left over after sizing. |
jackalmage@7651 | 2414 | |
jackalmage@7651 | 2415 | <div class='example'> |
jackalmage@7651 | 2416 | TODO: EXAMPLE HERE |
jackalmage@7651 | 2417 | </div> |
jackalmage@7651 | 2418 | |
jackalmage@7651 | 2419 | |
jackalmage@7651 | 2420 | <h3 id='row-align'> |
jackalmage@7651 | 2421 | Row-axis Alignment: the 'justify-self' and 'justify-items' properties</h3> |
jackalmage@7651 | 2422 | |
jackalmage@7651 | 2423 | <p> |
jackalmage@9432 | 2424 | <a>Grid items</a> can be aligned in the inline dimension |
jackalmage@8856 | 2425 | by using the 'justify-self' property on the <a>grid item</a> |
jackalmage@8856 | 2426 | or 'justify-items' property on the <a>grid container</a>, |
jackalmage@7651 | 2427 | as defined in [[!CSS3-ALIGN]]. |
jackalmage@7651 | 2428 | |
jackalmage@7651 | 2429 | <div class='example'> |
jackalmage@7651 | 2430 | For example, |
jackalmage@7651 | 2431 | for an English document, |
jackalmage@7651 | 2432 | the inline axis is horizontal, |
jackalmage@8856 | 2433 | and so the 'justify-*' properties align the <a>grid items</a> horizontally. |
jackalmage@7651 | 2434 | |
jackalmage@9738 | 2435 | <p class='issue'> |
jackalmage@9738 | 2436 | TODO: provide example |
jackalmage@7651 | 2437 | </div> |
jackalmage@7651 | 2438 | |
jackalmage@7651 | 2439 | |
jackalmage@7651 | 2440 | <h3 id='column-align'> |
jackalmage@7651 | 2441 | Column-axis Alignment: the 'align-self' and 'align-items' properties</h3> |
jackalmage@7651 | 2442 | |
jackalmage@7651 | 2443 | <p> |
jackalmage@8856 | 2444 | <a>Grid items</a> can also be aligned in the block dimension |
jackalmage@7651 | 2445 | (perpendicular to the inline dimension) |
jackalmage@8856 | 2446 | by using the 'align-self' property on the <a>grid item</a> |
jackalmage@8856 | 2447 | or 'align-items' property on the <a>grid container</a>, |
jackalmage@7651 | 2448 | as defined in [[!CSS3-ALIGN]]. |
jackalmage@7651 | 2449 | |
jackalmage@9444 | 2450 | <h3 id='grid-align'> |
jackalmage@9444 | 2451 | Aligning the Grid: the 'justify-content' and 'align-content' properties</h3> |
jackalmage@9444 | 2452 | |
jackalmage@9444 | 2453 | If the <a>grid</a>’s outer edges do not correspond to the <a>grid container</a>’s padding edges |
jackalmage@9444 | 2454 | (for example, if no columns are flex-sized), |
jackalmage@9444 | 2455 | the <a>grid</a> is aligned within the padding box according to the 'justify-content' and 'align-content' properties on the <a>grid container</a>. |
jackalmage@9444 | 2456 | |
jackalmage@9737 | 2457 | <div class='example'> |
jackalmage@9737 | 2458 | For example, the following grid is centered vertically, |
jackalmage@9737 | 2459 | and aligned to the right edge of its <a>grid container</a>: |
jackalmage@9737 | 2460 | |
jackalmage@9737 | 2461 | <pre> |
jackalmage@9737 | 2462 | .grid { |
jackalmage@9737 | 2463 | display: grid; |
jackalmage@9737 | 2464 | grid: 12rem 12rem 12rem 12rem / 10rem 10rem 10rem 10rem; |
jackalmage@9737 | 2465 | justify-content: end; |
jackalmage@9737 | 2466 | align-content: center; |
jackalmage@9737 | 2467 | } |
jackalmage@9737 | 2468 | </pre> |
jackalmage@9737 | 2469 | |
jackalmage@9737 | 2470 | <figure> |
jackalmage@9752 | 2471 | <img src="images/align-justify-content.svg" width="352" height="252" alt=''> |
jackalmage@9737 | 2472 | </figure> |
jackalmage@9737 | 2473 | </div> |
jackalmage@9444 | 2474 | |
jackalmage@7651 | 2475 | <h3 id='z-order'> |
jackalmage@7249 | 2476 | Z-axis Ordering: the 'z-index' property</h3> |
jackalmage@7249 | 2477 | |
jackalmage@7249 | 2478 | |
jackalmage@7249 | 2479 | <p> |
jackalmage@8856 | 2480 | <a>Grid items</a> can overlap when they are positioned into intersecting <a>grid areas</a>. |
jackalmage@8856 | 2481 | <a>Grid item</a> boxes in non-intersecting areas can also overlap because of negative margins or positioning. |
jackalmage@7251 | 2482 | |
jackalmage@7249 | 2483 | <p> |
jackalmage@9432 | 2484 | When <a>grid items</a> overlap, |
jackalmage@9752 | 2485 | the 'z-index' property provides control over the drawing order of <a>grid items</a>. |
jackalmage@8856 | 2486 | <a>Grid items</a> paint <a href="http://www.w3.org/TR/css3-flexbox/#painting">exactly the same as flex items</a> [[!CSS3-FLEXBOX]]: |
jackalmage@9752 | 2487 | they use <a>order-modified document order</a>, |
jackalmage@8856 | 2488 | and 'z-index' values other than <a value for=z-index>auto</a> create a stacking context even if 'position' is ''static''. |
jackalmage@7650 | 2489 | |
jackalmage@7650 | 2490 | <p class='note'> |
jackalmage@7776 | 2491 | Note: Descendants that are positioned outside a grid item still participate in any stacking context established by the grid item. |
jackalmage@7776 | 2492 | |
jackalmage@7776 | 2493 | <div class="example"> |
jackalmage@7776 | 2494 | <p> |
jackalmage@7776 | 2495 | The following diagram shows several overlapping grid items, |
jackalmage@7776 | 2496 | with a combination of implicit source order |
jackalmage@7776 | 2497 | and explicit 'z-index' |
jackalmage@7776 | 2498 | used to control their stacking order. |
jackalmage@7776 | 2499 | |
jackalmage@9752 | 2500 | <figure> |
jackalmage@9752 | 2501 | <img src="images/drawing-order.png" /> |
jackalmage@9752 | 2502 | |
jackalmage@9752 | 2503 | <figcaption>Drawing order controlled by z-index and source order.</figcaption> |
jackalmage@9752 | 2504 | </figure> |
jackalmage@7776 | 2505 | |
jackalmage@7776 | 2506 | <pre> |
jackalmage@9752 | 2507 | <style type="text/css"> |
jackalmage@9752 | 2508 | #grid { |
jackalmage@9752 | 2509 | display: grid; |
jackalmage@9752 | 2510 | grid-template-columns: 1fr 1fr; |
jackalmage@9752 | 2511 | grid-template-rows: 1fr 1fr |
jackalmage@9752 | 2512 | } |
jackalmage@9752 | 2513 | #A { grid-column: 1 / span 2; grid-row: 2; align-self: foot } |
jackalmage@9752 | 2514 | #B { grid-column: 1; grid-row: 1; z-index: 10 } |
jackalmage@9752 | 2515 | #C { grid-column: 2; grid-row: 1; align-self: head; margin-left: -20px } |
jackalmage@9752 | 2516 | #D { grid-column: 2; grid-row: 2; justify-self: end; align-self: head } |
jackalmage@9752 | 2517 | #E { grid-column: 1 / span 2; grid-row: 1 / span 2; |
jackalmage@9752 | 2518 | z-index: 5; justify-self: center; align-self: center; } |
jackalmage@9752 | 2519 | </style> |
jackalmage@9752 | 2520 | |
jackalmage@9752 | 2521 | <div id="grid"> |
jackalmage@9752 | 2522 | <div id="A">A</div> |
jackalmage@9752 | 2523 | <div id="B">B</div> |
jackalmage@9752 | 2524 | <div id="C">C</div> |
jackalmage@9752 | 2525 | <div id="D">D</div> |
jackalmage@9752 | 2526 | <div id="E">E</div> |
jackalmage@9752 | 2527 | </div> |
jackalmage@9752 | 2528 | </pre> |
jackalmage@7776 | 2529 | </div> |
jackalmage@7249 | 2530 | |
jackalmage@7754 | 2531 | <h3 id='grid-baselines'> |
jackalmage@7754 | 2532 | Grid Baselines</h3> |
jackalmage@7754 | 2533 | |
jackalmage@7754 | 2534 | <p> |
jackalmage@8856 | 2535 | The baselines of a <a>grid container</a> are determined as follows: |
jackalmage@7754 | 2536 | |
jackalmage@7754 | 2537 | <ol> |
jackalmage@7754 | 2538 | <li> |
jackalmage@8856 | 2539 | If any of the <a>grid items</a> whose areas intersect the <a>grid container</a>’s first row/column |
jackalmage@7754 | 2540 | <a href="#baseline-participation">participate in baseline alignment</a>, |
jackalmage@8856 | 2541 | the grid container's baseline is the baseline of those <a>grid items</a>. |
jackalmage@7754 | 2542 | |
jackalmage@7754 | 2543 | <li> |
jackalmage@8856 | 2544 | Otherwise, if the grid container has at least one <a>grid item</a> whose area intersects the first row/column, |
jackalmage@9752 | 2545 | and the first such <a>grid item</a> (in <a>order-modified grid order</a>) has a baseline |
jackalmage@7754 | 2546 | parallel to the relevant axis, |
jackalmage@7754 | 2547 | the grid container's baseline is that baseline. |
jackalmage@7754 | 2548 | |
jackalmage@7754 | 2549 | <li> |
jackalmage@9432 | 2550 | Otherwise, the grid container's baseline is <a href="http://www.w3.org/TR/css3-writing-modes/#inline-alignment">synthesized</a> |
jackalmage@9752 | 2551 | from the first item's (in <a>order-modified grid order</a>) content box, |
jackalmage@7754 | 2552 | or, failing that, from the grid container's content box. |
jackalmage@7754 | 2553 | </ol> |
jackalmage@7754 | 2554 | |
jackalmage@7754 | 2555 | <p> |
jackalmage@8858 | 2556 | A <a>grid item</a> <dfn export id="baseline-participation">participates in baseline alignment</dfn> in a particular dimension |
jackalmage@9432 | 2557 | if its value for 'align-self' or 'justify-self', as appropriate, is ''baseline'' |
jackalmage@7834 | 2558 | and its inline axis is parallel to that dimension. |
jackalmage@7834 | 2559 | |
jackalmage@7834 | 2560 | <p> |
jackalmage@9753 | 2561 | <dfn export title="order-modified grid order">'order'-modified grid order</dfn> is the order in which |
jackalmage@8856 | 2562 | <a>grid items</a> are encountered when traversing the grid's <a>grid cells</a>, |
jackalmage@7755 | 2563 | in row-major order if calculating the inline-axis baseline, |
jackalmage@7755 | 2564 | or in column-major order if calculating the block-axis baseline. |
jackalmage@7755 | 2565 | If two items are encountered at the same time, |
jackalmage@9752 | 2566 | they are taken in <a>order-modified document order</a>. |
jackalmage@7755 | 2567 | |
jackalmage@7755 | 2568 | <p> |
jackalmage@7754 | 2569 | When calculating the baseline according to the above rules, |
jackalmage@7754 | 2570 | if the box contributing a baseline has an 'overflow' value that allows scrolling, |
jackalmage@7754 | 2571 | the box must be treated as being in its initial scroll position |
jackalmage@7754 | 2572 | for the purpose of determining its baseline. |
jackalmage@7754 | 2573 | |
jackalmage@7754 | 2574 | <p> |
jackalmage@7754 | 2575 | When <a href="http://www.w3.org/TR/CSS21/tables.html#height-layout">determining the baseline of a table cell</a>, |
jackalmage@7754 | 2576 | a grid container provides a baseline just as a line box or table-row does. [[!CSS21]] |
jackalmage@7754 | 2577 | |
jackalmage@7754 | 2578 | |
jackalmage@7754 | 2579 | |
jackalmage@10078 | 2580 | <h2 id="layout-algorithm"> |
jackalmage@10078 | 2581 | Microsoft's Grid Track Sizing Algorithm</h2> |
jackalmage@10078 | 2582 | |
jackalmage@10078 | 2583 | <h3 id="algo-terms"> |
jackalmage@7249 | 2584 | Definition of Terms for use in Calculating Grid Track Sizes</h3> |
jackalmage@7249 | 2585 | |
jackalmage@7249 | 2586 | <dl> |
jackalmage@10078 | 2587 | <dt><dfn>AvailableSpace</dfn> |
jackalmage@10078 | 2588 | <dd>The grid container’s content box size in the applicable dimension. |
jackalmage@10078 | 2589 | |
jackalmage@10078 | 2590 | <dt><dfn>MaxTrackSizingFunction</dfn> |
jackalmage@10078 | 2591 | <dd>One of the <<track-breadth>> sizing functions assigned as the maximum breadth of a Grid track. |
jackalmage@10078 | 2592 | |
jackalmage@10078 | 2593 | <dt><dfn>MinTrackSizingFunction</dfn> |
jackalmage@10078 | 2594 | <dd>One of the <<track-breadth>> sizing functions assigned as the minimum breadth of a Grid track. |
jackalmage@10078 | 2595 | |
jackalmage@10078 | 2596 | <dt><dfn>RemainingSpace</dfn> |
jackalmage@10078 | 2597 | <dd>The max of zero and the AvailableSpace less the sum of all Grid track UsedBreadth values. |
jackalmage@10078 | 2598 | This is undefined if AvailableSpace is undefined |
jackalmage@10078 | 2599 | (i.e. the Grid element is shrink-to-fit or the height is auto.) |
jackalmage@10078 | 2600 | |
jackalmage@10078 | 2601 | <dt><dfn>SpanCount</dfn> |
jackalmage@10078 | 2602 | <dd>The number of Grid tracks crossed by a Grid item in the applicable dimension. |
jackalmage@7249 | 2603 | </dl> |
jackalmage@7249 | 2604 | |
jackalmage@8974 | 2605 | <h3 id="track-sizing-algorithm"> |
jackalmage@7249 | 2606 | Grid Track Sizing Algorithm</h3> |
jackalmage@10078 | 2607 | |
jackalmage@7249 | 2608 | <ol> |
jackalmage@7249 | 2609 | <li>Call ComputedUsedBreadthOfGridTracks for Grid Columns to resolve their logical width. |
jackalmage@8856 | 2610 | <li>Call ComputedUsedBreadthOfGridTracks for Grid Rows to resolve their logical height. The logical width of Grid Columns from the prior step is used in the formatting of <a>Grid items</a> in content-sized Grid Rows to determine their required height. |
jackalmage@8856 | 2611 | <li>If the minimum content size of any <a>Grid item</a> has changed based on available height for the <a>Grid item</a> as computed in step 2, adjust the min content size of the <a>Grid item</a> and restart the <a>Grid track</a> Sizing algorithm (once only). |
jackalmage@7249 | 2612 | </ol> |
jackalmage@7249 | 2613 | |
jackalmage@7249 | 2614 | <dl> |
jackalmage@8856 | 2615 | <dt id="function-ComputeUsedBreadthOfGridTracks">ComputeUsedBreadthOfGridTracks |
jackalmage@7251 | 2616 | |
jackalmage@7249 | 2617 | <dd> |
jackalmage@7249 | 2618 | <p> |
jackalmage@8856 | 2619 | This is the core <a>Grid track</a> sizing algorithm. It is run for Grid columns and Grid rows. The goal of the function is to ensure: |
jackalmage@7251 | 2620 | |
jackalmage@7249 | 2621 | <ol> |
jackalmage@8856 | 2622 | <li>That each <a>Grid track</a> satisfies its MinTrackSizingFunction |
jackalmage@8856 | 2623 | <li>That each <a>Grid track</a> grows from the breadth which satisfied its MinTrackSizingFunction to a breadth which satisfies its MaxTrackSizingFunction, subject to RemainingSpace. |
jackalmage@7249 | 2624 | </ol> |
jackalmage@7249 | 2625 | <p> |
jackalmage@8856 | 2626 | For the purposes of resolving the breadth that satisfies the MinTrackSizingFunction and MaxTrackSizingFunction, each <a>Grid track</a> falls into one of three categories: |
jackalmage@7251 | 2627 | |
jackalmage@7249 | 2628 | <ol> |
jackalmage@7249 | 2629 | <li>A percentage or length value which can be trivially resolved. |
jackalmage@8856 | 2630 | <li>A min-content or max-content value which will be resolved based on the measurements of the <a>Grid items</a> which cover the <a>Grid track</a>. |
jackalmage@8856 | 2631 | <li>A flexible length which can only be resolved after determining the RemainingSpace in the <a>grid container</a>’s content box after having considered all contributions from the prior two categories of <a>Grid tracks</a>. |
jackalmage@7249 | 2632 | </ol> |
jackalmage@7249 | 2633 | <p> |
jackalmage@8856 | 2634 | The breadths which satisfy MinTrackSizingFunctions and MaxTrackSizingFunctions for the first category of <a>Grid tracks</a> are resolved in step 1 during <a>Grid track</a> variable initialization. |
jackalmage@8856 | 2635 | The breadths which satisfy the MinTrackSizingFunctions and the MaxTrackSizingFunctions for the second category of content-sized <a>Grid tracks</a> are resolved in step 2. At the end of step 2, the first goal of ComputeUsedBreadthOfGridTracks function has been satisfied: |
jackalmage@8856 | 2636 | the UsedBreadth variable of each GridTrack now satisfies its MinTrackSizingFunction. The MaxBreadth variable for each <a>Grid track</a> now contains the resolved value for its MaxTrackSizingFunction. |
jackalmage@7251 | 2637 | |
jackalmage@7249 | 2638 | <p> |
jackalmage@8856 | 2639 | In step 3, the second goal of this function is satisfied as each (non-flex-sized) <a>Grid track</a> |
jackalmage@7249 | 2640 | attempts to grow from the UsedBreadth value to the MaxBreadth value, subject to RemainingSpace. |
jackalmage@7251 | 2641 | |
jackalmage@7249 | 2642 | <p> |
jackalmage@8856 | 2643 | Finally in step 4, the third category of flex-sized <a>Grid tracks</a> can be resolved using what is now the RemainingSpace having updated the UsedBreadth of each <a>Grid track</a> at the end of step 3. |
jackalmage@7251 | 2644 | |
jackalmage@7249 | 2645 | <dl> |
jackalmage@8856 | 2646 | <dt id="function-ComputeUsedBreadthOfGridTracks-inputs">Inputs |
jackalmage@7251 | 2647 | |
jackalmage@7249 | 2648 | <dd> |
jackalmage@7249 | 2649 | <ul> |
jackalmage@8856 | 2650 | <li>GridTracks: The set of <a>Grid tracks</a> for which the <a>Grid track</a> variable UsedBreadth will be computed. |
jackalmage@7249 | 2651 | </ul> |
jackalmage@7251 | 2652 | |
jackalmage@7249 | 2653 | </dl> |
jackalmage@7249 | 2654 | <dl> |
jackalmage@8856 | 2655 | <dt id="function-ComputeUsedBreadthOfGridTracks-algorithm">Algorithm |
jackalmage@7251 | 2656 | |
jackalmage@7249 | 2657 | <dd class="pseudo-code"> |
jackalmage@7249 | 2658 | <ol> |
jackalmage@8856 | 2659 | <li>Initialize per <a>Grid track</a> variables |
jackalmage@7249 | 2660 | <ol> |
jackalmage@8856 | 2661 | <li>For each <a>Grid track</a> t in GridTracks |
jackalmage@7249 | 2662 | <ol> |
jackalmage@7249 | 2663 | <li>If t.MinTrackSizingFunction is a percentage or length, then t.UsedBreadth = resolved length |
jackalmage@7742 | 2664 | <li>If t.MinTrackSizingFunction is min-content, max-content, or a flexible length, then t.UsedBreadth = 0 |
jackalmage@7249 | 2665 | <li>If t.MaxTrackSizingFunction is percentage or length, then t.MaxBreadth = resolved length |
jackalmage@7249 | 2666 | <ol> |
jackalmage@7249 | 2667 | <li>If the resolved length of the MaxTrackSizingFunction is less than the MinTrackSizingFunction, t.MaxBreadth = t.UsedBreadth. |
jackalmage@7249 | 2668 | </ol> |
jackalmage@7251 | 2669 | |
jackalmage@7249 | 2670 | <li>If t.MaxTrackSizingFunction is min-content, or max-content, then t.MaxBreadth = Infinity |
jackalmage@7742 | 2671 | <li>If t.MaxTrackSizingFunction is a flexible length, then t.MaxBreadth = t.UsedBreadth |
jackalmage@7249 | 2672 | <li>t.SpanGroupInWhichMaxBreadthWasMadeFinite = null |
jackalmage@7249 | 2673 | </ol> |
jackalmage@7251 | 2674 | |
jackalmage@7249 | 2675 | </ol> |
jackalmage@7251 | 2676 | |
jackalmage@7249 | 2677 | <li>Resolve content-based TrackSizingFunctions |
jackalmage@7249 | 2678 | <ol> |
jackalmage@7249 | 2679 | <li>Call ResolveContentBasedTrackSizingFunctions, with arguments: |
jackalmage@7249 | 2680 | <ul> |
jackalmage@8856 | 2681 | <li>GridItems: All <a>Grid items</a>. |
jackalmage@7249 | 2682 | </ul> |
jackalmage@7251 | 2683 | |
jackalmage@7249 | 2684 | </ol> |
jackalmage@7251 | 2685 | |
jackalmage@8856 | 2686 | <li>Grow all <a>Grid tracks</a> in GridTracks from their UsedBreadth up to their MaxBreadth value until RemainingSpace is exhausted. |
jackalmage@7249 | 2687 | <ol> |
jackalmage@7249 | 2688 | <li>If RemainingSpace is defined |
jackalmage@7249 | 2689 | <ol> |
jackalmage@7249 | 2690 | <li>Iterate over all GridTracks and assign UsedBreadth to UpdatedTrackBreadth |
jackalmage@7249 | 2691 | <li>Call DistributeSpaceToTracks, with arguments: |
jackalmage@7249 | 2692 | <ul> |
jackalmage@7249 | 2693 | <li>SpaceToDistribute: RemainingSpace |
jackalmage@8856 | 2694 | <li>TrackGrowthConstraint: A function which given a <a>Grid track</a> returns its MaxBreadth. |
jackalmage@8856 | 2695 | <li>TracksForGrowth: All <a>Grid tracks</a> |
jackalmage@7249 | 2696 | <li>SubsetOfTracksForGrowthBeyondTrackGrowthConstraint: The empty set. |
jackalmage@8856 | 2697 | <li>CurrentBreadth: A function which given a <a>Grid track</a> returns the UsedBreadth. |
jackalmage@7249 | 2698 | </ul> |
jackalmage@7251 | 2699 | |
jackalmage@7249 | 2700 | <li>Iterate over all GridTracks and assign UpdatedTrackBreadth to UsedBreadth |
jackalmage@7249 | 2701 | </ol> |
jackalmage@7251 | 2702 | |
jackalmage@7249 | 2703 | <li>Else |
jackalmage@7249 | 2704 | <ol> |
jackalmage@8856 | 2705 | <li>For each <a>Grid track</a> t in GridTracks |
jackalmage@7249 | 2706 | <ol> |
jackalmage@7249 | 2707 | <li>t.UsedBreadth = t.MaxBreadth |
jackalmage@7249 | 2708 | </ol> |
jackalmage@7251 | 2709 | |
jackalmage@7249 | 2710 | </ol> |
jackalmage@7251 | 2711 | |
jackalmage@7249 | 2712 | </ol> |
jackalmage@7251 | 2713 | |
jackalmage@8856 | 2714 | <li>Grow all <a>Grid tracks</a> having a flexible length as the MaxTrackSizingFunction |
jackalmage@7249 | 2715 | <ol> |
jackalmage@7742 | 2716 | <li>normalizedFlexBreadth = 0 |
jackalmage@7249 | 2717 | <li>If RemainingSpace is defined |
jackalmage@7249 | 2718 | <ol> |
jackalmage@7742 | 2719 | <li>normalizedFlexBreadth = Call ComputeNormalizedFlexBreadth, with arguments: |
jackalmage@7249 | 2720 | <ul> |
jackalmage@7249 | 2721 | <li>GridTracks: GridTracks |
jackalmage@7249 | 2722 | <li>SpaceToFill: AvailableSpace |
jackalmage@7249 | 2723 | </ul> |
jackalmage@7251 | 2724 | |
jackalmage@7249 | 2725 | </ol> |
jackalmage@7251 | 2726 | |
jackalmage@7249 | 2727 | <li>Else |
jackalmage@7249 | 2728 | <ol> |
jackalmage@8856 | 2729 | <li>For each <a>Grid track</a> t in GridTracks having a flexible length as the MaxTrackSizingFunction |
jackalmage@7249 | 2730 | <ol> |
jackalmage@7742 | 2731 | <li>normalizedFlexBreadth = Max( normalizedFlexBreadth, t.UsedBreadth / t.MaxTrackSizingFunction.FlexValue ) |
jackalmage@7251 | 2732 | |
jackalmage@7249 | 2733 | </ol> |
jackalmage@7251 | 2734 | |
jackalmage@8856 | 2735 | <li>For each <a>Grid item</a> i, which crosses a set of GridTracks s |
jackalmage@7249 | 2736 | <ol> |
jackalmage@7742 | 2737 | <li>itemNormalizedFlexBreadth = Call ComputeNormalizedFlexBreadth, with arguments: |
jackalmage@7249 | 2738 | <ul> |
jackalmage@7249 | 2739 | <li>GridTracks: s |
jackalmage@7249 | 2740 | <li>SpaceToFill: max-content size of i |
jackalmage@7249 | 2741 | </ul> |
jackalmage@7251 | 2742 | |
jackalmage@7742 | 2743 | <li>normalizedFlexBreadth = Max( normalizedFlexBreadth, itemNormalizedFlexBreadth ) |
jackalmage@7251 | 2744 | |
jackalmage@7249 | 2745 | </ol> |
jackalmage@7251 | 2746 | |
jackalmage@7249 | 2747 | </ol> |
jackalmage@7251 | 2748 | |
jackalmage@8856 | 2749 | <li>For each <a>Grid track</a> t in GridTracks |
jackalmage@7249 | 2750 | <ol> |
jackalmage@7742 | 2751 | <li>t.UsedBreadth = Max( t.UsedBreadth, normalizedFlexBreadth * t.MaxTrackSizingFunction.FlexValue ) |
jackalmage@7249 | 2752 | </ol> |
jackalmage@7251 | 2753 | |
jackalmage@7249 | 2754 | </ol> |
jackalmage@7251 | 2755 | |
jackalmage@7249 | 2756 | </ol> |
jackalmage@7251 | 2757 | |
jackalmage@7249 | 2758 | </dl> |
jackalmage@7251 | 2759 | |
jackalmage@7249 | 2760 | <!--End Function Definition: ComputeUsedBreadthOfGridTracks--> |
jackalmage@7249 | 2761 | </dl> |
jackalmage@7249 | 2762 | |
jackalmage@7249 | 2763 | <dl> |
jackalmage@8856 | 2764 | <dt id="function-ResolveContentBasedTrackSizingFunctions">ResolveContentBasedTrackSizingFunctions |
jackalmage@7251 | 2765 | |
jackalmage@7249 | 2766 | <dd> |
jackalmage@7249 | 2767 | <p> |
jackalmage@8856 | 2768 | The purpose of this function is to resolve the contribution that each <a>Grid item</a> makes to any min-content or max-content TrackSizingFunctions for the <a>Grid tracks</a> it covers. There are four permutations: min-content or max-content in either the MinTrackSizingFunction or MaxTrackSizingFunction. MinTrackSizingFunctions are resolved before MaxTrackSizingFunctions, and min-content contributions are resolved before max-content contributions. Note that when resolving min-content contributions they may grow tracks that have either min-content or max-content keywords, as seen in 3.a.i and 3.b.i below. |
jackalmage@7251 | 2769 | |
jackalmage@7249 | 2770 | <p class="issue"> |
jackalmage@8856 | 2771 | Currently this algorithm embodies several heuristics which regulate the growth of spanning <a>Grid items</a> to accommodate certain use cases. (E.g. the game example in Figures 2 and 3 above.) These heuristics should be a normative part of this specification to ensure interoperability. To the extent additional use cases can be identified that cannot be satisfied by following the current heuristics, the normative algorithm can be updated, or additional mechanisms can be introduced for fine-grained control of content-based TrackSizingFunction. |
jackalmage@7251 | 2772 | |
jackalmage@7249 | 2773 | <dl> |
jackalmage@8856 | 2774 | <dt id="function-ResolveContentBasedTrackSizingFunctions-inputs">Inputs |
jackalmage@7251 | 2775 | |
jackalmage@7249 | 2776 | <dd> |
jackalmage@7249 | 2777 | <ul> |
jackalmage@8856 | 2778 | <li>GridItems: The set of <a>Grid items</a> for which min-content or max-content keywords should be resolved. |
jackalmage@7249 | 2779 | </ul> |
jackalmage@7251 | 2780 | |
jackalmage@7249 | 2781 | </dl> |
jackalmage@7249 | 2782 | <dl> |
jackalmage@8856 | 2783 | <dt id="function-ResolveContentBasedTrackSizingFunctions-algorithm">Algorithm |
jackalmage@7251 | 2784 | |
jackalmage@7249 | 2785 | <dd class="pseudo-code"> |
jackalmage@7249 | 2786 | <ol> |
jackalmage@8856 | 2787 | <li>Filter all <a>Grid items</a> into a set g, such that each <a>Grid item</a> has either a SpanCount of 1 or does not cross a flex-sized <a>Grid track</a> |
jackalmage@8856 | 2788 | <li>Group all <a>Grid items</a> in set g by their SpanCount ascending |
jackalmage@8856 | 2789 | <li>For each group of <a>Grid items</a> |
jackalmage@7249 | 2790 | <ol> |
jackalmage@7249 | 2791 | <li>Resolve content-based MinTrackSizingFunctions |
jackalmage@7249 | 2792 | <ol> |
jackalmage@7249 | 2793 | <li>Call ResolveContentBasedTrackSizingFunctionsForItems, with arguments: |
jackalmage@7249 | 2794 | <ul> |
jackalmage@8856 | 2795 | <li>GridItems: All <a>Grid items</a> in the current group. |
jackalmage@8856 | 2796 | <li>AdditionalSpaceRequiredByItem: A function which given a <a>Grid item</a> returns the min-content size of that <a>Grid item</a> less the summed UsedBreadth of all <a>Grid tracks</a> it covers. |
jackalmage@8856 | 2797 | <li>TrackGrowthConstraint: A function which given a <a>Grid track</a> returns its MaxBreadth. |
jackalmage@8856 | 2798 | <li>TracksForGrowth: A function which given a <a>Grid item</a> returns the set of <a>Grid tracks</a> covered by that <a>Grid item</a> that have a min-content or max-content MinTrackSizingFunction. |
jackalmage@8856 | 2799 | <li>SubsetOfTracksForGrowthBeyondTrackGrowthConstraint: A function which given a set of <a>Grid tracks</a> returns the subset of <a>Grid tracks</a> having a min-content or max-content MaxTrackSizingFunction. If that set is the empty set, return the input set instead. |
jackalmage@8856 | 2800 | <li>Accumulator: A function which given a <a>Grid track</a> returns a reference to its UsedBreadth variable. |
jackalmage@7249 | 2801 | </ul> |
jackalmage@7251 | 2802 | |
jackalmage@7249 | 2803 | <li>Call ResolveContentBasedTrackSizingFunctionsForItems, with arguments: |
jackalmage@7249 | 2804 | <ul> |
jackalmage@8856 | 2805 | <li>GridItems: All <a>Grid items</a> in the current group. |
jackalmage@8856 | 2806 | <li>AdditionalSpaceRequiredByItem: A function which given a <a>Grid item</a> returns the max-content size of that <a>Grid item</a> less the summed UsedBreadth of all <a>Grid tracks</a> it covers. |
jackalmage@8856 | 2807 | <li>TrackGrowthConstraint: A function which given a <a>Grid track</a> returns its MaxBreadth. |
jackalmage@8856 | 2808 | <li>TracksForGrowth: A function which given a <a>Grid item</a> returns the set of <a>Grid tracks</a> covered by that <a>Grid item</a> that have a max-content MinTrackSizingFunction. |
jackalmage@8856 | 2809 | <li>SubsetOfTracksForGrowthBeyondTrackGrowthConstraint: A function which given a set of <a>Grid tracks</a> returns the subset of <a>Grid tracks</a> having a max-content MaxTrackSizingFunction. If that set is the empty set, return the input set instead. |
jackalmage@8856 | 2810 | <li>Accumulator: A function which given a <a>Grid track</a> returns a reference to its UsedBreadth variable. |
jackalmage@7249 | 2811 | </ul> |
jackalmage@7251 | 2812 | |
jackalmage@7249 | 2813 | </ol> |
jackalmage@7251 | 2814 | |
jackalmage@7249 | 2815 | <li>Resolve content-based MaxTrackSizingFunctions |
jackalmage@7249 | 2816 | <ol> |
jackalmage@7249 | 2817 | <li>Call ResolveContentBasedTrackSizingFunctionsForItems, with arguments: |
jackalmage@7249 | 2818 | <ul> |
jackalmage@8856 | 2819 | <li>GridItems: All <a>Grid items</a> in the current group. |
jackalmage@8856 | 2820 | <li>AdditionalSpaceRequiredByItem: A function which given a <a>Grid item</a> returns the min-content size of that <a>Grid item</a> less the summed MaxBreadth (unless the MaxBreadth is infinite, in which case use the UsedBreadth) of all <a>Grid tracks</a> it covers. |
jackalmage@8856 | 2821 | <li>TrackGrowthConstraint: A function which given a <a>Grid track</a> returns its MaxBreadth. |
jackalmage@8856 | 2822 | <li>TracksForGrowth: A function which given a <a>Grid item</a> returns the set of <a>Grid tracks</a> covered by that <a>Grid item</a> that have a min-content or max-content MaxTrackSizingFunction. |
jackalmage@7249 | 2823 | <li>SubsetOfTracksForGrowthBeyondTrackGrowthConstraint: The identity function. |
jackalmage@8856 | 2824 | <li>Accumulator: A function which given a <a>Grid track</a> returns a reference to its MaxBreadth variable. |
jackalmage@7249 | 2825 | </ul> |
jackalmage@7251 | 2826 | |
jackalmage@7249 | 2827 | <li>Call ResolveContentBasedTrackSizingFunctionsForItems, with arguments: |
jackalmage@7249 | 2828 | <ul> |
jackalmage@8856 | 2829 | <li>GridItems: All <a>Grid items</a> in the current group. |
jackalmage@8856 | 2830 | <li>AdditionalSpaceRequiredByItem: A function which given a <a>Grid item</a> returns the max-content size of that <a>Grid item</a> less the summed MaxBreadth (unless the MaxBreadth is infinite, in which case use the UsedBreadth) of all <a>Grid tracks</a> it covers. |
jackalmage@8856 | 2831 | <li>TrackGrowthConstraint: A function which given a <a>Grid track</a> returns infinity if the <a>Grid track</a>’s SpanGroupInWhichMaxBreadthWasMadeFinite is equal to the current group; otherwise return the <a>Grid track</a>’s MaxBreadth. |
jackalmage@8856 | 2832 | <li>TracksForGrowth: A function which given a <a>Grid item</a> returns the set of <a>Grid tracks</a> covered by that <a>Grid item</a> that have a max-content MaxTrackSizingFunction. |
jackalmage@7249 | 2833 | <li>SubsetOfTracksForGrowthBeyondTrackGrowthConstraint: The identity function. |
jackalmage@8856 | 2834 | <li>Accumulator: A function which given a <a>Grid track</a> returns a reference to its MaxBreadth variable. |
jackalmage@7249 | 2835 | </ul> |
jackalmage@7251 | 2836 | |
jackalmage@7249 | 2837 | </ol> |
jackalmage@7251 | 2838 | |
jackalmage@7249 | 2839 | </ol> |
jackalmage@7251 | 2840 | |
jackalmage@8856 | 2841 | <li>For each <a>Grid track</a> t from the set of all <a>Grid tracks</a> |
jackalmage@7249 | 2842 | <ol> |
jackalmage@7249 | 2843 | <li>If t.MaxBreadth == infinity then t.MaxBreadth = t.UsedBreadth |
jackalmage@7249 | 2844 | </ol> |
jackalmage@7251 | 2845 | |
jackalmage@7249 | 2846 | </ol> |
jackalmage@7251 | 2847 | |
jackalmage@7249 | 2848 | </dl> |
jackalmage@7251 | 2849 | |
jackalmage@7249 | 2850 | <!--End Function Definition: ResolveContentBasedTrackSizingFunctions--> |
jackalmage@7249 | 2851 | </dl> |
jackalmage@7249 | 2852 | |
jackalmage@7249 | 2853 | <dl> |
jackalmage@8856 | 2854 | <dt id="function-ResolveContentBasedTrackSizingFunctionsForItems">ResolveContentBasedTrackSizingFunctionsForItems |
jackalmage@7251 | 2855 | |
jackalmage@7249 | 2856 | <dd> |
jackalmage@7249 | 2857 | <p> |
jackalmage@8856 | 2858 | The above function, ResolveContentBasedTrackSizingFunctions, groups <a>Grid items</a> based on the number of <a>Grid tracks</a> each <a>Grid item</a> spanned. ResolveContentBasedTrackSizingFunctionsForItems, below, then calls DistributeSpaceToTracks for each <a>Grid item</a> in the |
jackalmage@8856 | 2859 | group to determine how much each <a>Grid item</a> needs to grow the <a>Grid tracks</a> that it covers. The maximum contribution made by any <a>Grid item</a> is accumulated into a temporary, per-<a>Grid track</a> variable, |
jackalmage@8856 | 2860 | and at the end of the group, the space is recorded into a final <a>Grid track</a> variable as determined by the Accumulator function. |
jackalmage@7251 | 2861 | |
jackalmage@7249 | 2862 | <dl> |
jackalmage@8856 | 2863 | <dt id="function-ResolveContentBasedTrackSizingFunctionsForItems-inputs">Inputs |
jackalmage@7251 | 2864 | |
jackalmage@7249 | 2865 | <dd> |
jackalmage@7249 | 2866 | <ul> |
jackalmage@8856 | 2867 | <li>GridItems: The set of <a>Grid items</a> which will contribute to the growth of <a>Grid tracks</a>. |
jackalmage@8856 | 2868 | <li>AdditionalSpaceRequiredByItem: A function which returns the difference between either the min-content or max-content for the <a>Grid item</a> and the space already allocated to the <a>Grid tracks</a> covered by the <a>Grid item</a> in earlier phases of the algorithm. |
jackalmage@8856 | 2869 | <li>TrackGrowthConstraint: A function which given a <a>Grid track</a> returns a value that limits the amount by which it may be grown by the <a>Grid items</a> which cover it. |
jackalmage@8856 | 2870 | <li>TracksForGrowth: A function which given a <a>Grid item</a> identifies the set of <a>Grid tracks</a> to be grown in this phase of the algorithm. |
jackalmage@8856 | 2871 | <li>SubsetOfTracksForGrowthBeyondTrackGrowthConstraint: A function which identifies a subset of <a>Grid tracks</a> from TracksForGrowth that may be grown in this phase of the algorithm after all <a>Grid tracks</a> in the TracksForGrowth set have already grown to their TrackGrowthConstraint. |
jackalmage@8856 | 2872 | <li>Accumulator: A function which given a <a>Grid track</a> returns the variable used to accumulate the results of the UpdatedTrackBreadth from DistributeSpaceToTracks. |
jackalmage@7249 | 2873 | </ul> |
jackalmage@7251 | 2874 | |
jackalmage@7249 | 2875 | </dl> |
jackalmage@7249 | 2876 | <dl> |
jackalmage@8856 | 2877 | <dt id="function-ResolveContentBasedTrackSizingFunctionsForItems-algorithm">Algorithm |
jackalmage@7251 | 2878 | |
jackalmage@7249 | 2879 | <dd class="pseudo-code"> |
jackalmage@7249 | 2880 | <ol> |
jackalmage@8856 | 2881 | <li>For each <a>Grid track</a> t |
jackalmage@7249 | 2882 | <ol> |
jackalmage@7250 | 2883 | <li>t.UpdatedTrackBreadth = Accumulator( t ) |
jackalmage@7249 | 2884 | </ol> |
jackalmage@7251 | 2885 | |
jackalmage@8856 | 2886 | <li>For each <a>Grid item</a> i in GridItems |
jackalmage@7249 | 2887 | <ol> |
jackalmage@7249 | 2888 | <li>Call DistributeSpaceToTracks, with arguments: |
jackalmage@7249 | 2889 | <ul> |
jackalmage@7249 | 2890 | <li>SpaceToDistribute: AdditionalSpaceRequiredByItem( i ) |
jackalmage@7249 | 2891 | <li>TrackGrowthConstraint: TrackGrowthConstraint |
jackalmage@7249 | 2892 | <li>TracksForGrowth: TracksForGrowth( i ) |
jackalmage@7249 | 2893 | <li>SubsetOfTracksForGrowthBeyondTrackGrowthConstraint: SubsetOfTracksForGrowthBeyondTrackGrowthConstraint( TracksForGrowth( i ) ) |
jackalmage@8856 | 2894 | <li>CurrentBreadth: A function which given a <a>Grid track</a> returns the UsedBreadth of the <a>Grid track</a> if Accumulator returns infinity; otherwise the value of the Accumulator is returned. |
jackalmage@7249 | 2895 | </ul> |
jackalmage@7251 | 2896 | |
jackalmage@7249 | 2897 | </ol> |
jackalmage@7251 | 2898 | |
jackalmage@8856 | 2899 | <li>For each <a>Grid track</a> t |
jackalmage@7249 | 2900 | <ol> |
jackalmage@7249 | 2901 | <li>If Accumulator( t ) == infinity and t.UpdatedTrackBreadth != infinity |
jackalmage@7249 | 2902 | <ol> |
jackalmage@7249 | 2903 | <li>t.SpanGroupInWhichMaxBreadthWasMadeFinite = GridItems |
jackalmage@7249 | 2904 | </ol> |
jackalmage@7251 | 2905 | |
jackalmage@7249 | 2906 | <li>Accumulator( t ) = t.UpdatedTrackBreadth |
jackalmage@7249 | 2907 | </ol> |
jackalmage@7251 | 2908 | |
jackalmage@7249 | 2909 | </ol> |
jackalmage@7251 | 2910 | |
jackalmage@7249 | 2911 | </dl> |
jackalmage@7251 | 2912 | |
jackalmage@7249 | 2913 | <!--End Function Definition: ResolveContentBasedTrackSizingFunctionsForItems--> |
jackalmage@7249 | 2914 | </dl> |
jackalmage@7249 | 2915 | |
jackalmage@7249 | 2916 | <dl> |
jackalmage@8856 | 2917 | <dt id="function-DistributeSpaceToTracks">DistributeSpaceToTracks |
jackalmage@7251 | 2918 | |
jackalmage@7249 | 2919 | <dd> |
jackalmage@7249 | 2920 | <p> |
jackalmage@8856 | 2921 | Ensures that for each <a>Grid track</a> in RecipientTracks, a value will be computed, UpdatedTrackBreadth, that represents the <a>Grid track</a>’s share of SpaceToDistribute. |
jackalmage@7251 | 2922 | |
jackalmage@7249 | 2923 | <p> |
jackalmage@8856 | 2924 | There are two parts to this function. The first for loop in step 2 is giving each <a>Grid track</a> an equal share of the space, but without exceeding their TrackGrowthConstraint values. |
jackalmage@8856 | 2925 | Because there are different MaxBreadths assigned to the different <a>Grid tracks</a>, the first loop can result in their uneven growth. |
jackalmage@7251 | 2926 | |
jackalmage@7249 | 2927 | <p> |
jackalmage@8856 | 2928 | If the first loop completes having grown every <a>Grid track</a> to its TrackGrowthConstraint, and there is still SpaceToDistribute, then SubsetOfTracksForGrowthBeyondTrackGrowthConstraint are further grown equally until SpaceToDistribute is exhausted. |
jackalmage@7251 | 2929 | |
jackalmage@7249 | 2930 | <p> |
jackalmage@8856 | 2931 | Note that <a>Grid tracks</a> considered by this function may have a TrackGrowthConstraint equal to Infinity, which signals that these tracks have not yet been grown by a <a>Grid item</a>. These tracks can therefore be grown without exceeding the TrackGrowthConstraint of the track. By only growing tracks up to their TrackGrowthConstraint value, we can ensure that the grid remains "tight" - that is, that track breadth is as close to the content size of the <a>Grid items</a> inside as possible. Only once all <a>Grid tracks</a> have a CurrentBreadth equal to a TrackGrowthConstraint do we move to the second for loop and grow tracks further, thereby making the <a>grid container</a> less tight. |
jackalmage@7251 | 2932 | |
jackalmage@7249 | 2933 | <dl> |
jackalmage@8856 | 2934 | <dt id="function-DistributeSpaceToTracks-inputs">Inputs |
jackalmage@7251 | 2935 | |
jackalmage@7249 | 2936 | <dd> |
jackalmage@7249 | 2937 | <ul> |
jackalmage@8856 | 2938 | <li>SpaceToDistribute: A length to be distributed among the supplied set of <a>Grid tracks</a>. |
jackalmage@8856 | 2939 | <li>TrackGrowthConstraint: A function which given a <a>Grid track</a> returns the maximum breadth of the track, unless the track is in the SubsetOfTracksForGrowthBeyoundTrackGrowthConstraint. |
jackalmage@8856 | 2940 | <li>TracksForGrowth: A set of <a>Grid tracks</a> to be grown up to their TrackGrowthConstraint while SpaceToDistribute remains. |
jackalmage@8856 | 2941 | <li>SubsetOfTracksForGrowthBeyondTrackGrowthConstraint: A subset of <a>Grid tracks</a> from TracksForGrowth that may be grown beyond their TrackGrowthConstraint after all <a>Grid tracks</a> in the TracksForGrowth set have already grown to their TrackGrowthConstraint if there is remaining SpaceToDistribute. |
jackalmage@8856 | 2942 | <li>CurrentBreadth: A function which given a <a>Grid track</a> returns a value to use as a starting point from which to grow this track. |
jackalmage@7249 | 2943 | </ul> |
jackalmage@7251 | 2944 | |
jackalmage@7249 | 2945 | </dl> |
jackalmage@7249 | 2946 | <dl> |
jackalmage@8856 | 2947 | <dt id="function-DistributeSpaceToTracks-algorithm">Algorithm |
jackalmage@7251 | 2948 | |
jackalmage@7249 | 2949 | <dd class="pseudo-code"> |
jackalmage@7249 | 2950 | <ol> |
jackalmage@7249 | 2951 | <li>Sort TracksForGrowth by TrackGrowthConstraint( t ) - CurrentBreadth( t ) ascending (where t is an element in the RecipientTrack set). |
jackalmage@7249 | 2952 | <li>For i = 0 to TracksForGrowth.length - 1 |
jackalmage@7249 | 2953 | <ol> |
jackalmage@7249 | 2954 | <li>t = TracksForGrowth[i] |
jackalmage@7249 | 2955 | <li>share = Min ((SpaceToDistribute / ( TracksForGrowth.length - i )), (TrackGrowthConstraint( t ) - CurrentBreadth( t ))) |
jackalmage@7249 | 2956 | <li>t.TempBreadth = CurrentBreadth( t ) + share |
jackalmage@7249 | 2957 | <li>SpaceToDistribute -= share |
jackalmage@7249 | 2958 | </ol> |
jackalmage@7251 | 2959 | |
jackalmage@7249 | 2960 | <li>If SpaceToDistribute > 0 |
jackalmage@7249 | 2961 | <ol> |
jackalmage@7249 | 2962 | <li>Let tracks = SubsetOfTracksForGrowthBeyondTrackGrowthConstraint( TracksForGrowth ) |
jackalmage@7249 | 2963 | <li>For i = 0 to tracks.length - 1 |
jackalmage@7249 | 2964 | <ol> |
jackalmage@7249 | 2965 | <li>t = tracks[i] |
jackalmage@7249 | 2966 | <li>share = SpaceToDistribute / ( tracks.length - i ) |
jackalmage@7249 | 2967 | <li>t.TempBreadth += share |
jackalmage@7249 | 2968 | <li>SpaceToDistribute -= share |
jackalmage@7249 | 2969 | </ol> |
jackalmage@7251 | 2970 | |
jackalmage@7249 | 2971 | </ol> |
jackalmage@7251 | 2972 | |
jackalmage@8856 | 2973 | <li>For each <a>Grid track</a> t in TracksForGrowth |
jackalmage@7249 | 2974 | <ol> |
jackalmage@7249 | 2975 | <li>If t.UpdatedTrackBreadth == infinity |
jackalmage@7249 | 2976 | <ol> |
jackalmage@7249 | 2977 | <li>t.UpdatedTrackBreadth = t.TempBreadth |
jackalmage@7249 | 2978 | </ol> |
jackalmage@7251 | 2979 | |
jackalmage@7249 | 2980 | <li>Else |
jackalmage@7249 | 2981 | <ol> |
jackalmage@7249 | 2982 | <li>t.UpdatedTrackBreadth = Max( t.UpdatedTrackBreadth, t.TempBreadth ) |
jackalmage@7249 | 2983 | </ol> |
jackalmage@7251 | 2984 | |
jackalmage@7249 | 2985 | </ol> |
jackalmage@7251 | 2986 | |
jackalmage@7249 | 2987 | </ol> |
jackalmage@7251 | 2988 | |
jackalmage@7249 | 2989 | </dl> |
jackalmage@7251 | 2990 | |
jackalmage@7249 | 2991 | <!--End Function Definition: DistributeSpaceToTracks--> |
jackalmage@7249 | 2992 | </dl> |
jackalmage@7249 | 2993 | |
jackalmage@7249 | 2994 | |
jackalmage@7249 | 2995 | <dl> |
jackalmage@8856 | 2996 | <dt id="function-CalculateNormalizedFlexBreadth">CalculateNormalizedFlexBreadth |
jackalmage@7251 | 2997 | |
jackalmage@7249 | 2998 | <dd> |
jackalmage@8856 | 2999 | This method computes a ''1fr'' value, referred to as the NormalizedFlexBreadth, for a set of <a>Grid tracks</a>. The value computed will ensure that when the NormalizedFlexBreadth is multiplied by the flex factors associated with GridTracks, that the UsedBreadths of GridTracks will increase by an amount equal to the maximum of zero and the specified SpaceToFill less the sum of the current UsedBreadths. |
jackalmage@7249 | 3000 | <dl> |
jackalmage@8856 | 3001 | <dt id="function-CalculateNormalizedFlexBreadth-inputs"> |
jackalmage@8856 | 3002 | Inputs |
jackalmage@7251 | 3003 | |
jackalmage@7249 | 3004 | <dd> |
jackalmage@7249 | 3005 | <ul> |
jackalmage@8856 | 3006 | <li>GridTracks: The set of <a>Grid tracks</a> whose flex sizing functions are considered for the purposes of a computing a NormalizedFlexBreadth that will cause GridTracks to fill SpaceToFill. |
jackalmage@7249 | 3007 | <li>SpaceToFill: The space to be filled by GridTracks. |
jackalmage@7249 | 3008 | </ul> |
jackalmage@7251 | 3009 | |
jackalmage@7249 | 3010 | </dl> |
jackalmage@7249 | 3011 | <dl> |
jackalmage@8856 | 3012 | <dt id="function-CalculateNormalizedFlexBreadth-returns">Returns |
jackalmage@7251 | 3013 | |
jackalmage@7249 | 3014 | <dd> |
jackalmage@7249 | 3015 | <ul> |
jackalmage@7249 | 3016 | <li>The 1fr value required by GridTracks to fill SpaceToFill. |
jackalmage@7249 | 3017 | </ul> |
jackalmage@7251 | 3018 | |
jackalmage@7249 | 3019 | </dl> |
jackalmage@7249 | 3020 | <dl> |
jackalmage@8856 | 3021 | <dt id="function-CalculateNormalizedFlexBreadth-algorithm">Algorithm |
jackalmage@7251 | 3022 | |
jackalmage@7249 | 3023 | <dd class="pseudo-code"> |
jackalmage@7249 | 3024 | <ol> |
jackalmage@8856 | 3025 | <li>allocatedSpace = the sum of the UsedBreadth for each <a>Grid track</a> in GridTracks |
jackalmage@7742 | 3026 | <li>flexTracks = the subset of GridTracks whose MaxTrackSizingFunction is a flexible length |
jackalmage@8856 | 3027 | <li>For each <a>Grid track</a> t in flexTracks |
jackalmage@7249 | 3028 | <ol> |
jackalmage@7742 | 3029 | <li>t.NormalizedFlexValue = t.UsedBreadth / t.MaxTrackSizingFunction.FractionValue |
jackalmage@7249 | 3030 | </ol> |
jackalmage@7251 | 3031 | |
jackalmage@7742 | 3032 | <li>Sort flexTracks by their NormalizedFlexValue ascending |
jackalmage@7742 | 3033 | <li>spaceNeededFromFlexTracks = SpaceToFill - allocatedSpace |
jackalmage@7249 | 3034 | <li>currentBandFractionBreadth = accumulatedFractions = 0 |
jackalmage@8856 | 3035 | <li>For each <a>Grid track</a> t in flexTracks |
jackalmage@7249 | 3036 | <ol> |
jackalmage@7742 | 3037 | <li>If t.NormalizedFlexValue > currentBandFractionBreadth |
jackalmage@7249 | 3038 | <ol> |
jackalmage@7742 | 3039 | <li>If t.NormalizedFlexValue * accumulatedFractions > spaceNeededFromFlexTracks then break from for loop |
jackalmage@7742 | 3040 | <li>currentBandFractionBreadth = t.NormalizedFlexValue |
jackalmage@7249 | 3041 | </ol> |
jackalmage@7251 | 3042 | |
jackalmage@7249 | 3043 | <li>accumulatedFractions += t.MaxTrackSizingFunction.FractionValue |
jackalmage@7742 | 3044 | <li>spaceNeededFromFlexTracks += t.UsedBreadth |
jackalmage@7249 | 3045 | </ol> |
jackalmage@7251 | 3046 | |
jackalmage@7742 | 3047 | <li>return spaceNeededFromFlexTracks / accumulatedFractions |
jackalmage@7249 | 3048 | </ol> |
jackalmage@7251 | 3049 | |
jackalmage@7249 | 3050 | </dl> |
jackalmage@7249 | 3051 | </dl> |
jackalmage@7249 | 3052 | |
jackalmage@9732 | 3053 | <h3 id='intrinsic-sizes'> |
jackalmage@9732 | 3054 | Intrinsic Sizing</h3> |
jackalmage@9732 | 3055 | |
jackalmage@9732 | 3056 | For a <a>grid container</a>, |
jackalmage@9732 | 3057 | the <a>min-content measure</a> is the sum of the UsedBreadths of the <a>Grid tracks</a> just before step 3 in ComputeUsedBreadthOfGridTracks. |
jackalmage@9732 | 3058 | and the <a>preferred measure</a> is the sum of the UsedBreadths of the <a>Grid tracks</a> after the entire track sizing algorithm has been run with infinite space. |
jackalmage@9732 | 3059 | |
jackalmage@9732 | 3060 | <p class='issue'> |
jackalmage@9732 | 3061 | This section'll need updating after the algorithm is rewritten. |
jackalmage@7249 | 3062 | |
jackalmage@10078 | 3063 | |
jackalmage@10078 | 3064 | |
jackalmage@10078 | 3065 | |
jackalmage@10078 | 3066 | <h2 id='tab-layout-algorithm'> |
jackalmage@10078 | 3067 | Translated Grid Layout Algorithm</h2> |
jackalmage@10078 | 3068 | |
jackalmage@10078 | 3069 | <h3 id='algo-terms'> |
jackalmage@10078 | 3070 | Definition of Terms for use in Calculating Grid Track Sizes</h3> |
jackalmage@10078 | 3071 | |
jackalmage@10078 | 3072 | <dl> |
jackalmage@10078 | 3073 | <dt><dfn>min track sizing function</dfn> |
jackalmage@10078 | 3074 | <dd> |
jackalmage@10078 | 3075 | If the track was sized with a ''minmax()'' function, |
jackalmage@10078 | 3076 | this is the first argument to that function. |
jackalmage@10078 | 3077 | Otherwise, it's the track's sizing function. |
jackalmage@10078 | 3078 | |
jackalmage@10078 | 3079 | <dt><dfn>max track sizing function</dfn> |
jackalmage@10078 | 3080 | <dd> |
jackalmage@10078 | 3081 | If the track was sized with a ''minmax()'' function, |
jackalmage@10078 | 3082 | this is the second argument to that function. |
jackalmage@10078 | 3083 | Otherwise, it's the track's sizing function. |
jackalmage@10078 | 3084 | |
jackalmage@10078 | 3085 | <dt><dfn>available space</dfn> |
jackalmage@10078 | 3086 | <dd> |
jackalmage@10078 | 3087 | The <a>grid container</a>’s content box size in the applicable dimension. |
jackalmage@10078 | 3088 | |
jackalmage@10078 | 3089 | <dt><dfn>remaining space</dfn> |
jackalmage@10078 | 3090 | <dd> |
jackalmage@10078 | 3091 | Equal to the <a>available space</a> minus the sum of the <a>base sizes</a> of all the grid tracks. |
jackalmage@10078 | 3092 | This value can change over the course of the algorithm, |
jackalmage@10078 | 3093 | as <a>base sizes</a> are adjusted. |
jackalmage@10078 | 3094 | If the sum of the <a>base sizes</a> is greater than the <a>available space</a>, |
jackalmage@10078 | 3095 | the <a>remaining space</a> is instead zero. |
jackalmage@10078 | 3096 | |
jackalmage@10078 | 3097 | If <a>available space</a> is <a>indefinite</a>, |
jackalmage@10078 | 3098 | the <a>remaining space</a> is <a>indefinite</a> as well. |
jackalmage@10078 | 3099 | |
jackalmage@10078 | 3100 | <dt><dfn>span count</dfn> |
jackalmage@10078 | 3101 | <dd> |
jackalmage@10078 | 3102 | The number of <a>grid tracks</a> crossed by a <a>grid item</a> in the applicable dimension. |
jackalmage@10078 | 3103 | </dl> |
jackalmage@10078 | 3104 | |
jackalmage@10078 | 3105 | <h3 id='algo-overview'> |
jackalmage@10078 | 3106 | Overall Sizing Algorithm</h3> |
jackalmage@10078 | 3107 | |
jackalmage@10078 | 3108 | <pre class='issue'> |
jackalmage@10078 | 3109 | 1. Find the used size of all grid columns. |
jackalmage@10078 | 3110 | 2. Find the used size of all grid rows. |
jackalmage@10078 | 3111 | 3. If the minimum content size of any grid item |
jackalmage@10078 | 3112 | has changed based on step 2's computations, |
jackalmage@10078 | 3113 | rerun this algorithm once. |
jackalmage@10078 | 3114 | </pre> |
jackalmage@10078 | 3115 | |
jackalmage@10078 | 3116 | <p class='issue'> |
jackalmage@10078 | 3117 | What situations trigger step 3? |
jackalmage@10078 | 3118 | |
jackalmage@10078 | 3119 | <h3 id="algo-find-size"> |
jackalmage@10078 | 3120 | Find the Used Size of Grid Tracks</h4> |
jackalmage@10078 | 3121 | |
jackalmage@10078 | 3122 | This algorithm is run against either the grid columns or the grid rows. |
jackalmage@10078 | 3123 | |
jackalmage@10078 | 3124 | <b>Initialize each track's base size and growth limit.</b> |
jackalmage@10078 | 3125 | Each track has a <dfn>base size</dfn>, |
jackalmage@10078 | 3126 | a <<length>> which grows throughout the algorithm |
jackalmage@10078 | 3127 | and which will eventually be the track's final size, |
jackalmage@10078 | 3128 | and a <dfn>growth limit</dfn>, |
jackalmage@10078 | 3129 | a <<length>> which provides a desired maximum size for the <a>base size</a>. |
jackalmage@10078 | 3130 | (The <a>base size</a> might end up being larger than the <a>growth limit</a>, |
jackalmage@10078 | 3131 | but the algorithm attempts to avoid this situation.) |
jackalmage@10078 | 3132 | |
jackalmage@10078 | 3133 | For each track, |
jackalmage@10078 | 3134 | if the track's <a>min track sizing function</a> is: |
jackalmage@10078 | 3135 | |
jackalmage@10078 | 3136 | <dl> |
jackalmage@10078 | 3137 | <dt>a <a>definite</a> length |
jackalmage@10078 | 3138 | <dd> |
jackalmage@10078 | 3139 | the track's <a>base size</a> is that length. |
jackalmage@10078 | 3140 | |
jackalmage@10078 | 3141 | Note: <a>Indefinite</a> lengths cannot occur, |
jackalmage@10078 | 3142 | as they're as ''auto''. |
jackalmage@10078 | 3143 | |
jackalmage@10078 | 3144 | <dt>''min-content'' or ''max-content'' |
jackalmage@10078 | 3145 | <dt><<flex>> |
jackalmage@10078 | 3146 | <dd> |
jackalmage@10078 | 3147 | the track's <a>base size</a> is zero. |
jackalmage@10078 | 3148 | </dl> |
jackalmage@10078 | 3149 | |
jackalmage@10078 | 3150 | For each track, |
jackalmage@10078 | 3151 | if the track's <a>max track sizing function</a> is: |
jackalmage@10078 | 3152 | |
jackalmage@10078 | 3153 | <dl> |
jackalmage@10078 | 3154 | <dt>a <a>definite</a> length |
jackalmage@10078 | 3155 | <dd> |
jackalmage@10078 | 3156 | the track's <a>growth limit</a> is that length. |
jackalmage@10078 | 3157 | |
jackalmage@10078 | 3158 | <dt>''min-content'' or ''max-content'' |
jackalmage@10078 | 3159 | <dd> |
jackalmage@10078 | 3160 | the track's <a>growth limit</a> is infinity. |
jackalmage@10078 | 3161 | |
jackalmage@10078 | 3162 | <dt><<flex>> |
jackalmage@10078 | 3163 | <dd> |
jackalmage@10078 | 3164 | the track's <a>growth limit</a> is its <a>base size</a>. |
jackalmage@10078 | 3165 | </dl> |
jackalmage@10078 | 3166 | |
jackalmage@10078 | 3167 | |
jackalmage@10078 | 3168 | <h3 id="algo-content"> |
jackalmage@10078 | 3169 | Resolve Content-Based Track Sizing Functions</h3> |
jackalmage@10078 | 3170 | |
jackalmage@10078 | 3171 | This step determines the contribution that each <a>grid item</a> makes |
jackalmage@10078 | 3172 | to any ''min-content'' or ''max-content'' track sizing functions. |
jackalmage@10078 | 3173 | |
jackalmage@10078 | 3174 | It is run multiple times, |
jackalmage@10078 | 3175 | once for each set of <a>grid items</a> with a particular <a>span count</a>, |
jackalmage@10078 | 3176 | and each time it moves through four phases, |
jackalmage@10078 | 3177 | each one addressing one combination of ''min-content'' or ''max-content'' |
jackalmage@10078 | 3178 | as a <a>min track sizing function</a> or <a>max track sizing function</a>. |
jackalmage@10078 | 3179 | |
jackalmage@10078 | 3180 | Note: There is no single way to satisfy these constraints |
jackalmage@10078 | 3181 | when items span across multiple tracks. |
jackalmage@10078 | 3182 | This algorithm embodies a number of heuristics |
jackalmage@10078 | 3183 | which have been seen to deliver good results on real-world use-cases, |
jackalmage@10078 | 3184 | such as the "game" examples earlier in this specification. |
jackalmage@10078 | 3185 | This algorithm may be updated in the future |
jackalmage@10078 | 3186 | to take into account more advanced heuristics as they are identified. |
jackalmage@10078 | 3187 | |
jackalmage@10078 | 3188 | Starting from the set of all <a>grid items</a> in the grid, |
jackalmage@10078 | 3189 | remove any with a <a>span count</a> greater than one |
jackalmage@10078 | 3190 | which span a track with a <<flex>> <a>max track sizing function</a>. |
jackalmage@10078 | 3191 | Of the remaining, |
jackalmage@10078 | 3192 | sort them into groups according to their <a>span count</a>, |
jackalmage@10078 | 3193 | and order the groups in ascending order of <a>span count</a>. |
jackalmage@10078 | 3194 | For each group, in order, |
jackalmage@10078 | 3195 | perform the following steps four times: |
jackalmage@10078 | 3196 | |
jackalmage@10078 | 3197 | <ol> |
jackalmage@10078 | 3198 | <li> |
jackalmage@10078 | 3199 | <b>Initialize variables</b>. |
jackalmage@10078 | 3200 | |
jackalmage@10078 | 3201 | Let each item's <dfn>needed space</dfn> be: |
jackalmage@10078 | 3202 | |
jackalmage@10078 | 3203 | <dl> |
jackalmage@10078 | 3204 | <dt>In phase 1 |
jackalmage@10078 | 3205 | <dd> |
jackalmage@10078 | 3206 | The min-content size of the item, |
jackalmage@10078 | 3207 | minus the sum of the <a>base sizes</a> of the grid tracks it spans. |
jackalmage@10078 | 3208 | <dt>In phase 2 |
jackalmage@10078 | 3209 | <dd> |
jackalmage@10078 | 3210 | The max-content size of the item, |
jackalmage@10078 | 3211 | minus the sum of the <a>base sizes</a> of the grid tracks it spans. |
jackalmage@10078 | 3212 | <dt>In phase 3 |
jackalmage@10078 | 3213 | <dd> |
jackalmage@10078 | 3214 | The min-content size of the item, |
jackalmage@10078 | 3215 | minus the sum of the <a>growth limits</a> of the grid tracks it spans |
jackalmage@10078 | 3216 | (or, if the <a>growth limit</a> is infinite, the <a>base size</a>). |
jackalmage@10078 | 3217 | <dt>In phase 4 |
jackalmage@10078 | 3218 | <dd> |
jackalmage@10078 | 3219 | The max-content size of the item, |
jackalmage@10078 | 3220 | minus the sum of the <a>growth limits</a> of the grid tracks it spans |
jackalmage@10078 | 3221 | (or, if the <a>growth limit</a> is infinite, the <a>base size</a>). |
jackalmage@10078 | 3222 | </dl> |
jackalmage@10078 | 3223 | |
jackalmage@10078 | 3224 | Let each item's <dfn>growable tracks</dfn> be: |
jackalmage@10078 | 3225 | |
jackalmage@10078 | 3226 | <dl> |
jackalmage@10078 | 3227 | <dt>In phase 1 |
jackalmage@10078 | 3228 | <dd> |
jackalmage@10078 | 3229 | The grid tracks it spans with a ''min-content'' or ''max-content'' <a>min track sizing function</a>. |
jackalmage@10078 | 3230 | <dt>In phase 2 |
jackalmage@10078 | 3231 | <dd> |
jackalmage@10078 | 3232 | The grid tracks it spans with a ''max-content'' <a>min track sizing function</a>. |
jackalmage@10078 | 3233 | <dt>In phase 3 |
jackalmage@10078 | 3234 | <dd> |
jackalmage@10078 | 3235 | The grid tracks it spans with a ''min-content'' or ''max-content'' <a>max track sizing function</a>. |
jackalmage@10078 | 3236 | <dt>In phase 4 |
jackalmage@10078 | 3237 | <dd> |
jackalmage@10078 | 3238 | The grid tracks it spans with a ''max-content'' <a>max track sizing function</a>. |
jackalmage@10078 | 3239 | </dl> |
jackalmage@10078 | 3240 | |
jackalmage@10078 | 3241 | Let each item's <dfn>overgrowable tracks</dfn> be: |
jackalmage@10078 | 3242 | |
jackalmage@10078 | 3243 | <dl> |
jackalmage@10078 | 3244 | <dt>In phase 1 |
jackalmage@10078 | 3245 | <dd> |
jackalmage@10078 | 3246 | The item's <a>growable tracks</a> that also have a ''min-content'' or ''max-content'' <a>max track sizing function</a>. |
jackalmage@10078 | 3247 | If there are no such tracks, |
jackalmage@10078 | 3248 | then it's all the <a>growable tracks</a>. |
jackalmage@10078 | 3249 | <dt>In phase 2 |
jackalmage@10078 | 3250 | <dd> |
jackalmage@10078 | 3251 | The item's <a>growable tracks</a> that also have a ''max-content'' <a>max track sizing function</a>. |
jackalmage@10078 | 3252 | If there ar eno such tracks, |
jackalmage@10078 | 3253 | then it's all the <a>growable tracks</a>. |
jackalmage@10078 | 3254 | <dt>In phase 3 |
jackalmage@10078 | 3255 | <dt>In phase 4 |
jackalmage@10078 | 3256 | <dd> |
jackalmage@10078 | 3257 | The item's <a>growable tracks</a>. |
jackalmage@10078 | 3258 | </dl> |
jackalmage@10078 | 3259 | |
jackalmage@10078 | 3260 | Let each track's <dfn>growth delta</dfn> initially be zero. |
jackalmage@10078 | 3261 | |
jackalmage@10078 | 3262 | <li> |
jackalmage@10078 | 3263 | <b>Calculate growth deltas.</b> |
jackalmage@10078 | 3264 | |
jackalmage@10078 | 3265 | For each grid item in the group: |
jackalmage@10078 | 3266 | |
jackalmage@10078 | 3267 | <ol> |
jackalmage@10078 | 3268 | <li> |
jackalmage@10078 | 3269 | <dl> |
jackalmage@10078 | 3270 | <dt>In phase 1 |
jackalmage@10078 | 3271 | <dt>In phase 2 |
jackalmage@10078 | 3272 | <dd> |
jackalmage@10078 | 3273 | Let each track's <dfn>hypothetical size</dfn> |
jackalmage@10078 | 3274 | be the track's <a>base size</a>. |
jackalmage@10078 | 3275 | <dt>In phase 3 |
jackalmage@10078 | 3276 | <dt>In phase 4 |
jackalmage@10078 | 3277 | <dd> |
jackalmage@10078 | 3278 | Let each track's <a>hypothetical size</a> |
jackalmage@10078 | 3279 | be the track's <a>growth limit</a> if it's finite, |
jackalmage@10078 | 3280 | or else the track's <a>base size</a> otherwise. |
jackalmage@10078 | 3281 | </dl> |
jackalmage@10078 | 3282 | |
jackalmage@10078 | 3283 | <li> |
jackalmage@10078 | 3284 | Distribute the item's <a>needed space</a> |
jackalmage@10078 | 3285 | as evenly as possible among the <a>hypothetical sizes</a> of the item's <a>growable tracks</a>, |
jackalmage@10078 | 3286 | maxing each out as its <a>hypothetical size</a> reaches its <a>growth limit</a>. |
jackalmage@10078 | 3287 | |
jackalmage@10078 | 3288 | <dl> |
jackalmage@10078 | 3289 | <dt>In phase 4 |
jackalmage@10078 | 3290 | <dd> |
jackalmage@10078 | 3291 | If the track's <a>growth limit</a> was changed from infinite to a finite value |
jackalmage@10078 | 3292 | in phase 3, |
jackalmage@10078 | 3293 | treat its <a>growth limit</a> as infinite for the purposes of this step. |
jackalmage@10078 | 3294 | </dl> |
jackalmage@10078 | 3295 | |
jackalmage@10078 | 3296 | <li> |
jackalmage@10078 | 3297 | If all <a>growable tracks</a> reached their <a>growth limit</a> in the previous step |
jackalmage@10078 | 3298 | and there is still <a>needed space</a> to distribute, |
jackalmage@10078 | 3299 | distribute the leftover space evenly among the <a>hypothetical sizes</a> of the item's <a>overgrowable tracks</a>. |
jackalmage@10078 | 3300 | |
jackalmage@10078 | 3301 | <li> |
jackalmage@10078 | 3302 | <dl> |
jackalmage@10078 | 3303 | <dt>In phase 1 |
jackalmage@10078 | 3304 | <dt>In phase 2 |
jackalmage@10078 | 3305 | <dd> |
jackalmage@10078 | 3306 | For each track, |
jackalmage@10078 | 3307 | if the difference between its <a>hypothetical size</a> and its <a>base size</a> |
jackalmage@10078 | 3308 | is greater than its <a>growth delta</a>, |
jackalmage@10078 | 3309 | set its <a>growth delta</a> to that difference. |
jackalmage@10078 | 3310 | <dt>In phase 3 |
jackalmage@10078 | 3311 | <dd>In phase 4 |
jackalmage@10078 | 3312 | <dd> |
jackalmage@10078 | 3313 | For each track, |
jackalmage@10078 | 3314 | if its <a>growth limit</a> is finite, |
jackalmage@10078 | 3315 | and the difference between its <a>hypothetical size</a> and its <a>growth limit</a> |
jackalmage@10078 | 3316 | is greater than its <a>growth delta</a>, |
jackalmage@10078 | 3317 | set its <a>growth delta</a> to that difference. |
jackalmage@10078 | 3318 | Otherwise, if its <a>growth limit</a> is infinite, |
jackalmage@10078 | 3319 | and the difference between its <a>hypothetical size</a> and its <a>base size</a> |
jackalmage@10078 | 3320 | is greater than its <a>growth delta</a>, |
jackalmage@10078 | 3321 | set its <a>growth delta</a> to that difference. |
jackalmage@10078 | 3322 | </dl> |
jackalmage@10078 | 3323 | </ol> |
jackalmage@10078 | 3324 | |
jackalmage@10078 | 3325 | <li> |
jackalmage@10078 | 3326 | <b>Adjust each track's affected size.</b> |
jackalmage@10078 | 3327 | |
jackalmage@10078 | 3328 | <dl> |
jackalmage@10078 | 3329 | <dt>In phase 1 |
jackalmage@10078 | 3330 | <dt>In phase 2 |
jackalmage@10078 | 3331 | <dd> |
jackalmage@10078 | 3332 | For each track, |
jackalmage@10078 | 3333 | increase its <a>base size</a> by its <a>growth delta</a>. |
jackalmage@10078 | 3334 | <dt>In phase 3 |
jackalmage@10078 | 3335 | <dt>In phase 4 |
jackalmage@10078 | 3336 | For each track, |
jackalmage@10078 | 3337 | if its <a>growth limit</a> is finite, |
jackalmage@10078 | 3338 | increase its <a>growth limit</a> by its <a>growth delta</a>. |
jackalmage@10078 | 3339 | Otherwise, if its <a>growth limit</a> is infinite, |
jackalmage@10078 | 3340 | set its <a>growth limit</a> |
jackalmage@10078 | 3341 | to the sum of its <a>base size</a> and its <a>growth delta</a>. |
jackalmage@10078 | 3342 | </dl> |
jackalmage@10078 | 3343 | </ol> |
jackalmage@10078 | 3344 | |
jackalmage@10078 | 3345 | <h3 id="algo-grow-tracks"> |
jackalmage@10078 | 3346 | Grow All Tracks To Their Max</h3> |
jackalmage@10078 | 3347 | |
jackalmage@10078 | 3348 | If <a>remaining space</a> is a definite value, |
jackalmage@10078 | 3349 | distribute the <a>remaining space</a> |
jackalmage@10078 | 3350 | as evenly as possible among the <a>base sizes</a> of all the tracks, |
jackalmage@10078 | 3351 | maxing each out as its <a>base size</a> reaches its <a>growth limit</a>. |
jackalmage@10078 | 3352 | |
jackalmage@10078 | 3353 | If <a>remaining space</a> is indefinite, |
jackalmage@10078 | 3354 | then for each track whose <a>base size</a> is less than its <a>growth limit</a>, |
jackalmage@10078 | 3355 | set its <a>base size</a> to its <a>growth limit</a>. |
jackalmage@10078 | 3356 | |
jackalmage@10078 | 3357 | <h3 id="algo-flex-tracks"> |
jackalmage@10078 | 3358 | Process Flexible Tracks</h3> |
jackalmage@10078 | 3359 | |
jackalmage@10078 | 3360 | |
jackalmage@10078 | 3361 | |
jackalmage@10078 | 3362 | |
jackalmage@10078 | 3363 | |
jackalmage@10078 | 3364 | |
jackalmage@10078 | 3365 | |
fantasai@10071 | 3366 | <h2 id='layout-algorithm-fantasai'> |
fantasai@10071 | 3367 | Rewritten Grid Layout Algorithm</h2> |
fantasai@10071 | 3368 | |
fantasai@10071 | 3369 | <p class='issue'> |
fantasai@10071 | 3370 | This should be functionally identical to the Microsoft algorithm. |
fantasai@10071 | 3371 | If not, please let Tab and fantasai know in what cases it's not! |
fantasai@10071 | 3372 | |
fantasai@10071 | 3373 | Each track has a <dfn title="minimum track size">minimum</dfn> and |
fantasai@10071 | 3374 | a <dfn title="maximum track size">maximum</dfn> <i>sizing function</i> |
fantasai@10071 | 3375 | (which may be the same). |
fantasai@10071 | 3376 | Each <i>sizing function</i> is either: |
fantasai@10071 | 3377 | <ul> |
fantasai@10071 | 3378 | <li>A fixed size (<<length>> or resolved <<percentage>>). |
fantasai@10071 | 3379 | <li>An intrinsic size (''min-content'' or ''max-content''). |
fantasai@10071 | 3380 | <li>A flexible size (<<flex>>). |
fantasai@10071 | 3381 | </ul> |
fantasai@10071 | 3382 | |
fantasai@10071 | 3383 | The grid layout algorithm defines how to resolve these sizing constraints into used track sizes. |
fantasai@10071 | 3384 | The grid items are then laid out into their respective <i>grid areas</i>. |
fantasai@10071 | 3385 | |
fantasai@10071 | 3386 | <ol> |
fantasai@10071 | 3387 | <li>First, the <i>track sizing algorithm</i> is used to resolve the sizes of the grid columns. |
fantasai@10071 | 3388 | <li>Next, the <i>track sizing algorithm</i> resolves the sizes of the grid rows. |
fantasai@10071 | 3389 | <li>Then, if the <i>min-size contribution</i> of any grid items have changed |
fantasai@10071 | 3390 | based on the row sizes calculated in step 2, |
fantasai@10071 | 3391 | steps 1 and 2 are repeated with the new <i>min-size contribution</i> (once only). |
fantasai@10071 | 3392 | <p class='issue'> |
fantasai@10071 | 3393 | What is this solving and is this the right solution? |
fantasai@10071 | 3394 | </ol> |
fantasai@10071 | 3395 | |
fantasai@10071 | 3396 | The remainder of this section is the <dfn>track sizing algorithm</dfn>. There are four steps: |
fantasai@10071 | 3397 | <ol> |
fantasai@10071 | 3398 | <li><a href="#init-sizes">Initializing Used Sizes</a> |
fantasai@10071 | 3399 | <li><a href="#resolve-intrinsic">Resolving Intrinsic Track Sizes</a> |
fantasai@10071 | 3400 | <li><a href="#resolve-minmax">Distributing Free Space to ''minmax()'' Ranges</a> |
fantasai@10071 | 3401 | <li><a href="#resolve-flex">Distributing Free Space to Flexible Lengths</a> |
fantasai@10071 | 3402 | </ol> |
fantasai@10071 | 3403 | |
fantasai@10071 | 3404 | <h3 id='init-sizes'> |
fantasai@10071 | 3405 | Initialize Minimum and Maximum Track Sizes</h3> |
fantasai@10071 | 3406 | |
fantasai@10071 | 3407 | For fixed track sizes, |
fantasai@10071 | 3408 | use that resolved size. |
fantasai@10071 | 3409 | |
fantasai@10071 | 3410 | For intrinsic track sizes, |
fantasai@10071 | 3411 | use an initial <i>minimum track size</i> of zero and an initial <i>maximum track size</i> of infinity. |
fantasai@10071 | 3412 | |
fantasai@10071 | 3413 | For flexible track sizes, |
fantasai@10071 | 3414 | use an initial <i>maximum track size</i> of infinity. |
fantasai@10071 | 3415 | |
fantasai@10071 | 3416 | A flexible <i>minimum track size</i> is treated exactly as a fixed track size of zero; |
fantasai@10071 | 3417 | except when the <i>grid container</i> is being sized under a <i>min-content constraint</i>, |
fantasai@10071 | 3418 | in which case it is treated exactly as ''min-content''. |
fantasai@10071 | 3419 | <span class='issue'>This seems correct, but should be checked because it wasn't in the original algorithm.</span> |
fantasai@10071 | 3420 | |
fantasai@10071 | 3421 | These initial sizes will be resolved in subsequent steps. |
fantasai@10071 | 3422 | |
fantasai@10071 | 3423 | <h3 id="resolve-intrinsic"> |
fantasai@10071 | 3424 | Resolve Intrinsic Track Sizes</h3> |
fantasai@10071 | 3425 | |
fantasai@10071 | 3426 | The following steps resolve intrinsic track sizes to used lengths. |
fantasai@10071 | 3427 | First it resolves those sizes based on items that are contained wholly within a single track. |
fantasai@10071 | 3428 | Then it gradually adds in the space requirements of items that span multiple tracks, |
fantasai@10071 | 3429 | evenly increasing their sizes insofar as possible. |
fantasai@10071 | 3430 | |
fantasai@10071 | 3431 | <ol> |
fantasai@10071 | 3432 | <li> |
fantasai@10071 | 3433 | For each track with an intrinsic size, consider the items with a span of 1: |
fantasai@10071 | 3434 | <ul> |
fantasai@10071 | 3435 | <li>Set any ''min-content'' track size to the maximum of their <i>min-size contributions</i>. |
fantasai@10071 | 3436 | <li>Set any ''max-content'' track size to the maximum of their <i>max-size contributions</i>. |
fantasai@10071 | 3437 | </ul> |
fantasai@10071 | 3438 | <li> |
fantasai@10071 | 3439 | Next, consider the items with a span of 2 |
fantasai@10071 | 3440 | and that do not span a track with a flexible maximum size: |
fantasai@10071 | 3441 | <ol> |
fantasai@10071 | 3442 | <li> |
fantasai@10071 | 3443 | First increase any ''min-content'' <i>minimum track sizes</i> |
fantasai@10071 | 3444 | by <a href="#extra-space">distributing extra space</a> |
fantasai@10071 | 3445 | as needed to any tracks with intrinsic minimum sizes |
fantasai@10071 | 3446 | to account for these items' <i>min-size contributions</i>. |
fantasai@10071 | 3447 | <li> |
fantasai@10071 | 3448 | Next increase any ''max-content'' <i>minimum track sizes</i> |
fantasai@10071 | 3449 | by <a href="#extra-space">distributing extra space</a> |
fantasai@10071 | 3450 | as needed to any tracks with max-content minimum sizes |
fantasai@10071 | 3451 | to account for these items' <i>max-size contributions</i>. |
fantasai@10071 | 3452 | <li> |
fantasai@10071 | 3453 | Third increase any ''min-content'' <i>maximum track sizes</i> |
fantasai@10071 | 3454 | by <a href="#extra-space">distributing extra space</a> |
fantasai@10071 | 3455 | as needed to any tracks with intrinsic maximum sizes |
fantasai@10071 | 3456 | to account for these items' <i>min-size contributions</i>. |
fantasai@10071 | 3457 | <li> |
fantasai@10071 | 3458 | Lastly increase any ''max-content'' <i>maximum track sizes</i> |
fantasai@10071 | 3459 | by <a href="#extra-space">distributing extra space</a> |
fantasai@10071 | 3460 | as needed to any tracks with max-content maximum sizes |
fantasai@10071 | 3461 | to account for these items' <i>min-size contributions</i>. |
fantasai@10071 | 3462 | </ol> |
fantasai@10071 | 3463 | |
fantasai@10071 | 3464 | Repeat incrementally for items with greater spans until all items have been considered. |
fantasai@10071 | 3465 | </ol> |
fantasai@10071 | 3466 | |
fantasai@10071 | 3467 | <p id='extra-space'> |
fantasai@10071 | 3468 | To <dfn noexport>distribute extra space</dfn> required by a set of intrinsic size contributions, |
fantasai@10071 | 3469 | <ol> |
fantasai@10071 | 3470 | <li> |
fantasai@10071 | 3471 | Maintain separately for each affected track size an amount of planned increase. |
fantasai@10071 | 3472 | (This prevents the size increases from becoming order-dependent.) |
fantasai@10071 | 3473 | |
fantasai@10071 | 3474 | For each considered item, |
fantasai@10071 | 3475 | <ol> |
fantasai@10071 | 3476 | <li> |
fantasai@10071 | 3477 | Subtract the corresponding (non-infinite) sizes of all spanned tracks |
fantasai@10071 | 3478 | from its size contribution to find the item's remaining size contribution. |
fantasai@10071 | 3479 | This is the space to distribute. |
fantasai@10071 | 3480 | <pre><var>extra-space</var> = <var>size-contribution</var> - ∑<var>track-sizes</var></pre> |
fantasai@10071 | 3481 | <li> |
fantasai@10071 | 3482 | Distribute the space evenly to the tracked increase of each spanned track with an affected size, |
fantasai@10071 | 3483 | dropping maxed-out tracks as they hit their maximums. |
fantasai@10071 | 3484 | <pre><var>track-size-increase</var> = max(<var>track-size-increase</var>, <var>share-of-extra-space</var>)</pre> |
fantasai@10071 | 3485 | <li> |
fantasai@10071 | 3486 | If space remains after all tracks max out, continue to increase… |
fantasai@10071 | 3487 | <ul> |
fantasai@10071 | 3488 | <li> |
fantasai@10071 | 3489 | for ''min-content'' minimum sizes, |
fantasai@10071 | 3490 | any affected tracks that happen to also have intrinsic maximum sizes; |
fantasai@10071 | 3491 | else all affected tracks. |
fantasai@10071 | 3492 | <li> |
fantasai@10071 | 3493 | for ''max-content'' minimum sizes, |
fantasai@10071 | 3494 | any affected tracks that happen to also have max-content maximum sizes; |
fantasai@10071 | 3495 | else all affected tracks. |
fantasai@10071 | 3496 | <li>for intrinsic maximum sizes, |
fantasai@10071 | 3497 | all affected tracks |
fantasai@10071 | 3498 | </ul> |
fantasai@10071 | 3499 | <li> |
fantasai@10071 | 3500 | Update the tracks' affected sizes by folding in the calculated increase |
fantasai@10071 | 3501 | so that the next round of space distribution will account for the increase. |
fantasai@10071 | 3502 | </ol> |
fantasai@10071 | 3503 | </ol> |
fantasai@10071 | 3504 | |
fantasai@10071 | 3505 | At this point, all intrinsic <i title="minimum track size">minimum</i>and <i title="maximum track size">maximum track sizes</i> |
fantasai@10071 | 3506 | will have been resolved to their used lengths. |
fantasai@10071 | 3507 | |
fantasai@10071 | 3508 | <h3 id="resolve-minmax"> |
fantasai@10071 | 3509 | Distribute Free Space to ''minmax()'' Ranges</h3> |
fantasai@10071 | 3510 | |
fantasai@10071 | 3511 | Size all tracks to their <i>minimum track size</i> |
fantasai@10071 | 3512 | and find the remaining space (the <i>free space</i>) in the <i>grid container</i>. |
fantasai@10071 | 3513 | If sizing under a max-content constraint, the <i>free space</i> for this step is infinite. |
fantasai@10071 | 3514 | If sizing under a min-content constraint, the <i>free space</i> for this step is zero. |
fantasai@10071 | 3515 | If this <i>free space</i> is positive, distribute it evenly to all tracks, |
fantasai@10071 | 3516 | dropping maxed-out tracks as they hit their maximum sizes. |
fantasai@10071 | 3517 | |
fantasai@10071 | 3518 | <h3 id="resolve-flex"> |
fantasai@10071 | 3519 | Distribute Free Space to Flexible Lengths</h3> |
fantasai@10071 | 3520 | |
fantasai@10071 | 3521 | If the remaining <i>free space</i> after the previous step is finite and positive, |
fantasai@10071 | 3522 | find the <i>flex fraction</i> by dividing the this space by the sum of all the tracks' <i>flex factors</i>. |
fantasai@10071 | 3523 | |
fantasai@10071 | 3524 | Otherwise, if the <i>free space</i> is not finite |
fantasai@10071 | 3525 | (i.e. when the grid container's is sized under a max-content or preferred-size constraint |
fantasai@10071 | 3526 | or it is auto-sized in infinite available space), |
fantasai@10071 | 3527 | find the <i>flex fraction</i> by taking the maximum of: |
fantasai@10071 | 3528 | <ul> |
fantasai@10071 | 3529 | <li> |
fantasai@10071 | 3530 | Each flexible track's minimum size divided by its <i>flex factor</i>. |
fantasai@10071 | 3531 | <li> |
fantasai@10071 | 3532 | The <i>max-size contribution</i> of each item in a flexible track divided by that track's <i>flex factor</i>. |
fantasai@10071 | 3533 | For items that span multiple tracks, |
fantasai@10071 | 3534 | first subtract the used sizes of all spanned non-flexible tracks from the item's <i>max-size contribution</i>, |
fantasai@10071 | 3535 | then divide by the sum of all spanned flexible tracks' <i>flex factors</i>. |
fantasai@10071 | 3536 | </ul> |
fantasai@10071 | 3537 | |
fantasai@10071 | 3538 | Size each flexible track to the product of its <i>flex factor</i> and this calculated <i>flex fraction</i>. |
jackalmage@7249 | 3539 | |
jackalmage@7249 | 3540 | <h2 id='pagination'> |
jackalmage@7249 | 3541 | Fragmenting Grid Layout</h2> |
jackalmage@7249 | 3542 | |
jackalmage@7249 | 3543 | <p class='issue'> |
jackalmage@7249 | 3544 | Fill this in. |
jackalmage@7249 | 3545 | |
jackalmage@8974 | 3546 | <h2 class="no-num" id="acks"> |
jackalmage@7249 | 3547 | Acknowledgements</h2> |
jackalmage@7249 | 3548 | <p> |
ratan@7295 | 3549 | This specification is made possible by input from Erik Anderson, Rossen Atanassov, Arron Eicholz, Sylvain Galineau, Markus Mielke, John Jansen, Chris Jones, Kathy Kam, Veljko Miljanic, Peter Salas, Christian Stockwell, Eugene Veselov, and the CSS Working Group members. Thanks to Eliot Graff for editorial input. |
jackalmage@7251 | 3550 | |
jackalmage@8789 | 3551 | <h2 class="no-num" id="changes"> |
jackalmage@8789 | 3552 | Changes</h2> |
jackalmage@8789 | 3553 | |
jackalmage@8789 | 3554 | <p> |
jackalmage@8789 | 3555 | The following significant changes were made since the |
jackalmage@8789 | 3556 | <a href="http://www.w3.org/TR/2013/WD-css3-grid-layout-20130402/">2 April 2013 Working Draft</a>. |
jackalmage@8789 | 3557 | |
jackalmage@8789 | 3558 | <ul> |
fantasai@8949 | 3559 | <li>Redesigned <a>subgrid</a> feature. |
jackalmage@8789 | 3560 | <li>Renamed all the <a href="#placement">placement properties</a> and <a href="#grid-definition">grid-defining properties</a>. |
fantasai@8948 | 3561 | <li>Added the 'grid-template' and 'grid' shorthands. |
fantasai@8949 | 3562 | <li>Changed the syntax of <a href="#named-lines">named lines</a> to use parentheses and identifiers rather than strings. |
jackalmage@9755 | 3563 | <li>Made named grid areas <a href="#implicit-named-lines">imply named grid lines</a>. |
fantasai@8949 | 3564 | <li><a href="#auto-margins">Margin alignment</a> now matches <a href="http://www.w3.org/TR/css3-flexbox">Flexbox</a> and <a href="http://www.w3.org/TR/css3-align">Box Alignment</a>. |
fantasai@8949 | 3565 | <li>Percentages are no longer resolved like they are in table layout. |
jackalmage@8789 | 3566 | <li>Refined <a href="#abspos-items">definitions of absolutely-positioned elements</a> whose containing block is a grid container. |
fantasai@8948 | 3567 | <li>Defined the <a href="#static-position">static position</a> of direct children of a <i>grid container</i>. |
fantasai@8949 | 3568 | <li>Added an option for dense packing to 'grid-auto-flow'. |
fantasai@8949 | 3569 | <li>Proposed 'grid-auto-position' property so that auto-stacking items can be controlled a bit better. (But see open issues on changing ''grid-auto-flow: none''.) |
fantasai@8949 | 3570 | <li>Rewrote and fixed errors in the <a href="#auto-placement-algo">auto-placement algorithm</a>. |
jackalmage@8789 | 3571 | <li>Marked <a href="#visibility-collapse">grid row/column collapsing</a> as an open issue. |
fantasai@8839 | 3572 | </ul> |