Skip to main content

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

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

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

caution

플렉스 박스는 웹 CSS와 동일한 방식으로 동작하지만, 몇 가지 차이점이 있다. 기본값이 다르며, flexDirectionrow 대신 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-around를 사용하면 첫 번째 자식 요소의 시작 부분과 마지막 자식 요소의 끝 부분에도 공간이 분배된다.

  • space-evenly: 컨테이너의 메인 축을 따라 자식 요소들을 균등하게 배치한다. 각 인접한 요소 쌍 사이의 간격, 메인 축 시작 부분과 첫 번째 요소 사이의 간격, 메인 축 끝 부분과 마지막 요소 사이의 간격이 모두 동일하다.

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

Align Items

alignItems는 컨테이너의 교차 축을 기준으로 자식 요소들을 어떻게 정렬할지 정의한다. justifyContent와 매우 유사하지만, 주축이 아닌 교차 축에 적용된다는 점이 다르다.

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

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

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

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

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

info

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

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

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를 사용해 줄들이 컨테이너 내에서 어떻게 배치될지 지정할 수 있다. 자세한 내용은 여기에서 확인할 수 있다.

플렉스 박스의 Basis, Grow, Shrink 이해

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

  • flexGrow는 컨테이너 내에서 남은 공간을 주축을 따라 자식들 사이에 어떻게 분배할지 정의한다. 자식들을 배치한 후, 컨테이너는 남은 공간을 자식들의 flexGrow 값에 따라 비례적으로 분배한다.

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

  • flexShrink는 주축을 따라 자식들의 크기가 컨테이너의 크기를 초과할 경우, 자식들을 어떻게 줄일지 정의한다. flexShrinkflexGrow와 매우 유사하며, 초과된 크기를 음수의 남은 공간으로 생각하면 이해하기 쉽다. 이 두 속성은 자식들이 필요에 따라 늘어나거나 줄어들 수 있도록 함께 잘 작동한다.

    flexShrink는 0 이상의 부동 소수점 값을 받으며, 기본값은 0이다(웹에서는 기본값이 1이다). 컨테이너는 자식들의 flexShrink 값에 따라 자식들의 크기를 줄인다.

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

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

  • rowGap은 엘리먼트의 행 사이 간격(거터) 크기를 설정한다.

  • columnGap은 엘리먼트의 열 사이 간격(거터) 크기를 설정한다.

  • gap은 행과 열 사이 간격 크기를 설정한다. rowGapcolumnGap을 한 번에 지정하는 단축 속성이다.

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

너비와 높이

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에서 포함 블록의 동작 방식은 웹에서의 동작 방식과 매우 유사하지만, 일부 웹 기능이 없기 때문에 단순화된 형태로 구현된다.

절대 위치로 지정된 엘리먼트의 top, right, bottom, left 값은 포함 블록을 기준으로 상대적으로 결정된다.

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

다음 목록은 특정 엘리먼트의 포함 블록을 결정하는 데 도움을 준다:

  • 엘리먼트의 position 타입이 relative 또는 static이라면, 포함 블록은 부모 엘리먼트이다.
  • 엘리먼트의 position 타입이 absolute라면, 포함 블록은 다음 조건 중 하나를 만족하는 가장 가까운 상위 엘리먼트이다:
    • static이 아닌 position 타입을 가진 경우
    • transform 속성을 가진 경우

더 깊이 알아보기

플렉스 박스를 더 잘 이해하기 위해 Yoga Playground를 활용해 보자. 이 인터랙티브 도구를 사용하면 개념을 더 명확히 이해할 수 있다.

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

또한, Wix 엔지니어들이 작성한 예제도 참고하면 도움이 될 것이다.