1# Relative Layout (RelativeContainer)
2
3
4## Overview
5
6During application development, nesting components – same or different – is common in page layout, especially when the target page is complicated. Yet, nesting components too deeply, or nesting too many components, can be especially expensive. Naturally, optimizing the layout hierarchies can effectively lead to better performance and less time overhead. <!--Del-->For details about how the relative container is more performance-efficient than the list, see [Improving Layout Performance](../performance/reduce-view-nesting-levels.md).<!--DelEnd-->
7
8The relative layout, implemented using the **RelativeContainer** container component, is used to lay out child elements in relative positions. It is applicable to element alignment in complex scenarios. A child element can use the container or another child element as the anchor, based on which its relative position is determined. Below shows a relative layout. The dotted lines in the figure indicate the position dependency.
9
10
11  **Figure 1** Relative layout 
12
13![relative-layout](figures/relative-layout.png)
14
15
16A child element does not necessarily adopt the dependency shown above to determine its relative position. For example, Item4 may use Item2 or the **RelativeContainer** parent container as a dependency anchor.
17
18
19## Basic Concepts
20
21- Anchor: element relative to which an element's position is specified.
22
23- Alignment mode: how the current element is aligned with the anchor, which can be top-, center-, or bottom-aligned in the vertical direction or left-, center-, and right-aligned in the horizontal direction.
24
25
26## Setting the Dependency
27
28
29### Setting the Anchor
30
31By setting the anchor, you set a position dependency relationship between a child element and its parent element or sibling elements. In the horizontal direction, you can set the left, middle, and right anchors. In the vertical direction, you can set the top, center, and bottom anchors.
32To specify anchors, you must set IDs for the **RelativeContainer** component and its child elements. The default ID is **\_\_container\_\_**, and the IDs for the remaining child elements are set through the **id** attribute.  Components without **id** set can be displayed but cannot be used as anchors by other child components; the relative layout container will generate an ID for them, and the pattern of this ID is not predictable by the application logic. When a mutual or circular dependency occurs, none of the child components in the container are drawn. If anchors are set for more than two positions in a single direction but the anchor positions are reversed, the size of the child component is 0, which means that the child component is not drawn. 
33
34>**NOTE**
35>
36>When using anchors, pay attention to the relative positions of child elements to avoid misplacement or blocking.
37
38- The ID of the **RelativeContainer** parent component is **__container__**.
39
40  ```ts
41  let AlignRus:Record<string,Record<string,string|VerticalAlign|HorizontalAlign>> = {
42    'top': { 'anchor': '__container__', 'align': VerticalAlign.Top },
43    'left': { 'anchor': '__container__', 'align': HorizontalAlign.Start }
44  }
45  let AlignRue:Record<string,Record<string,string|VerticalAlign|HorizontalAlign>> = {
46    'top': { 'anchor': '__container__', 'align': VerticalAlign.Top },
47    'right': { 'anchor': '__container__', 'align': HorizontalAlign.End }
48  }
49  let Mleft:Record<string,number> = { 'left': 20 }
50  let BWC:Record<string,number|string> = { 'width': 2, 'color': '#6699FF' }
51 
52  @Entry
53  @Component
54  struct Index {
55    build() {
56      RelativeContainer() {
57        Row(){Text('row1')}.justifyContent(FlexAlign.Center).width(100).height(100)
58        .backgroundColor("#FF3333")
59        .alignRules(AlignRus)
60        .id("row1")
61
62        Row(){Text('row2')}.justifyContent(FlexAlign.Center).width(100).height(100)
63        .backgroundColor("#FFCC00")
64        .alignRules(AlignRue)
65        .id("row2")
66      }.width(300).height(300)
67      .margin(Mleft)
68      .border(BWC)
69    }
70  }
71  ```
72
73  ![en-us_image_0000001562820901](figures/en-us_image_0000001562820901.png)
74
75- Example of using a sibling element as the anchor:
76
77  ```ts
78  let AlignRus:Record<string,Record<string,string|VerticalAlign|HorizontalAlign>> = {
79    'top': { 'anchor': '__container__', 'align': VerticalAlign.Top },
80    'left': { 'anchor': '__container__', 'align': HorizontalAlign.Start }
81  }
82  let RelConB:Record<string,Record<string,string|VerticalAlign|HorizontalAlign>> = {
83    'top': { 'anchor': 'row1', 'align': VerticalAlign.Bottom },
84    'left' : { 'anchor': 'row1', 'align': HorizontalAlign.Start }
85  }
86  let Mleft:Record<string,number> = { 'left': 20 }
87  let BWC:Record<string,number|string> = { 'width': 2, 'color': '#6699FF' }
88
89  @Entry
90  @Component
91  struct Index {
92    build() {
93      RelativeContainer() {
94        Row(){Text('row1')}.justifyContent(FlexAlign.Center).width(100).height(100)
95        .backgroundColor("#FF3333")
96        .alignRules(AlignRus)
97        .id("row1")
98
99        Row(){Text('row2')}.justifyContent(FlexAlign.Center).width(100).height(100)
100        .backgroundColor("#FFCC00")
101        .alignRules(RelConB)
102        .id("row2")
103      }.width(300).height(300)
104      .margin(Mleft)
105      .border(BWC)
106    }
107  }
108  ```
109
110  ![en-us_image_0000001562940613](figures/en-us_image_0000001562940613.png)
111
112- Make sure the anchors of a child component do not depend on each other.
113
114  ```ts
115  @Entry
116  @Component
117  struct Index {
118    build() {
119      Row() {
120        RelativeContainer() {
121          Row(){Text('row1')}.justifyContent(FlexAlign.Center).width(100).height(100)
122            .backgroundColor('#ff3339ff')
123            .alignRules({
124              top: {anchor: "__container__", align: VerticalAlign.Top},
125              left: {anchor: "__container__", align: HorizontalAlign.Start}
126            })
127            .id("row1")
128
129          Row(){Text('row2')}.justifyContent(FlexAlign.Center).width(100)
130            .backgroundColor('#ff298e1e')
131            .alignRules({
132              top: {anchor: "__container__", align: VerticalAlign.Top},
133              right: {anchor: "__container__", align: HorizontalAlign.End},
134              bottom: {anchor: "row1", align: VerticalAlign.Center},
135            })
136            .id("row2")
137
138          Row(){Text('row3')}.justifyContent(FlexAlign.Center).height(100)
139            .backgroundColor('#ffff6a33')
140            .alignRules({
141              top: {anchor: "row1", align: VerticalAlign.Bottom},
142              left: {anchor: "row1", align: HorizontalAlign.Start},
143              right: {anchor: "row2", align: HorizontalAlign.Start}
144            })
145            .id("row3")
146
147          Row(){Text('row4')}.justifyContent(FlexAlign.Center)
148            .backgroundColor('#ffff33fd')
149            .alignRules({
150              top: {anchor: "row3", align: VerticalAlign.Bottom},
151              left: {anchor: "row1", align: HorizontalAlign.Center},
152              right: {anchor: "row2", align: HorizontalAlign.End},
153              bottom: {anchor: "__container__", align: VerticalAlign.Bottom}
154            })
155            .id("row4")
156        }
157        .width(300).height(300)
158        .margin({left: 50})
159        .border({width:2, color: "#6699FF"})
160      }
161      .height('100%')
162    }
163  }
164  ```
165  ![Simplify-Component-Layout](figures/arkts-simplify-component-layout-image1.png)
166
167### Setting Alignment Relative to the Anchor
168
169After an anchor is set, you can use **align** to set the alignment mode relative to the anchor.
170
171Alignment modes in the horizontal direction can be left, center, or right, achieved by the **HorizontalAlign.Start**, **HorizontalAlign.Center**, and **HorizontalAlign.End** attributes, respectively.
172
173![alignment-relative-anchor-horizontal](figures/alignment-relative-anchor-horizontal.png)
174
175Alignment modes in the vertical direction can be top, center, or bottom, achieved by the **VerticalAlign.Top**, **VerticalAlign.Center**, and **VerticalAlign.Bottom** attributes, respectively.
176
177![alignment-relative-anchor-vertical](figures/alignment-relative-anchor-vertical.png)
178
179### Setting Offset
180
181After being aligned relative to the anchor, a child component may be still not at its target position. In this case, you can set the offset.
182
183  ```ts
184  @Entry
185  @Component
186  struct Index {
187    build() {
188      Row() {
189        RelativeContainer() {
190          Row(){Text('row1')}.justifyContent(FlexAlign.Center).width(100).height(100)
191            .backgroundColor("#FF3333")
192            .alignRules({
193              top: {anchor: "__container__", align: VerticalAlign.Top},
194              left: {anchor: "__container__", align: HorizontalAlign.Start}
195            })
196            .id("row1")
197
198          Row(){Text('row2')}.justifyContent(FlexAlign.Center).width(100)
199            .backgroundColor("#FFCC00")
200            .alignRules({
201              top: {anchor: "__container__", align: VerticalAlign.Top},
202              right: {anchor: "__container__", align: HorizontalAlign.End},
203              bottom: {anchor: "row1", align: VerticalAlign.Center},
204            })
205            .offset({
206              x:-40,
207              y:-20
208            })
209            .id("row2")
210
211          Row(){Text('row3')}.justifyContent(FlexAlign.Center).height(100)
212            .backgroundColor("#FF6633")
213            .alignRules({
214              top: {anchor: "row1", align: VerticalAlign.Bottom},
215              left: {anchor: "row1", align: HorizontalAlign.End},
216              right: {anchor: "row2", align: HorizontalAlign.Start}
217            })
218            .offset({
219              x:-10,
220              y:-20
221            })
222            .id("row3")
223
224          Row(){Text('row4')}.justifyContent(FlexAlign.Center)
225            .backgroundColor("#FF9966")
226            .alignRules({
227              top: {anchor: "row3", align: VerticalAlign.Bottom},
228              bottom: {anchor: "__container__", align: VerticalAlign.Bottom},
229              left: {anchor: "__container__", align: HorizontalAlign.Start},
230              right: {anchor: "row1", align: HorizontalAlign.End}
231            })
232            .offset({
233              x:-10,
234              y:-30
235            })
236            .id("row4")
237
238          Row(){Text('row5')}.justifyContent(FlexAlign.Center)
239            .backgroundColor("#FF66FF")
240            .alignRules({
241              top: {anchor: "row3", align: VerticalAlign.Bottom},
242              bottom: {anchor: "__container__", align: VerticalAlign.Bottom},
243              left: {anchor: "row2", align: HorizontalAlign.Start},
244              right: {anchor: "row2", align: HorizontalAlign.End}
245            })
246            .offset({
247              x:10,
248              y:20
249            })
250            .id("row5")
251
252          Row(){Text('row6')}.justifyContent(FlexAlign.Center)
253            .backgroundColor('#ff33ffb5')
254            .alignRules({
255              top: {anchor: "row3", align: VerticalAlign.Bottom},
256              bottom: {anchor: "row4", align: VerticalAlign.Bottom},
257              left: {anchor: "row3", align: HorizontalAlign.Start},
258              right: {anchor: "row3", align: HorizontalAlign.End}
259            })
260            .offset({
261              x:-15,
262              y:10
263            })
264            .backgroundImagePosition(Alignment.Bottom)
265            .backgroundImageSize(ImageSize.Cover)
266            .id("row6")
267        }
268        .width(300).height(300)
269        .margin({left: 50})
270        .border({width:2, color: "#6699FF"})
271      }
272      .height('100%')
273    }
274  }
275  ```
276  ![Simplify-Component-Layout](figures/arkts-simplify-component-layout-image2.png)
277
278## Aligning Components in Multiple Layouts
279
280You can set components in multiple layout components, such as **Row**, **Column**, **Flex**, and **Stack**, to be aligned based on the relative layout rules.
281
282  ```ts
283  @Entry
284  @Component
285  struct Index {
286    @State value: number = 0
287    build() {
288      Row() {
289
290        RelativeContainer() {
291          Row().width(100).height(100)
292            .backgroundColor('#ff33ffcc')
293            .alignRules({
294              top: {anchor: "__container__", align: VerticalAlign.Top},
295              left: {anchor: "__container__", align: HorizontalAlign.Start}
296            })
297            .id("row1")
298
299          Column().width('50%').height(30).backgroundColor(0xAFEEEE)
300            .alignRules({
301              top: {anchor: "__container__", align: VerticalAlign.Top},
302              left: {anchor: "__container__", align: HorizontalAlign.Center}
303            }).id("row2")
304
305          Flex({ direction: FlexDirection.Row }) {
306            Text('1').width('20%').height(50).backgroundColor(0xF5DEB3)
307            Text('2').width('20%').height(50).backgroundColor(0xD2B48C)
308            Text('3').width('20%').height(50).backgroundColor(0xF5DEB3)
309            Text('4').width('20%').height(50).backgroundColor(0xD2B48C)
310          }
311          .padding(10)
312          .backgroundColor('#ffedafaf')
313          .alignRules({
314            top: {anchor: "row2", align: VerticalAlign.Bottom},
315            left: {anchor: "__container__", align: HorizontalAlign.Start},
316            bottom: {anchor: "__container__", align: VerticalAlign.Center},
317            right: {anchor: "row2", align: HorizontalAlign.Center}
318          })
319          .id("row3")
320
321          Stack({ alignContent: Alignment.Bottom }) {
322            Text('First child, show in bottom').width('90%').height('100%').backgroundColor(0xd2cab3).align(Alignment.Top)
323            Text('Second child, show in top').width('70%').height('60%').backgroundColor(0xc1cbac).align(Alignment.Top)
324          }
325          .margin({ top: 5 })
326          .alignRules({
327            top: {anchor: "row3", align: VerticalAlign.Bottom},
328            left: {anchor: "__container__", align: HorizontalAlign.Start},
329            bottom: {anchor: "__container__", align: VerticalAlign.Bottom},
330            right: {anchor: "row3", align: HorizontalAlign.End}
331          })
332          .id("row4")
333
334        }
335        .width(300).height(300)
336        .margin({left: 50})
337        .border({width:2, color: "#6699FF"})
338      }
339      .height('100%')
340    }
341  }
342  ```
343  ![Simplify-Component-Layout](figures/arkts-simplify-component-layout-image3.png)
344
345## Component Size
346
347The size of a child component is not affected by the relative layout rules. If two or more **alignRule** values are set for a child component in one direction, avoid setting the size in this direction. Otherwise, the component size determined by **alignRule** may conflict with the size you set.
348
349  ```ts
350  @Entry
351  @Component
352  struct Index {
353    build() {
354      Row() {
355        RelativeContainer() {
356          Row(){Text('row1')}.justifyContent(FlexAlign.Center)
357            .width(100).height(100)
358            .backgroundColor("#FF3333")
359            .alignRules({
360              top: {anchor: "__container__", align: VerticalAlign.Top},
361              left: {anchor: "__container__", align: HorizontalAlign.Start}
362            })
363            .id("row1")
364
365          Row(){Text('row2')}.justifyContent(FlexAlign.Center).width(100)
366            .backgroundColor("#FFCC00")
367            .alignRules({
368              top: {anchor: "__container__", align: VerticalAlign.Top},
369              right: {anchor: "__container__", align: HorizontalAlign.End},
370              bottom: {anchor: "row1", align: VerticalAlign.Center},
371            })
372            .id("row2")
373
374          Row(){Text('row3')}.justifyContent(FlexAlign.Center).height(100)
375            .backgroundColor("#FF6633")
376            .alignRules({
377              top: {anchor: "row1", align: VerticalAlign.Bottom},
378              left: {anchor: "row1", align: HorizontalAlign.End},
379              right: {anchor: "row2", align: HorizontalAlign.Start}
380            })
381            .id("row3")
382
383          Row(){Text('row4')}.justifyContent(FlexAlign.Center)
384            .backgroundColor("#FF9966")
385            .alignRules({
386              top: {anchor: "row3", align: VerticalAlign.Bottom},
387              bottom: {anchor: "__container__", align: VerticalAlign.Bottom},
388              left: {anchor: "__container__", align: HorizontalAlign.Start},
389              right: {anchor: "row1", align: HorizontalAlign.End}
390            })
391            .id("row4")
392
393          Row(){Text('row5')}.justifyContent(FlexAlign.Center)
394            .backgroundColor("#FF66FF")
395            .alignRules({
396              top: {anchor: "row3", align: VerticalAlign.Bottom},
397              bottom: {anchor: "__container__", align: VerticalAlign.Bottom},
398              left: {anchor: "row2", align: HorizontalAlign.Start},
399              right: {anchor: "row2", align: HorizontalAlign.End}
400            })
401            .id("row5")
402
403          Row(){Text('row6')}.justifyContent(FlexAlign.Center)
404            .backgroundColor('#ff33ffb5')
405            .alignRules({
406              top: {anchor: "row3", align: VerticalAlign.Bottom},
407              bottom: {anchor: "row4", align: VerticalAlign.Bottom},
408              left: {anchor: "row3", align: HorizontalAlign.Start},
409              right: {anchor: "row3", align: HorizontalAlign.End}
410            })
411            .id("row6")
412            .backgroundImagePosition(Alignment.Bottom)
413            .backgroundImageSize(ImageSize.Cover)
414        }
415        .width(300).height(300)
416        .margin({left: 50})
417        .border({width:2, color: "#6699FF"})
418      }
419      .height('100%')
420    }
421  }
422  ```
423  ![Simplify-Component-Layout](figures/arkts-simplify-component-layout-image4.png)
424