• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Responsive Grid Layout
2
3
4## Overview
5
6As an auxiliary positioning tool, the responsive grid layout is handy in UI design on mobile devices. It exhibits the following advantages:
7
81. Provides rules for layout design and resolves issues of dynamic layout across devices with different sizes. By dividing a page into equal-width columns and rows, you can easily locate and typeset page elements.
9
102. Provides a unified positioning method for the system to ensure layout consistency across layouts on different devices. This can reduce the complexity of design and development and improve work efficiency.
11
123. Provides a flexible spacing adjustment method for applications to accommodate special layout requirements. You can adjust the spacing between columns and between rows to control the typesetting of the entire page.
13
144. Completes the wrapping and adaptation automatically when overflow occurs. When the number of page elements exceeds the capacity of a row or column, they automatically wrap to a new row or column and adapt the typesetting to different devices.
15
16The [\<GridRow>](../reference/arkui-ts/ts-container-gridrow.md) component is the responsive grid container component and must be used together with the [\<GridCol>](../reference/arkui-ts/ts-container-gridcol.md) child component.
17
18
19## GridRow
20
21
22### Grid Breakpoints
23
24The grid system defines breakpoints, which are screen width types in effect, based on the horizontal width (screen density pixels, in vp) of the screens. You can use the breakpoints to meet specific layout requirements.
25
26By default, the grid system provides four breakpoints: xs, sm, md, and lg.
27
28| Breakpoint| Value Range (vp)       | Device Description     |
29| ---- | --------------- | --------- |
30| xs   | [0, 320)  | Device of the minimum size.|
31| sm   | [320,&nbsp;520) | Small-sized device. |
32| md   | [520,&nbsp;840) | Medium-sized device.|
33| lg   | [840,&nbsp;+∞)  | Large-sized device. |
34
35In the **\<GridRow>** component, you can use **breakpoints** to customize the value range of breakpoints. A maximum of six breakpoints are supported. In addition to the four default breakpoints, you can also enable the xl and xxl breakpoints for your application window layout.
36
37| Breakpoint| Device Description     |
38| ---- | --------- |
39| xs   | Device of the minimum size.|
40| sm   | Small-sized device. |
41| md   | Medium-sized device.|
42| lg   | Large-sized device. |
43| xl   | Extra-large-sized device.|
44| xxl  | Ultra-large-sized device.|
45
46- Set **breakpoints** with a monotonically increasing array based on the use case. Because **breakpoints** supports a maximum of six breakpoints, the maximum length of the monotonically increasing array is 5.
47
48
49  ```ts
50  breakpoints: {value: ['100vp', '200vp']}
51  ```
52
53  Enables three breakpoints: xs, sm, and md. If the value is less than 100 vp, the breakpoint is xs. If the value is 100–200 vp, the breakpoint is sm. If the value is greater than 200 vp, the breakpoint is md.
54
55
56  ```ts
57  breakpoints: {value: ['320vp', '520vp', '840vp', '1080vp']}
58  ```
59
60  Enables five breakpoints: xs, sm, md, lg, and xl. If the value is less than 320 vp, the breakpoint is xs. If the value is 320–520 vp, the breakpoint is sm. If the value is 520–840 vp, the breakpoint is md. If the value is 840–1080vp, the breakpoint is lg. If the value is greater than 1080 vp, the breakpoint is xl.
61
62- The grid system implements breakpoints by listening for the changes in the window or container size, and sets the breakpoint references through **reference**. Considering that the application may be displayed in non-full-screen mode, design the breakpoints with the application window width as the reference.
63
64In the following example, the default number of columns of a grid is 12. Breakpoints are used to divide the application window width into six ranges, where different grid items occupy a different number of columns.
65
66
67```ts
68@State bgColors: Color[] = [Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Pink, Color.Grey, Color.Blue, Color.Brown];
69...
70GridRow({
71  breakpoints: {
72    value: ['200vp', '300vp', '400vp', '500vp', '600vp'],
73    reference: BreakpointsReference.WindowSize
74  }
75}) {
76   ForEach(this.bgColors, (color, index) => {
77     GridCol({
78       span: {
79         xs: 2,
80         sm: 3,
81         md: 4,
82         lg: 6,
83         xl: 8,
84         xxl: 12
85       }
86     }) {
87       Row() {
88         Text(`${index}`)
89       }.width("100%").height('50vp')
90     }.backgroundColor(color)
91   })
92}
93```
94
95![en-us_image_0000001511421272](figures/en-us_image_0000001511421272.gif)
96
97
98### Columns
99
100In the **\<GridRow>**, **columns** is used to set the total number of columns in the responsive grid layout.
101
102- The default value of **columns** is 12. If **columns** is not set, the responsive grid layout is divided into 12 columns at any breakpoint.
103
104
105  ```ts
106  @State bgColors: Color[] = [Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Pink, Color.Grey, Color.Blue, Color.Brown];
107  ...
108  GridRow() {
109    ForEach(this.bgColors, (item, index) => {
110      GridCol() {
111        Row() {
112          Text(`${index + 1}`)
113        }.width('100%').height('50')
114      }.backgroundColor(item)
115    })
116  }
117  ```
118
119  ![en-us_image_0000001563060709](figures/en-us_image_0000001563060709.png)
120
121- When **columns** is set to a number, the responsive grid layout is divided into the specified number of columns regardless of the screen size. The following example sets the number of grid layout columns to 4 and 8 in sequence, where a child component occupies one column by default.
122
123
124  ```ts
125  @State bgColors: Color[] = [Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Pink, Color.Grey, Color.Blue, Color.Brown];
126  @State currentBp: string = 'unknown';
127  ...
128  Row() {
129    GridRow({ columns: 4 }) {
130      ForEach(this.bgColors, (item, index) => {
131        GridCol() {
132          Row() {
133            Text(`${index + 1}`)
134          }.width('100%').height('50')
135        }.backgroundColor(item)
136      })
137    }
138    .width('100%').height('100%')
139    .onBreakpointChange((breakpoint) => {
140      this.currentBp = breakpoint
141    })
142  }
143  .height(160)
144  .border({ color: Color.Blue, width: 2 })
145  .width('90%')
146
147  Row() {
148    GridRow({ columns: 8 }) {
149      ForEach(this.bgColors, (item, index) => {
150        GridCol() {
151          Row() {
152            Text(`${index + 1}`)
153          }.width('100%').height('50')
154        }.backgroundColor(item)
155      })
156    }
157    .width('100%').height('100%')
158    .onBreakpointChange((breakpoint) => {
159      this.currentBp = breakpoint
160    })
161  }
162  .height(160)
163  .border({ color: Color.Blue, width: 2 })
164  .width('90%')
165  ```
166
167  ![en-us_image_0000001511421268](figures/en-us_image_0000001511421268.png)
168
169- When **columns** is set to a value of the **GridRowColumnOption** type, you can assign values specific to the screen size (xs, sm, md, lg, xl, xxl).
170
171
172  ```ts
173  @State bgColors: Color[] = [Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Pink, Color.Grey, Color.Blue, Color.Brown]
174  GridRow({ columns: { sm: 4, md: 8 }, breakpoints: { value: ['200vp', '300vp', '400vp', '500vp', '600vp'] } }) {
175    ForEach(this.bgColors, (item, index) => {
176      GridCol() {
177        Row() {
178          Text(`${index + 1}`)
179        }.width('100%').height('50')
180      }.backgroundColor(item)
181    })
182  }
183  ```
184
185  ![en-us_image_0000001563060689](figures/en-us_image_0000001563060689.gif)
186
187  If **columns** is only set for the sm and md screen size types, screen sizes smaller than sm use the default value **12**, and screen sizes larger than md (lg, xl, and xxl) use the value of **columns** of the md type.
188
189
190### Alignment
191
192In the responsive grid layout, you can set the **direction** attribute of **\<GridRow>** to define the direction in which child components are arranged. The options are **GridRowDirection.Row** (from left to right) or **GridRowDirection.RowReverse** (from right to left). An appropriate **direction** value can make the page layout more flexible and meet the design requirements.
193
194- When child components are arranged from left to right (default):
195
196
197  ```ts
198  GridRow({ direction: GridRowDirection.Row }){}
199  ```
200
201  ![en-us_image_0000001511740488](figures/en-us_image_0000001511740488.png)
202
203- When child components are arranged from right to left (default):
204
205
206  ```ts
207  GridRow({ direction: GridRowDirection.RowReverse }){}
208  ```
209
210  ![en-us_image_0000001562940517](figures/en-us_image_0000001562940517.png)
211
212
213### Gutters
214
215In the **\<GridRow>** component, **gutter** is used to set the spacing between adjacent child components in the horizontal and vertical directions.
216
217- When **gutter** is set to a number, the number applies to both the horizontal and vertical directions. In the following example, the horizontal and vertical spacing between adjacent child components is set to **10**.
218
219
220  ```ts
221   GridRow({ gutter: 10 }){}
222  ```
223
224  ![en-us_image_0000001511740476](figures/en-us_image_0000001511740476.png)
225
226- When **gutter** is set to a value of the **GutterOption** type, the **x** attribute of the value indicates the horizontal gutter, and the **y** attribute indicates the vertical gutter.
227
228
229  ```ts
230  GridRow({ gutter: { x: 20, y: 50 } }){}
231  ```
232
233  ![en-us_image_0000001511900456](figures/en-us_image_0000001511900456.png)
234
235
236## GridCol
237
238The **\<GridCol>** component is a child component of the **\<GridRow>** component. You can set the **span**, **offset**, and **order** attributes of this component by passing parameters or using setters.
239
240- Setting **span**
241
242
243  ```ts
244  GridCol({ span: 2 }){}
245  GridCol({ span: { xs: 1, sm: 2, md: 3, lg: 4 } }){}
246  GridCol(){}.span(2)
247  GridCol(){}.span({ xs: 1, sm: 2, md: 3, lg: 4 })
248  ```
249
250- Setting **offset**
251
252
253  ```ts
254  GridCol({ offset: 2 }){}
255  GridCol({ offset: { xs: 2, sm: 2, md: 2, lg: 2 } }){}
256  GridCol(){}.offset(2)
257  GridCol(){}.offset({ xs: 1, sm: 2, md: 3, lg: 4 })
258  ```
259
260- Setting **order**
261
262
263  ```ts
264  GridCol({ order: 2 }){}
265  GridCol({ order: { xs: 1, sm: 2, md: 3, lg: 4 } }){}
266  GridCol(){}.order(2)
267  GridCol(){}.order({ xs: 1, sm: 2, md: 3, lg: 4 })
268  ```
269
270
271### span
272
273Sets the number of columns occupied by a child component in the grid layout, which determines the child component width. The default value is **1**.
274
275- When the value type is number, the number of columns occupied by the child component is the same across screen sizes.
276
277
278  ```ts
279  @State bgColors: Color[] = [Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Pink, Color.Grey, Color.Blue, Color.Brown];
280  ...
281  GridRow({ columns: 8 }) {
282    ForEach(this.bgColors, (color, index) => {
283      GridCol({ span: 2 }) {
284        Row() {
285          Text(`${index}`)
286        }.width('100%').height('50vp')
287      }
288      .backgroundColor(color)
289    })
290  }
291  ```
292
293  ![en-us_image_0000001511421264](figures/en-us_image_0000001511421264.png)
294
295- When the value type is **GridColColumnOption**, you can assign values specific to the screen size (xs, sm, md, lg, xl, xxl).
296
297
298  ```ts
299  @State bgColors: Color[] = [Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Pink, Color.Grey, Color.Blue, Color.Brown];
300  ...
301  GridRow({ columns: 8 }) {
302    ForEach(this.bgColors, (color, index) => {
303      GridCol({ span: { xs: 1, sm: 2, md: 3, lg: 4 } }) {
304        Row() {
305          Text(`${index}`)
306        }.width('100%').height('50vp')
307      }
308      .backgroundColor(color)
309    })
310  }
311  ```
312
313  ![en-us_image_0000001511740492](figures/en-us_image_0000001511740492.gif)
314
315
316### offset
317
318Sets the column offset of a child component relative to the previous child component. The default value is **0**.
319
320- When the value type is number, the column offset of the child component is the same across screen sizes.
321
322
323  ```ts
324  @State bgColors: Color[] = [Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Pink, Color.Grey, Color.Blue, Color.Brown];
325  ...
326  GridRow() {
327    ForEach(this.bgColors, (color, index) => {
328      GridCol({ offset: 2 }) {
329        Row() {
330          Text('' + index)
331        }.width('100%').height('50vp')
332      }
333      .backgroundColor(color)
334    })
335  }
336  ```
337
338  ![en-us_image_0000001563060705](figures/en-us_image_0000001563060705.png)
339
340  By default, a grid is divided into 12 columns and each child component occupies one column with an offset of two columns. Each row holds four child components, with three columns per child component plus the gutter.
341
342- When the value type is **GridColColumnOption**, you can assign values specific to the screen size (xs, sm, md, lg, xl, xxl).
343
344
345  ```ts
346  @State bgColors: Color[] = [Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Pink, Color.Grey, Color.Blue, Color.Brown];
347  ...
348
349  GridRow() {
350    ForEach(this.bgColors, (color, index) => {
351      GridCol({ offset: { xs: 1, sm: 2, md: 3, lg: 4 } }) {
352        Row() {
353          Text('' + index)
354        }.width('100%').height('50vp')
355      }
356      .backgroundColor(color)
357    })
358  }
359  ```
360
361  ![en-us_image_0000001562700433](figures/en-us_image_0000001562700433.gif)
362
363
364### order
365
366Sets the sequence number of a child component in the grid layout. If a child component shares an **order** value with another child component or does not have **order** set, it is displayed based on its code sequence number. A child component with a smaller **order** value is placed before the one with a larger **order** value.
367
368If **order** is not set for all child components, those that have **order** set are displayed after those that do not have **order** set and are sorted in ascending order based on the value.
369
370- When the value type is number, child components are sorted in the same order across screen sizes.
371
372
373  ```ts
374  GridRow() {
375    GridCol({ order: 4 }) {
376      Row() {
377        Text('1')
378      }.width('100%').height('50vp')
379    }.backgroundColor(Color.Red)
380    GridCol({ order: 3 }) {
381      Row() {
382        Text('2')
383      }.width('100%').height('50vp')
384    }.backgroundColor(Color.Orange)
385    GridCol({ order: 2 }) {
386      Row() {
387        Text('3')
388      }.width('100%').height('50vp')
389    }.backgroundColor(Color.Yellow)
390    GridCol({ order: 1 }) {
391      Row() {
392        Text('4')
393      }.width('100%').height('50vp')
394    }.backgroundColor(Color.Green)
395  }
396  ```
397
398  ![en-us_image_0000001511580892](figures/en-us_image_0000001511580892.png)
399
400- When the value type is **GridColColumnOption**, you can assign values specific to the screen size (xs, sm, md, lg, xl, xxl). You can set 1234 for xs, 2341 for sm, 3412 for md, and 2431 for lg.
401
402
403  ```ts
404  GridRow() {
405    GridCol({ order: { xs:1, sm:5, md:3, lg:7}}) {
406      Row() {
407        Text('1')
408      }.width('100%').height('50vp')
409    }.backgroundColor(Color.Red)
410    GridCol({ order: { xs:2, sm:2, md:6, lg:1} }) {
411      Row() {
412        Text('2')
413      }.width('100%').height('50vp')
414    }.backgroundColor(Color.Orange)
415    GridCol({ order: { xs:3, sm:3, md:1, lg:6} }) {
416      Row() {
417        Text('3')
418      }.width('100%').height('50vp')
419    }.backgroundColor(Color.Yellow)
420    GridCol({ order: { xs:4, sm:4, md:2, lg:5} }) {
421      Row() {
422        Text('4')
423      }.width('100%').height('50vp')
424    }.backgroundColor(Color.Green)
425  }
426  ```
427
428  ![en-us_image_0000001511900444](figures/en-us_image_0000001511900444.gif)
429
430
431## Nesting of Responsive Grid Components
432
433Responsive grid components can be contained in other responsive grid components.
434
435In the following example, the responsive grid divides the entire space into 12 parts. **\<GridCol>** is nested in **\<GridRow>** at the first layer, which is divided into the large area in the center and the footer area. **\<GridCol>** is nested in **\<GridRow>** at the second layer, which is divided into the left and right areas. The child component space is divided based on the space allocation of the parent component at the upper layer. For example, the pink area is made up of 12 columns of the screen space, and the green and blue areas are made up of 12 columns of the **\<GridRow>** parent component.
436
437
438
439```ts
440@Entry
441@Component
442struct GridRowExample {
443  build() {
444    GridRow() {
445      GridCol({ span: { sm: 12 } }) {
446        GridRow() {
447          GridCol({ span: { sm: 2 } }) {
448            Row() {
449              Text('left').fontSize(24)
450            }
451            .justifyContent(FlexAlign.Center)
452            .height('90%')
453          }.backgroundColor('#ff41dbaa')
454
455          GridCol({ span: { sm: 10 } }) {
456            Row() {
457              Text('right').fontSize(24)
458            }
459            .justifyContent(FlexAlign.Center)
460            .height('90%')
461          }.backgroundColor('#ff4168db')
462        }
463        .backgroundColor('#19000000')
464        .height('100%')
465      }
466
467      GridCol({ span: { sm: 12 } }) {
468        Row() {
469          Text('footer').width('100%').textAlign(TextAlign.Center)
470        }.width('100%').height('10%').backgroundColor(Color.Pink)
471      }
472    }.width('100%').height(300)
473  }
474}
475```
476
477
478![en-us_image_0000001563060697](figures/en-us_image_0000001563060697.png)
479
480
481To sum up, the responsive grid components are powerful tools with a wide range of customization capabilities. With the required attributes set at different breakpoints, such as **Columns**, **Margin**, **Gutter**, and **span**, the layout is created automatically. You do not need to pay attention to the specific device type and device state (such as landscape and portrait).
482