Skip to main content
Version: Next

플렉스 박스를 활용한 레이아웃

컴포넌트는 플렉스 박스 알고리즘을 사용해 자식 엘리먼트의 레이아웃을 지정할 수 있다. 플렉스 박스는 다양한 화면 크기에서 일관된 레이아웃을 제공하도록 설계되었다.

일반적으로 flexDirection, alignItems, justifyContent를 조합해 원하는 레이아웃을 구현한다.

caution

플렉스 박스는 웹의 CSS와 동일하게 동작하지만 몇 가지 차이점이 있다. 기본값이 다르다. flexDirection은 기본값이 row가 아닌 column이고, alignContentstretch가 아닌 flex-start이며, flexShrink1이 아닌 0이다. 또한 flex 파라미터는 단일 숫자만 지원한다.

플렉스 박스

flex는 메인 축을 따라 사용 가능한 공간을 아이템들이 어떻게 "채울지" 정의한다. 각 엘리먼트의 flex 속성에 따라 공간이 나뉜다.

다음 예제에서 빨간색, 주황색, 초록색 뷰는 모두 flex: 1이 설정된 컨테이너 뷰의 자식 엘리먼트다. 빨간색 뷰는 flex: 1, 주황색 뷰는 flex: 2, 초록색 뷰는 flex: 3을 사용한다. 1+2+3 = 6이므로, 빨간색 뷰는 전체 공간의 1/6, 주황색 뷰는 2/6, 초록색 뷰는 3/6을 차지한다.

플렉스 방향

flexDirection은 노드의 자식 요소들이 배치되는 방향을 제어한다. 이를 메인 축이라고도 부른다. 크로스 축은 메인 축에 수직인 축으로, 줄바꿈이 발생할 때 요소가 배치되는 방향이다.

  • column (기본값): 자식 요소를 위에서 아래로 정렬한다. 줄바꿈이 활성화된 경우, 다음 줄은 컨테이너 상단의 첫 번째 아이템 오른쪽에서 시작한다.

  • row: 자식 요소를 왼쪽에서 오른쪽으로 정렬한다. 줄바꿈이 활성화된 경우, 다음 줄은 컨테이너 왼쪽의 첫 번째 아이템 아래에서 시작한다.

  • column-reverse: 자식 요소를 아래에서 위로 정렬한다. 줄바꿈이 활성화된 경우, 다음 줄은 컨테이너 하단의 첫 번째 아이템 오른쪽에서 시작한다.

  • row-reverse: 자식 요소를 오른쪽에서 왼쪽으로 정렬한다. 줄바꿈이 활성화된 경우, 다음 줄은 컨테이너 오른쪽의 첫 번째 아이템 아래에서 시작한다.

더 자세한 내용은 여기에서 확인할 수 있다.

레이아웃 방향

레이아웃 direction은 계층 구조 내에서 자식 요소와 텍스트가 배치되는 방향을 지정한다. 이 속성은 startend가 가리키는 가장자리에도 영향을 미친다. 기본적으로 React Native는 LTR(왼쪽에서 오른쪽) 레이아웃 방향을 사용한다. 이 모드에서 start는 왼쪽을, end는 오른쪽을 의미한다.

  • LTR (기본값) 텍스트와 자식 요소가 왼쪽에서 오른쪽으로 배치된다. 요소의 시작 부분에 적용된 마진과 패딩은 왼쪽에 적용된다.

  • RTL 텍스트와 자식 요소가 오른쪽에서 왼쪽으로 배치된다. 요소의 시작 부분에 적용된 마진과 패딩은 오른쪽에 적용된다.

Justify Content

justifyContent는 컨테이너의 메인 축을 기준으로 자식 요소들을 어떻게 정렬할지 결정한다. 예를 들어, 이 속성을 사용해 flexDirectionrow로 설정된 컨테이너 내에서 자식 요소를 수평으로 가운데 정렬하거나, flexDirectioncolumn으로 설정된 컨테이너 내에서 자식 요소를 수직으로 가운데 정렬할 수 있다.

  • flex-start(기본값): 컨테이너의 메인 축 시작점에 자식 요소를 정렬한다.
  • flex-end: 컨테이너의 메인 축 끝점에 자식 요소를 정렬한다.
  • center: 컨테이너의 메인 축 중앙에 자식 요소를 정렬한다.
  • space-between: 컨테이너의 메인 축을 따라 자식 요소 사이에 남은 공간을 균등하게 분배한다.
  • space-around: 컨테이너의 메인 축을 따라 자식 요소 주변에 남은 공간을 균등하게 분배한다. space-between과 달리, 첫 번째 자식 요소의 시작 부분과 마지막 자식 요소의 끝 부분에도 공간이 분배된다.
  • space-evenly: 컨테이너의 메인 축을 따라 자식 요소를 균등하게 배치한다. 각 자식 요소 사이의 간격, 첫 번째 자식 요소와 메인 축 시작점 사이의 간격, 마지막 자식 요소와 메인 축 끝점 사이의 간격이 모두 동일하다.

더 자세한 내용은 여기에서 확인할 수 있다.

Align Items

alignItems는 컨테이너의 교차 축(cross axis)을 기준으로 자식 요소를 정렬하는 방법을 정의한다. justifyContent와 매우 유사하지만, 주축(main axis) 대신 교차 축에 적용된다는 점이 다르다.

  • stretch (기본값): 컨테이너의 교차 축 높이에 맞게 자식 요소를 늘린다.

  • flex-start: 컨테이너의 교차 축 시작점에 자식 요소를 정렬한다.

  • flex-end: 컨테이너의 교차 축 끝점에 자식 요소를 정렬한다.

  • center: 컨테이너의 교차 축 중앙에 자식 요소를 정렬한다.

  • baseline: 컨테이너의 자식 요소를 공통 기준선(baseline)에 맞춰 정렬한다. 각 자식 요소는 부모의 기준선이 될 수 있다.

info

stretch가 효과를 발휘하려면, 자식 요소가 교차 축 방향으로 고정된 크기를 가지면 안 된다. 아래 예제에서 alignItems: stretch를 설정해도 width: 50이 자식 요소에 설정되어 있으면 아무런 효과가 없다. width: 50을 제거해야 stretch가 적용된다.

더 자세한 내용은 여기에서 확인할 수 있다.

Align Self

alignSelfalignItems와 동일한 옵션과 효과를 가지지만, 컨테이너 내부의 자식들 전체에 영향을 주는 대신, 특정 자식에 이 속성을 적용해 부모 내에서의 정렬을 변경할 수 있다. alignSelf는 부모가 alignItems로 설정한 옵션을 덮어쓴다.

Align Content

alignContent는 교차 축(cross-axis)을 따라 라인을 배치하는 방식을 정의한다. 이 속성은 flexWrap을 사용해 여러 줄로 나뉜 아이템에만 적용된다.

  • flex-start (기본값): 여러 줄을 컨테이너의 교차 축 시작점에 정렬한다.
  • flex-end: 여러 줄을 컨테이너의 교차 축 끝점에 정렬한다.
  • stretch (웹에서 Yoga를 사용할 때의 기본값): 여러 줄을 컨테이너의 교차 축 높이에 맞게 늘린다.
  • center: 여러 줄을 컨테이너의 교차 축 중앙에 정렬한다.
  • space-between: 여러 줄을 컨테이너의 교차 축에 균등하게 배치하고, 남은 공간을 줄 사이에 분배한다.
  • space-around: 여러 줄을 컨테이너의 교차 축에 균등하게 배치하고, 남은 공간을 줄 주위에 분배한다. 컨테이너 양 끝의 공간은 줄 사이의 공간보다 절반 크기다.
  • space-evenly: 여러 줄을 컨테이너의 교차 축에 균등하게 배치하고, 남은 공간을 줄 주위에 동일한 크기로 분배한다.

더 자세한 내용은 여기에서 확인할 수 있다.

플렉스 박스 줄바꿈

flexWrap 속성은 컨테이너에 설정하며, 자식 엘리먼트가 컨테이너의 주축 크기를 초과할 때 어떻게 처리할지 결정한다. 기본적으로 자식 엘리먼트는 한 줄에 강제로 배치되며(이 경우 엘리먼트가 축소될 수 있음), 줄바꿈이 허용되면 필요에 따라 주축을 따라 여러 줄로 나뉜다.

줄바꿈이 발생할 때, alignContent를 사용해 줄이 컨테이너 내에서 어떻게 배치될지 지정할 수 있다. 자세한 내용은 여기에서 확인할 수 있다.

플렉스 박스의 기본 크기, 확장, 축소

  • flexBasis는 주축을 따라 아이템의 기본 크기를 설정하는 축 독립적인 방법이다. 부모 컨테이너가 flexDirection: row일 때는 아이템의 width를 설정하는 것과 유사하고, flexDirection: column일 때는 height를 설정하는 것과 유사하다. flexBasis는 아이템의 기본 크기를 정의하며, flexGrowflexShrink 계산이 수행되기 전의 크기를 의미한다.

  • flexGrow는 컨테이너 내에서 남은 공간을 아이템들 간에 어떻게 분배할지 결정한다. 아이템을 배치한 후, 컨테이너는 남은 공간을 아이템의 flexGrow 값에 따라 비율적으로 분배한다.

    flexGrow는 0 이상의 부동 소수점 값을 받으며, 기본값은 0이다. 컨테이너는 아이템의 flexGrow 값에 따라 남은 공간을 분배한다.

  • flexShrink는 아이템의 크기가 컨테이너를 넘칠 때 주축을 따라 아이템을 어떻게 축소할지 결정한다. flexShrinkflexGrow와 매우 유사하며, 넘치는 크기를 음수의 남은 공간으로 생각하면 이해하기 쉽다. 이 두 속성은 아이템이 필요에 따라 확장되고 축소될 수 있도록 함께 작동한다.

    flexShrink는 0 이상의 부동 소수점 값을 받으며, 기본값은 0이다(웹에서는 기본값이 1이다). 컨테이너는 아이템의 flexShrink 값에 따라 아이템을 축소한다.

더 자세한 내용은 여기에서 확인할 수 있다.

행 간격, 열 간격, 그리고 간격

  • rowGap은 엘리먼트의 행 사이 간격(거터) 크기를 설정한다.
  • columnGap은 엘리먼트의 열 사이 간격(거터) 크기를 설정한다.
  • gap은 행과 열 사이의 간격 크기를 설정한다. 이는 rowGapcolumnGap을 한 번에 설정하는 단축 속성이다.

flexWrapalignContentgap과 함께 사용하면 아이템 간 일관된 간격을 추가할 수 있다.

너비와 높이

width 속성은 엘리먼트의 콘텐츠 영역 너비를 지정한다. 마찬가지로 height 속성은 엘리먼트의 콘텐츠 영역 높이를 지정한다.

widthheight는 다음과 같은 값을 가질 수 있다:

  • auto (기본값): React Native가 엘리먼트의 너비/높이를 자식 엘리먼트, 텍스트, 이미지 등의 콘텐츠를 기반으로 계산한다.

  • pixels: 절대적인 픽셀 단위로 너비/높이를 정의한다. 컴포넌트에 설정된 다른 스타일에 따라 최종 노드 크기가 달라질 수 있다.

  • percentage: 부모 엘리먼트의 너비 또는 높이에 대한 백분율로 너비 또는 높이를 정의한다.

Position

엘리먼트의 position 타입은 해당 엘리먼트가 자신, 부모, 또는 컨테이닝 블록에 대해 어떻게 위치할지 정의한다.

  • relative (기본값): 기본적으로 엘리먼트는 상대적으로 위치한다. 이는 엘리먼트가 레이아웃의 일반적인 흐름에 따라 배치된 후, top, right, bottom, left 값에 따라 그 위치에서 상대적으로 오프셋을 적용한다는 의미다. 이 오프셋은 형제나 부모 엘리먼트의 위치에 영향을 미치지 않는다.

  • absolute: 절대적으로 위치할 경우, 엘리먼트는 일반적인 레이아웃 흐름에 참여하지 않는다. 대신 형제 엘리먼트와 독립적으로 배치된다. 위치는 top, right, bottom, left 값에 따라 결정되며, 이 값들은 엘리먼트를 컨테이닝 블록에 상대적으로 위치시킨다.

  • static: 정적으로 위치할 경우, 엘리먼트는 레이아웃의 일반적인 흐름에 따라 배치되며, top, right, bottom, left 값을 무시한다. 이 position은 또한 엘리먼트가 절대적으로 위치한 자손 엘리먼트에 대한 컨테이닝 블록을 형성하지 않는다. 단, 다른 우선순위가 높은 스타일 속성(예: transform)이 있는 경우는 예외다. 이를 통해 absolute 엘리먼트가 부모가 아닌 다른 요소에 대해 위치할 수 있다. static은 New Architecture에서만 사용 가능하다는 점에 유의한다.

컨테이닝 블록

컨테이닝 블록은 엘리먼트의 위치와 크기를 제어하는 상위 엘리먼트를 말한다. React Native에서 컨테이닝 블록의 동작 방식은 웹에서의 동작과 매우 유사하지만, 일부 웹 기능이 없기 때문에 단순화된 형태로 구현된다.

절대 위치 지정(absolute positioning)된 엘리먼트의 top, right, bottom, left 값은 해당 엘리먼트의 컨테이닝 블록을 기준으로 계산된다.

절대 위치 지정된 엘리먼트에 적용된 백분율 길이(예: width: '50%' 또는 padding: '10%')는 컨테이닝 블록의 크기를 기준으로 계산된다. 예를 들어, 컨테이닝 블록의 너비가 100포인트라면, 절대 위치 지정된 엘리먼트의 width: 50%는 50포인트 너비로 계산된다.

다음 목록은 주어진 엘리먼트의 컨테이닝 블록을 결정하는 데 도움을 준다:

  • 엘리먼트의 position 타입이 relative 또는 static인 경우, 컨테이닝 블록은 부모 엘리먼트가 된다.
  • 엘리먼트의 position 타입이 absolute인 경우, 컨테이닝 블록은 다음 조건 중 하나를 만족하는 가장 가까운 상위 엘리먼트가 된다:
    • position 타입이 static이 아닌 경우
    • transform 속성이 적용된 경우

더 깊이 알아보기

플렉스 박스를 더 잘 이해하려면 Yoga Playground를 활용해 보자. 이 인터랙티브 도구를 사용하면 플렉스 박스의 동작을 직접 실험해 볼 수 있다.

기본 개념을 다뤘지만, 레이아웃을 구성할 때 필요한 다양한 스타일이 더 있다. 레이아웃을 제어하는 모든 속성의 전체 목록은 여기에서 확인할 수 있다.

또한, Wix 엔지니어들이 작성한 예제도 참고하면 도움이 될 것이다. 이 자료는 React Native 레이아웃을 구성하는 데 필요한 다양한 팁과 예제를 제공한다.