• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 相对布局 (RelativeContainer)
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @fenglinbailu-->
5<!--Designer: @lanshouren-->
6<!--Tester: @liuli0427-->
7<!--Adviser: @HelloCrease-->
8
9
10## 概述
11
12在应用的开发过程中,经常需要设计复杂界面,此时涉及到多个相同或不同组件之间的嵌套。如果布局组件嵌套深度过深,或者嵌套组件数过多,会带来额外的开销。如果在布局的方式上进行优化,就可以有效的提升性能,减少时间开销。<!--Del-->请参考[优化布局时间](../performance/reduce-view-nesting-levels.md#优化布局时间)了解RelativeContainer相对于List,在布局时间上的性能提升。<!--DelEnd-->
13
14RelativeContainer是一种采用相对布局的容器,支持容器内部的子元素设置相对位置关系,适用于处理界面复杂的场景,对多个子元素进行对齐和排列。子元素可以指定兄弟元素或父容器作为锚点,基于锚点进行相对位置布局。在使用锚点时,需注意子元素的相对位置关系,以避免出现错位或遮挡的情况。下图展示了一个 RelativeContainer的概念图,图中的虚线表示位置的依赖关系。
15
16
17  **图1** 相对布局示意图  
18
19![relative-layout](figures/relative-layout.png)
20
21
22子元素并不完全是上图中的依赖关系。比如,Item4可以以Item2为依赖锚点,也可以以RelativeContainer父容器为依赖锚点。
23
24
25## 基本概念
26
27- 参考边界:设置当前组件的哪个边界对齐到锚点。
28
29- 锚点:通过锚点设置当前元素基于哪个元素确定位置。
30
31- 对齐方式:通过对齐方式,设置当前元素是基于锚点的上中下对齐,还是基于锚点的左中右对齐。
32
33
34## 设置依赖关系
35
36### 设置参考边界
37
38设置当前组件的哪个边界对齐到锚点。容器内子组件的参考边界区分水平方向和垂直方向。
39* 在水平方向上,可以按照起始(left)、居中(middle)或尾端(right)的组件边界与锚点对齐。当设置三个边界时,仅起始(left)和居中(middle)的边界设置生效。
40![relative-layout-alignrules01](figures/relative-layout-alignrules01.png)
41* 在垂直方向上,可以设置组件边界与锚点对齐,具体包括顶部(top)、居中(center)和底部(bottom)。当设置三个边界时,仅顶部(top)和居中(center)生效。
42![relative-layout-alignrules02](figures/relative-layout-alignrules02.png)
43
44### 设置锚点
45
46锚点设置涉及子元素相对于其父元素或兄弟元素的位置依赖关系。具体而言,子元素可以将其位置锚定到相对布局容器(RelativeContainer)、辅助线(guideline)、屏障(barrier)或其他子元素上。
47
48为了准确定义锚点,RelativeContainer的子元素必须拥有唯一的组件标识(id),用于指定锚点信息。父元素RelativeContainer的标识默认为“\_\_container\_\_”,其他子元素的组件标识(id)则通过[id](../reference/apis-arkui/arkui-ts/ts-universal-attributes-component-id.md#id)属性设置。
49
50> **说明:**
51>
52> * 未设置组件标识(id)的组件虽可显示,但无法被其他组件引用为锚点。相对布局容器会为其拼接组件标识,但组件标识(id)的规律无法被应用感知。辅助线(guideline)与屏障(barrier)的组件标识(id)需确保唯一,避免与任何组件冲突。若有重复,遵循组件 > guideline > barrier 的优先级。
53> * 组件间设置锚点时应避免形成依赖循环(组件之间设置链除外),依赖循环将导致子组件缺乏定位基准,最终无法绘制。
54
55- RelativeContainer父组件为锚点,__container__代表父容器的组件标识(id)。
56
57  ```ts
58  let AlignRus: Record<string, Record<string, string | VerticalAlign | HorizontalAlign>> = {
59    'top': { 'anchor': '__container__', 'align': VerticalAlign.Top },
60    'left': { 'anchor': '__container__', 'align': HorizontalAlign.Start }
61  }
62  let AlignRue: Record<string, Record<string, string | VerticalAlign | HorizontalAlign>> = {
63    'top': { 'anchor': '__container__', 'align': VerticalAlign.Top },
64    'right': { 'anchor': '__container__', 'align': HorizontalAlign.End }
65  }
66  let Mleft: Record<string, number> = { 'left': 20 }
67  let BWC: Record<string, number | string> = { 'width': 2, 'color': '#6699FF' }
68
69  @Entry
70  @Component
71  struct Index {
72    build() {
73      RelativeContainer() {
74        Row() {
75          Text('row1')
76        }
77        .justifyContent(FlexAlign.Center)
78        .width(100)
79        .height(100)
80        .backgroundColor('#a3cf62')
81        .alignRules(AlignRus)
82        .id("row1")
83
84        Row() {
85          Text('row2')
86        }
87        .justifyContent(FlexAlign.Center)
88        .width(100)
89        .height(100)
90        .backgroundColor('#00ae9d')
91        .alignRules(AlignRue)
92        .id("row2")
93      }.width(300).height(300)
94      .margin(Mleft)
95      .border(BWC)
96    }
97  }
98  ```
99
100  ![zh-cn_image_0000001562820901](figures/zh-cn_image_0000001562820901.png)
101
102- 以兄弟元素为锚点。
103
104  ```ts
105  let AlignRus: Record<string, Record<string, string | VerticalAlign | HorizontalAlign>> = {
106    'top': { 'anchor': '__container__', 'align': VerticalAlign.Top },
107    'left': { 'anchor': '__container__', 'align': HorizontalAlign.Start }
108  }
109  let RelConB: Record<string, Record<string, string | VerticalAlign | HorizontalAlign>> = {
110    'top': { 'anchor': 'row1', 'align': VerticalAlign.Bottom },
111    'left': { 'anchor': 'row1', 'align': HorizontalAlign.Start }
112  }
113  let Mleft: Record<string, number> = { 'left': 20 }
114  let BWC: Record<string, number | string> = { 'width': 2, 'color': '#6699FF' }
115
116  @Entry
117  @Component
118  struct Index {
119    build() {
120      RelativeContainer() {
121        Row() {
122          Text('row1')
123        }
124        .justifyContent(FlexAlign.Center)
125        .width(100)
126        .height(100)
127        .backgroundColor('#00ae9d')
128        .alignRules(AlignRus)
129        .id("row1")
130
131        Row() {
132          Text('row2')
133        }
134        .justifyContent(FlexAlign.Center)
135        .width(100)
136        .height(100)
137        .backgroundColor('#a3cf62')
138        .alignRules(RelConB)
139        .id("row2")
140      }.width(300).height(300)
141      .margin(Mleft)
142      .border(BWC)
143    }
144  }
145  ```
146
147  ![zh-cn_image_0000001562940613](figures/zh-cn_image_0000001562940613.png)
148
149- 子组件锚点可以任意选择,但需注意不要相互依赖。
150
151  ```ts
152  @Entry
153  @Component
154  struct Index {
155    build() {
156      Row() {
157        RelativeContainer() {
158          Row(){Text('row1')}.justifyContent(FlexAlign.Center).width(100).height(100)
159          .backgroundColor('#a3cf62')
160          .alignRules({
161            top: {anchor: "__container__", align: VerticalAlign.Top},
162            left: {anchor: "__container__", align: HorizontalAlign.Start}
163          })
164          .id("row1")
165
166          Row(){Text('row2')}.justifyContent(FlexAlign.Center).width(100)
167          .backgroundColor('#00ae9d')
168          .alignRules({
169            top: {anchor: "__container__", align: VerticalAlign.Top},
170            right: {anchor: "__container__", align: HorizontalAlign.End},
171            bottom: {anchor: "row1", align: VerticalAlign.Center},
172          })
173          .id("row2")
174
175          Row(){Text('row3')}.justifyContent(FlexAlign.Center).height(100)
176          .backgroundColor('#0a59f7')
177          .alignRules({
178            top: {anchor: "row1", align: VerticalAlign.Bottom},
179            left: {anchor: "row1", align: HorizontalAlign.Start},
180            right: {anchor: "row2", align: HorizontalAlign.Start}
181          })
182          .id("row3")
183
184          Row(){Text('row4')}.justifyContent(FlexAlign.Center)
185          .backgroundColor('#2ca9e0')
186          .alignRules({
187            top: {anchor: "row3", align: VerticalAlign.Bottom},
188            left: {anchor: "row1", align: HorizontalAlign.Center},
189            right: {anchor: "row2", align: HorizontalAlign.End},
190            bottom: {anchor: "__container__", align: VerticalAlign.Bottom}
191          })
192          .id("row4")
193        }
194        .width(300).height(300)
195        .margin({left: 50})
196        .border({width:2, color: "#6699FF"})
197      }
198      .height('100%')
199    }
200  }
201  ```
202  ![Simplify-Component-Layout](figures/arkts-simplify-component-layout-image1.png)
203
204### 设置相对于锚点的对齐位置
205
206设置了锚点之后,可以通过[alignRules](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#alignrules9)属性的align设置相对于锚点的对齐位置。
207
208在水平方向上,对齐位置可以设置为HorizontalAlign.StartHorizontalAlign.CenterHorizontalAlign.End209
210![alignment-relative-anchor-horizontal](figures/alignment-relative-anchor-horizontal.png)
211
212在垂直方向上,对齐位置可以设置为VerticalAlign.TopVerticalAlign.CenterVerticalAlign.Bottom213
214![alignment-relative-anchor-vertical](figures/alignment-relative-anchor-vertical.png)
215
216### 子组件位置偏移
217
218子组件经过相对位置对齐后,可能尚未达到目标位置。开发者可根据需要设置额外偏移(offset)。当使用offset调整位置的组件作为锚点时,对齐位置为设置offset之前的位置。从API Version 11开始,新增了[Bias](../reference/apis-arkui/arkui-ts/ts-types.md#bias对象说明)对象,建议API Version 11及以后的版本使用bias来设置额外偏移。使用bias的示例可以参考[示例4(设置偏移)](../reference/apis-arkui/arkui-ts/ts-container-relativecontainer.md#示例4设置偏移)。
219
220  ```ts
221@Entry
222@Component
223struct Index {
224  build() {
225    Row() {
226      RelativeContainer() {
227        Row() {
228          Text('row1')
229        }
230        .justifyContent(FlexAlign.Center)
231        .width(100)
232        .height(100)
233        .backgroundColor('#a3cf62')
234        .alignRules({
235          top: { anchor: "__container__", align: VerticalAlign.Top },
236          left: { anchor: "__container__", align: HorizontalAlign.Start }
237        })
238        .id("row1")
239
240        Row() {
241          Text('row2')
242        }
243        .justifyContent(FlexAlign.Center)
244        .width(100)
245        .backgroundColor('#00ae9d')
246        .alignRules({
247          top: { anchor: "__container__", align: VerticalAlign.Top },
248          right: { anchor: "__container__", align: HorizontalAlign.End },
249          bottom: { anchor: "row1", align: VerticalAlign.Center },
250        })
251        .offset({
252          x: -40,
253          y: -20
254        })
255        .id("row2")
256
257        Row() {
258          Text('row3')
259        }
260        .justifyContent(FlexAlign.Center)
261        .height(100)
262        .backgroundColor('#0a59f7')
263        .alignRules({
264          top: { anchor: "row1", align: VerticalAlign.Bottom },
265          left: { anchor: "row1", align: HorizontalAlign.End },
266          right: { anchor: "row2", align: HorizontalAlign.Start }
267        })
268        .offset({
269          x: -10,
270          y: -20
271        })
272        .id("row3")
273
274        Row() {
275          Text('row4')
276        }
277        .justifyContent(FlexAlign.Center)
278        .backgroundColor('#2ca9e0')
279        .alignRules({
280          top: { anchor: "row3", align: VerticalAlign.Bottom },
281          bottom: { anchor: "__container__", align: VerticalAlign.Bottom },
282          left: { anchor: "__container__", align: HorizontalAlign.Start },
283          right: { anchor: "row1", align: HorizontalAlign.End }
284        })
285        .offset({
286          x: -10,
287          y: -30
288        })
289        .id("row4")
290
291        Row() {
292          Text('row5')
293        }
294        .justifyContent(FlexAlign.Center)
295        .backgroundColor('#30c9f7')
296        .alignRules({
297          top: { anchor: "row3", align: VerticalAlign.Bottom },
298          bottom: { anchor: "__container__", align: VerticalAlign.Bottom },
299          left: { anchor: "row2", align: HorizontalAlign.Start },
300          right: { anchor: "row2", align: HorizontalAlign.End }
301        })
302        .offset({
303          x: 10,
304          y: 20
305        })
306        .id("row5")
307
308        Row() {
309          Text('row6')
310        }
311        .justifyContent(FlexAlign.Center)
312        .backgroundColor('#ff33ffb5')
313        .alignRules({
314          top: { anchor: "row3", align: VerticalAlign.Bottom },
315          bottom: { anchor: "row4", align: VerticalAlign.Bottom },
316          left: { anchor: "row3", align: HorizontalAlign.Start },
317          right: { anchor: "row3", align: HorizontalAlign.End }
318        })
319        .offset({
320          x: -15,
321          y: 10
322        })
323        .backgroundImagePosition(Alignment.Bottom)
324        .backgroundImageSize(ImageSize.Cover)
325        .id("row6")
326      }
327      .width(300).height(300)
328      .margin({ left: 50 })
329      .border({ width: 2, color: "#6699FF" })
330    }
331    .height('100%')
332  }
333}
334  ```
335  ![Simplify-Component-Layout](figures/arkts-simplify-component-layout-image2.png)
336
337## 多种组件的对齐布局
338
339Row、Column、Flex、Stack等多种布局组件,可按照RelativeContainer组件规则进行对齐排布。
340
341  ```ts
342@Entry
343@Component
344struct Index {
345  @State value: number = 0
346
347  build() {
348    Row() {
349
350      RelativeContainer() {
351        Row()
352          .width(100)
353          .height(100)
354          .backgroundColor('#a3cf62')
355          .alignRules({
356            top: { anchor: "__container__", align: VerticalAlign.Top },
357            left: { anchor: "__container__", align: HorizontalAlign.Start }
358          })
359          .id("row1")
360
361        Column()
362          .width('50%')
363          .height(30)
364          .backgroundColor('#00ae9d')
365          .alignRules({
366            top: { anchor: "__container__", align: VerticalAlign.Top },
367            left: { anchor: "__container__", align: HorizontalAlign.Center }
368          })
369          .id("row2")
370
371        Flex({ direction: FlexDirection.Row }) {
372          Text('1').width('20%').height(50).backgroundColor('#0a59f7')
373          Text('2').width('20%').height(50).backgroundColor('#2ca9e0')
374          Text('3').width('20%').height(50).backgroundColor('#0a59f7')
375          Text('4').width('20%').height(50).backgroundColor('#2ca9e0')
376        }
377        .padding(10)
378        .backgroundColor('#30c9f7')
379        .alignRules({
380          top: { anchor: "row2", align: VerticalAlign.Bottom },
381          left: { anchor: "__container__", align: HorizontalAlign.Start },
382          bottom: { anchor: "__container__", align: VerticalAlign.Center },
383          right: { anchor: "row2", align: HorizontalAlign.Center }
384        })
385        .id("row3")
386
387        Stack({ alignContent: Alignment.Bottom }) {
388          Text('First child, show in bottom').width('90%').height('100%').backgroundColor('#a3cf62').align(Alignment.Top)
389          Text('Second child, show in top').width('70%').height('60%').backgroundColor('#00ae9d').align(Alignment.Top)
390        }
391        .margin({ top: 5 })
392        .alignRules({
393          top: { anchor: "row3", align: VerticalAlign.Bottom },
394          left: { anchor: "__container__", align: HorizontalAlign.Start },
395          bottom: { anchor: "__container__", align: VerticalAlign.Bottom },
396          right: { anchor: "row3", align: HorizontalAlign.End }
397        })
398        .id("row4")
399
400      }
401      .width(300).height(300)
402      .margin({ left: 50 })
403      .border({ width: 2, color: "#6699FF" })
404    }
405    .height('100%')
406  }
407}
408  ```
409  ![Simplify-Component-Layout](figures/arkts-simplify-component-layout-image3.png)
410
411## 组件尺寸
412
413当同时存在前端页面设置的子组件尺寸和相对布局规则时,子组件的绘制尺寸依据约束规则确定。从API Version 11开始,此规则有所变化,子组件自身设置的尺寸优先级高于相对布局规则中的对齐锚点尺寸。因此,若要使子组件与锚点严格对齐,应仅使用alignRules,避免使用[尺寸设置](../reference/apis-arkui/arkui-ts/ts-universal-attributes-size.md)。
414
415> **说明:**
416>
417> * 根据约束条件和子组件自身的size属性无法确定子组件的大小,此时,不绘制该子组件。
418> * 在同一方向上设置两个或更多锚点时,若这些锚点的位置顺序有误,该子组件将被视为大小为0而不予绘制。
419```ts
420@Entry
421@Component
422struct Index {
423  build() {
424    Row() {
425      RelativeContainer() {
426        Row() {
427          Text('row1')
428        }
429        .justifyContent(FlexAlign.Center)
430        .width(100)
431        .height(100)
432        .backgroundColor('#a3cf62')
433        .alignRules({
434          top: { anchor: "__container__", align: VerticalAlign.Top },
435          left: { anchor: "__container__", align: HorizontalAlign.Start }
436        })
437        .id("row1")
438
439        Row() {
440          Text('row2')
441        }
442        .justifyContent(FlexAlign.Center)
443        .width(100)
444        .backgroundColor('#00ae9d')
445        .alignRules({
446          top: { anchor: "__container__", align: VerticalAlign.Top },
447          right: { anchor: "__container__", align: HorizontalAlign.End },
448          bottom: { anchor: "row1", align: VerticalAlign.Center },
449        })
450        .id("row2")
451
452        Row() {
453          Text('row3')
454        }
455        .justifyContent(FlexAlign.Center)
456        .height(100)
457        .backgroundColor('#0a59f7')
458        .alignRules({
459          top: { anchor: "row1", align: VerticalAlign.Bottom },
460          left: { anchor: "row1", align: HorizontalAlign.End },
461          right: { anchor: "row2", align: HorizontalAlign.Start }
462        })
463        .id("row3")
464
465        Row() {
466          Text('row4')
467        }.justifyContent(FlexAlign.Center)
468        .backgroundColor('#2ca9e0')
469        .alignRules({
470          top: { anchor: "row3", align: VerticalAlign.Bottom },
471          bottom: { anchor: "__container__", align: VerticalAlign.Bottom },
472          left: { anchor: "__container__", align: HorizontalAlign.Start },
473          right: { anchor: "row1", align: HorizontalAlign.End }
474        })
475        .id("row4")
476
477        Row() {
478          Text('row5')
479        }.justifyContent(FlexAlign.Center)
480        .backgroundColor('#30c9f7')
481        .alignRules({
482          top: { anchor: "row3", align: VerticalAlign.Bottom },
483          bottom: { anchor: "__container__", align: VerticalAlign.Bottom },
484          left: { anchor: "row2", align: HorizontalAlign.Start },
485          right: { anchor: "row2", align: HorizontalAlign.End }
486        })
487        .id("row5")
488
489        Row() {
490          Text('row6')
491        }
492        .justifyContent(FlexAlign.Center)
493        .backgroundColor('#ff33ffb5')
494        .alignRules({
495          top: { anchor: "row3", align: VerticalAlign.Bottom },
496          bottom: { anchor: "row4", align: VerticalAlign.Bottom },
497          left: { anchor: "row3", align: HorizontalAlign.Start },
498          right: { anchor: "row3", align: HorizontalAlign.End }
499        })
500        .id("row6")
501        .backgroundImagePosition(Alignment.Bottom)
502        .backgroundImageSize(ImageSize.Cover)
503      }
504      .width(300).height(300)
505      .margin({ left: 50 })
506      .border({ width: 2, color: "#6699FF" })
507    }
508    .height('100%')
509  }
510}
511```
512  ![Simplify-Component-Layout](figures/arkts-simplify-component-layout-image4.png)
513
514
515## 多个组件形成链
516
517链的形成依赖于组件之间的关联关系。以组件A和组件B构成的最简水平链为例,其依赖关系为:锚点1 <-- 组件A <---> 组件B --> 锚点2,即A具有left锚点,B具有right锚点,同时A的right锚点与B的HorizontalAlign.Start对齐,B的left锚点与A的HorizontalAlign.End对齐。
518* 链的方向和格式在链头组件的[chainMode](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#chainmode12)接口中声明;链内元素的bias属性全部失效,链头元素的bias属性作为整个链的bias生效。链头是指在满足成链规则时链的第一个组件(在水平方向上,从左边开始,镜像语言中从右边开始;在垂直方向上,从上边开始)。
519* 如果链内所有元素的size超出链的锚点约束,超出部分将被均匀分配到链的两侧。在[PACKED](../reference/apis-arkui/arkui-ts/ts-universal-attributes-location.md#chainstyle12)链中,可以通过[Bias](../reference/apis-arkui/arkui-ts/ts-types.md#bias对象说明)设置超出部分的分布。
520
521
522```ts
523@Entry
524@Component
525struct Index {
526  build() {
527    Row() {
528      RelativeContainer() {
529        Row() {
530          Text('row1')
531        }
532        .justifyContent(FlexAlign.Center)
533        .width(80)
534        .height(80)
535        .backgroundColor('#a3cf62')
536        .alignRules({
537          left: { anchor: "__container__", align: HorizontalAlign.Start },
538          right: { anchor: "row2", align: HorizontalAlign.Start },
539          top: { anchor: "__container__", align: VerticalAlign.Top }
540        })
541        .id("row1")
542        .chainMode(Axis.Horizontal, ChainStyle.SPREAD)
543
544        Row() {
545          Text('row2')
546        }
547        .justifyContent(FlexAlign.Center)
548        .width(80)
549        .height(80)
550        .backgroundColor('#00ae9d')
551        .alignRules({
552          left: { anchor: "row1", align: HorizontalAlign.End },
553          right: { anchor: "row3", align: HorizontalAlign.Start },
554          top: { anchor: "row1", align: VerticalAlign.Top }
555        })
556        .id("row2")
557
558        Row() {
559          Text('row3')
560        }
561        .justifyContent(FlexAlign.Center)
562        .width(80)
563        .height(80)
564        .backgroundColor('#0a59f7')
565        .alignRules({
566          left: { anchor: "row2", align: HorizontalAlign.End },
567          right: { anchor: "__container__", align: HorizontalAlign.End },
568          top: { anchor: "row1", align: VerticalAlign.Top }
569        })
570        .id("row3")
571
572        Row() {
573          Text('row4')
574        }
575        .justifyContent(FlexAlign.Center)
576        .width(80)
577        .height(80)
578        .backgroundColor('#a3cf62')
579        .alignRules({
580          left: { anchor: "__container__", align: HorizontalAlign.Start },
581          right: { anchor: "row5", align: HorizontalAlign.Start },
582          center: { anchor: "__container__", align: VerticalAlign.Center }
583        })
584        .id("row4")
585        .chainMode(Axis.Horizontal, ChainStyle.SPREAD_INSIDE)
586
587        Row() {
588          Text('row5')
589        }
590        .justifyContent(FlexAlign.Center)
591        .width(80)
592        .height(80)
593        .backgroundColor('#00ae9d')
594        .alignRules({
595          left: { anchor: "row4", align: HorizontalAlign.End },
596          right: { anchor: "row6", align: HorizontalAlign.Start },
597          top: { anchor: "row4", align: VerticalAlign.Top }
598        })
599        .id("row5")
600
601        Row() {
602          Text('row6')
603        }
604        .justifyContent(FlexAlign.Center)
605        .width(80)
606        .height(80)
607        .backgroundColor('#0a59f7')
608        .alignRules({
609          left: { anchor: "row5", align: HorizontalAlign.End },
610          right: { anchor: "__container__", align: HorizontalAlign.End },
611          top: { anchor: "row4", align: VerticalAlign.Top }
612        })
613        .id("row6")
614
615        Row() {
616          Text('row7')
617        }
618        .justifyContent(FlexAlign.Center)
619        .width(80)
620        .height(80)
621        .backgroundColor('#a3cf62')
622        .alignRules({
623          left: { anchor: "__container__", align: HorizontalAlign.Start },
624          right: { anchor: "row8", align: HorizontalAlign.Start },
625          bottom: { anchor: "__container__", align: VerticalAlign.Bottom }
626        })
627        .id("row7")
628        .chainMode(Axis.Horizontal, ChainStyle.PACKED)
629
630        Row() {
631          Text('row8')
632        }
633        .justifyContent(FlexAlign.Center)
634        .width(80)
635        .height(80)
636        .backgroundColor('#00ae9d')
637        .alignRules({
638          left: { anchor: "row7", align: HorizontalAlign.End },
639          right: { anchor: "row9", align: HorizontalAlign.Start },
640          top: { anchor: "row7", align: VerticalAlign.Top }
641        })
642        .id("row8")
643
644        Row() {
645          Text('row9')
646        }
647        .justifyContent(FlexAlign.Center)
648        .width(80)
649        .height(80)
650        .backgroundColor('#0a59f7')
651        .alignRules({
652          left: { anchor: "row8", align: HorizontalAlign.End },
653          right: { anchor: "__container__", align: HorizontalAlign.End },
654          top: { anchor: "row7", align: VerticalAlign.Top }
655        })
656        .id("row9")
657      }
658      .width(300).height(300)
659      .margin({ left: 50 })
660      .border({ width: 2, color: "#6699FF" })
661    }
662    .height('100%')
663  }
664}
665```
666![relative container](figures/relativecontainer6.png)