Flutter&Dart

Flutter Column Row와 축(Axis) 정렬 정리

dev-emong 2026. 9. 8. 11:25

Flutter에서 레이아웃을 처음 배울 때 가장 많이 쓰는 위젯이 ColumnRow다.

이 둘을 잘 이해하면 대부분의 화면 배치를 해결할 수 있다.

그런데 mainAxisAlignmentcrossAxisAlignment가 등장하는 순간 헷갈리기 시작한다.

이번 글에서는 이 두 개념을 축(axis)의 관점에서 명확하게 정리한다.

1. Column과 Row의 차이

ColumnRow는 자식 위젯 여러 개를 받아 나란히 배치하는 위젯이다. 차이는 방향뿐이다.

  • Column: 자식들을 **세로(위에서 아래)**로 배치

  • Row: 자식들을 **가로(왼쪽에서 오른쪽)**로 배치

// 세로 배치
Column(
  children: [
    Text('첫 번째'),
    Text('두 번째'),
    Text('세 번째'),
  ],
)

// 가로 배치
Row(
  children: [
    Icon(Icons.star),
    SizedBox(width: 8),
    Text('즐겨찾기'),
  ],
)

children(복수)을 받는다는 점도 기억해두자. ContainerCenter처럼 위젯 하나만 받는 경우는 child(단수)를 사용한다.

2. 두 개의 축 — mainAxis와 crossAxis

Column과 Row 각각에는 두 개의 축이 존재한다.

Column Row
주축(mainAxis) 세로 방향 (↕) 가로 방향 (↔)
교차축(crossAxis) 가로 방향 (↔) 세로 방향 (↕)

즉, 주축(mainAxis)은 배치가 이루어지는 방향이고, 교차축(crossAxis)은 그에 수직인 방향이다. Column의 주축은 세로, Row의 주축은 가로다.

이 개념이 중요한 이유는, 정렬 속성 이름이 "주축/교차축 기준"으로 붙어있기 때문이다. mainAxisAlignment는 주축 방향 정렬이고, crossAxisAlignment는 교차축 방향 정렬이다.

3. mainAxisAlignment — 주축 정렬

자식 위젯들을 주축 방향으로 어떻게 배치할지 결정한다.

Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: [Text('A'), Text('B'), Text('C')],
)
동작
start 시작점(Column이면 위, Row면 왼쪽)에 붙여서 배치. 기본값
end 끝점에 붙여서 배치
center 중앙에 모아서 배치
spaceBetween 첫 번째와 마지막은 가장자리에 붙이고, 나머지 간격을 균등하게
spaceAround 각 위젯 양쪽에 동일한 여백. 가장자리는 그 절반
spaceEvenly 모든 간격(가장자리 포함)을 동일하게

spaceBetween은 AppBar처럼 양쪽 끝에 위젯을 붙이고 가운데를 비울 때 자주 쓴다.

4. crossAxisAlignment — 교차축 정렬

교차축 방향으로 자식들을 정렬한다. Column 기준이면 가로 방향 정렬이다.

Column(
  crossAxisAlignment: CrossAxisAlignment.start,  // 왼쪽 정렬
  children: [
    Text('이 텍스트는'),
    Text('전부 왼쪽에 붙어있다'),
  ],
)
동작
start 교차축의 시작점. Column이면 왼쪽, Row이면 위쪽
center 교차축 중앙. 기본값
end 교차축 끝. Column이면 오른쪽, Row이면 아래쪽
stretch 교차축을 꽉 채우도록 늘림

crossAxisAlignment.stretch는 Column 안의 버튼이나 카드를 화면 너비 전체로 늘릴 때 유용하다.

5. mainAxisSize — 주축 크기

Column과 Row는 기본적으로 주축 방향으로 가능한 최대 크기를 차지한다. 이 동작을 바꾸고 싶으면 mainAxisSize를 사용한다.

Column(
  mainAxisSize: MainAxisSize.min,   // 자식들의 합계 크기만큼만 차지
  children: [Text('A'), Text('B')],
)

MainAxisSize.min은 다이얼로그나 바텀시트처럼 내용물 크기에 딱 맞게 줄어들어야 하는 경우에 쓴다.

6. 자주 쓰는 패턴

화면 가운데 배치

Column(
  mainAxisAlignment: MainAxisAlignment.center,
  crossAxisAlignment: CrossAxisAlignment.center,
  children: [
    Icon(Icons.check_circle, size: 64),
    SizedBox(height: 16),
    Text('완료되었습니다'),
  ],
)

AppBar 스타일 좌우 분리

Row(
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  children: [
    Text('제목'),
    Icon(Icons.more_vert),
  ],
)

리스트 아이템 가로 배치

Row(
  children: [
    CircleAvatar(child: Text('김')),
    SizedBox(width: 12),
    Expanded(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('김철수', style: TextStyle(fontWeight: FontWeight.bold)),
          Text('안녕하세요', style: TextStyle(color: Colors.grey)),
        ],
      ),
    ),
    Text('오후 3:42'),
  ],
)

정리

Column은 세로, Row는 가로로 위젯을 배치한다. mainAxisAlignment는 배치 방향 정렬, crossAxisAlignment는 그에 수직인 방향 정렬이다. 이 두 속성을 조합하면 대부분의 레이아웃을 만들 수 있다.