UI5

HBox vs VBox vs FlexBox 언제 쓸까? #shorts #SAP #UI5

▶ YouTube에서 보기

HBox, VBox, FlexBox가 생긴 이유

SAPUI5에서 화면을 구성할 때 가장 먼저 마주치는 고민은 "컨트롤을 어떻게 배치할 것인가"입니다. 초창기 UI5는 sap.ui.layout 패키지의 Grid, VerticalLayout, HorizontalLayout 등을 사용했지만, CSS Flexbox 표준이 브라우저에 정착되면서 sap.m.FlexBox와 그 파생 컨트롤인 HBox, VBox가 모바일 친화적 레이아웃 컨테이너로 자리 잡았습니다.

이 글의 목적은 세 컨트롤의 차이를 명확히 구분하고, 판매주문(Sales Order) 관리 화면을 예시로 실무에서 어떤 상황에 어떤 컨테이너를 골라야 하는지 판단 기준을 제시하는 것입니다.

핵심 개념: 세 컨트롤의 관계와 동작 원리

가장 먼저 이해해야 할 점은 HBox와 VBox가 FlexBox의 서브클래스라는 사실입니다.

sap.ui.core.Control
 └─ sap.m.FlexBox
     ├─ sap.m.HBox   // direction="Row" 고정
     └─ sap.m.VBox   // direction="Column" 고정

HBox는 direction이 Row로, VBox는 Column으로 미리 세팅된 FlexBox입니다. 내부적으로 렌더링되는 DOM은 모두 display: flex가 적용된 단일 <div>입니다.

1단계 실전 예제: HBox — 판매주문 헤더 수평 배치

<HBox alignItems="Center" justifyContent="SpaceBetween" class="sapUiSmallMargin">
    <items>
        <Title text="주문번호: {orderModel>/orderId}" level="H2"/>
        <Text text="고객: {orderModel>/customerName}"/>
        <ObjectStatus
            text="{orderModel>/statusText}"
            state="{= ${orderModel>/statusCode} === 'C' ? 'Success' : 'Warning' }"/>
    </items>
</HBox>

justifyContent="SpaceBetween"이 세 자식을 양 끝과 중앙으로 균등하게 분배하고, alignItems="Center"가 높이가 다른 컨트롤들을 수직 중앙에 맞춥니다.

2단계 실전 예제: VBox — 라인아이템 수직 스택

<VBox class="sapUiSmallMargin" items="{orderModel>/lineItems}">
    <HBox alignItems="Center" justifyContent="SpaceBetween">
        <VBox>
            <Label text="자재: {orderModel>materialCode}" design="Bold"/>
            <Text text="{orderModel>materialName}"/>
        </VBox>
        <HBox alignItems="Center">
            <ObjectNumber number="{orderModel>quantity}" unit="EA"/>
            <Button icon="sap-icon://delete" type="Transparent"
                    press=".onRemoveLine"/>
        </HBox>
    </HBox>
</VBox>

외곽 VBox는 컬렉션을, 내부 HBox는 각 행의 좌우 분할을 담당합니다.

3단계 실전 예제: FlexBox — 반응형 방향 전환

<FlexBox id="orderLayout"
         direction="{device>/layoutDirection}"
         wrap="Wrap"
         alignItems="Stretch"
         renderType="Bare">
    <items>
        <Panel headerText="고객 정보" width="{device>/panelWidth}">
            <VBox>
                <Label text="고객번호"/>
                <Text text="{orderModel>/customer/id}"/>
            </VBox>
        </Panel>
        <Panel headerText="배송지" width="{device>/panelWidth}">
            <VBox>
                <Text text="{orderModel>/shipTo/address}"/>
            </VBox>
        </Panel>
    </items>
</FlexBox>
onInit: function () {
    const oDeviceModel = new JSONModel({
        layoutDirection: sap.ui.Device.system.phone ? "Column" : "Row",
        panelWidth: sap.ui.Device.system.phone ? "100%" : "50%"
    });
    this.getView().setModel(oDeviceModel, "device");

    sap.ui.Device.media.attachHandler((mParams) => {
        const bPhone = mParams.name === "Phone";
        oDeviceModel.setProperty("/layoutDirection", bPhone ? "Column" : "Row");
        oDeviceModel.setProperty("/panelWidth", bPhone ? "100%" : "50%");
    }, null, sap.ui.Device.media.RANGESETS.SAP_STANDARD);
}

주요 속성 정리

속성의미주요 값
direction주축 방향Row, Column, RowReverse, ColumnReverse
justifyContent주축 정렬Start, Center, End, SpaceBetween, SpaceAround
alignItems교차축 정렬Start, Center, End, Stretch, Baseline
wrap줄바꿈 허용NoWrap, Wrap, WrapReverse
renderTypeDOM 렌더 방식Div, Bare, List

흔한 실수와 트러블슈팅

HBox 자식이 공간을 다 채우지 않을 때는 자식에 <FlexItemData growFactor="1"/>를 추가하면 CSS flex-grow: 1이 적용되어 남는 공간을 차지합니다. VBox 높이가 의도대로 잡히지 않을 때는 fitContainer="true"를 지정하거나 height="100%"를 명시합니다. FlexBox를 중첩할 때 DOM 깊이가 깊어지면 renderType="Bare"로 래퍼 div를 제거해 성능을 개선할 수 있습니다.

판단 기준 정리

단순 수평 배치라면 HBox, 단순 수직 스택이라면 VBox를 사용합니다. 방향을 동적으로 전환하거나 wrap, alignContent를 세밀히 제어해야 할 때는 FlexBox를 직접 사용합니다. 일반적으로 고정된 레이아웃에는 HBox와 VBox가 코드 가독성이 높고, 반응형 요구사항이 생기면 FlexBox로 전환하는 방식이 실용적입니다.

HBox/VBox 이후 살펴볼 컨트롤

FlexBox에 익숙해지면 sap.ui.layout.Splitter(드래그 분할), sap.f.GridContainer(카드 대시보드), sap.m.OverflowToolbar(버튼 자동 접힘)도 함께 익혀두면 반응형 화면 설계가 훨씬 수월해집니다.

댓글 0

아직 댓글이 없습니다.