-
Flutter에서 Container(width)가 안 먹는 이유AI Agent/flutter 2026. 7. 2. 09:00728x90반응형

width: 300이 무시되던 삼십 분의 기록 width: 200을240으로 바꿔도 화면은 그대로였습니다.300으로 해봐도 똑같았습니다.
숫자만 바뀌고 파란 박스의 폭은 1픽셀도 안 움직였습니다.
삼십 분쯤 이걸 붙잡고 있었습니다.
hot reload가 안 먹나 싶어서 앱을 껐다 켜기도 했고요.Flutter 레이아웃은 자식이 "나 200이야"라고 선언하면 그대로 되는 구조가 아니었습니다.
부모가 먼저 "너는 이 안에서만 커라"라고 제약을 내려보내고, 자식은 그 제약 안에서 크기를 고릅니다.
제 파란 박스는 부모가 이미 폭을 정해둔 자리에 앉아 있었습니다.제약이 내려가고, 크기가 올라옵니다
그 시간 동안 제가 한 짓을 돌아보면 좀 웃깁니다.
200을 240으로, 240을 300으로, 안 되니까 이번엔 반대로 150으로.
숫자만 위아래로 흔들었습니다.
중간엔color를 빨강으로 바꿔서 박스가 화면에 있긴 한지부터 확인했고요.
박스는 분명히 있었습니다.
폭만 제 말을 안 들었을 뿐이죠.문서에서 본 한 문장이 그제서야 걸렸습니다.
"Constraints go down.
Sizes go up.
Parent sets position." 제약은 부모에서 자식으로 내려가고, 크기는 자식에서 부모로 올라가고, 위치는 부모가 정한다.
외울 땐 무슨 말인지 몰랐는데, 안 움직이는 박스 앞에서 보니 뜻이 살아났습니다.제 코드는 이랬습니다.
Row( children: [ Expanded( child: Container(width: 300, height: 60, color: Colors.blue), ), Text('옆 칸'), ], )문제는
Expanded였습니다.Expanded는 자식에게 "가로는 남는 만큼 딱 이만큼 채워"라는 제약을 내려보냅니다.
이 제약은 최솟값과 최댓값이 같은, 이른바 tight 제약입니다.
폭이 하나로 못 박혀 있으니 자식은 크기를 고를 여지가 없습니다.
그러니 Container에 적은width: 300은 읽히지도 않고 버려집니다.
숫자를 아무리 바꿔도 화면이 그대로였던 건 이 때문이었습니다.
제가 바꾸던 건 자식의 희망 사항이었고, 실제 결정권은 부모가 내려보내는 제약에 있었습니다.Layout Explorer가 보여준 숫자
DevTools의 Layout Explorer를 연 게 그때가 처음이었습니다.
위젯을 클릭하니 부모가 자식에게 내려보낸 제약이 그대로 숫자로 떠 있었습니다.BoxConstraints(w=..., h=...)형태로요.
제가 준 200이나 300이라는 값이 부모의 제약 범위와 어떻게 부딪히는지가 한눈에 보였습니다.
콘솔에 print 찍던 것과는 다른 종류의 정보였습니다.
화면이 왜 이 크기인지를, 위젯 트리의 위아래 방향으로 읽게 해줬거든요.클릭한 순간 제일 먼저 눈에 들어온 건 width의 최솟값과 최댓값이 똑같은 숫자였다는 점입니다.
w=132.0처럼 값 하나로 딱 고정돼 있었죠.
최솟값과 최댓값이 같다는 건 "이 폭이어야 한다"는 명령이지 "이 안에서 골라라"가 아닙니다.
제가 준 300은 그 사이에 낄 자리가 없었습니다.
그 132라는 숫자도 제가 어디에도 적은 적 없는 값이었습니다.
옆 칸 텍스트를 놓고 Row에 남은 가로를Expanded가 통째로 자식한테 넘긴 결과였습니다.콘솔에 print로 width를 찍었으면 132라는 결과만 봤지, 그게 왜 132인지는 몰랐을 겁니다.
Layout Explorer는 그 숫자가 위에서 어떻게 정해져 내려왔는지를 트리로 보여줬습니다.
print가 결과라면 이건 경로였습니다.
부모 노드를 하나씩 접었다 펴면서, 어느 위젯이 tight 제약을 걸었는지를 손가락으로 짚어갈 수 있었습니다.(사실 이 도구가 있는 걸 그날 처음 안 게 조금 부끄러웠습니다.
반나절도 아니고 그 짧은 시간을 숫자만 바꾸며 날렸으니까요.)Expanded를 벗기니 폭이 돌아왔습니다
돌아보니 제가 헷갈린 건 의도 두 개가 섞여 있어서였습니다.
남는 공간을 다 채우고 싶으면Expanded가 맞고, 딱 300 폭이 필요하면Expanded로 감싸면 안 됩니다.
저는 300을 원하면서Expanded로 싸매고 있었으니, 서로 반대되는 말을 코드에 동시에 적어둔 셈이었습니다.
그래서 감싼 걸 벗겼습니다.Row( children: [ Container(width: 300, height: 60, color: Colors.blue), Text('옆 칸'), ], )Row는Expanded로 감싸지 않은 자식에게는 loose 제약을 줍니다.
"0부터 남는 만큼 사이에서 네가 골라"라는 뜻이라, 이제 Container의width: 300이 그 범위 안에서 존중됩니다.
최솟값이 0이고 최댓값이 넉넉하니 300이 그 사이에 편하게 들어앉은 거죠.
hot reload를 누르자마자 파란 박스가 300 폭으로 딱 서고 옆 칸이 그 오른쪽에 붙었습니다.
한참을 안 움직이던 게 한 번에 자리를 잡으니 좀 허무하더라고요.이제 박스가 안 움직이면
요즘은 위젯 크기가 코드대로 안 나오면 숫자를 바꾸는 대신 Layout Explorer부터 엽니다.
그 위젯에 실제로 어떤 제약이 내려오고 있는지를 봅니다.
대개는 제가 준 값이 무시된 게 아니라, 부모가 이미 다른 말을 하고 있었던 거였습니다.아직도
IntrinsicWidth나 높이가 정해지지 않은 자리는 감이 덜 옵니다.
스크롤 안에 또 스크롤을 넣을 때 나는 그 빨간 에러 화면은 매번 문서를 다시 봅니다.
그건 다음 삽질의 몫으로 남겨뒀습니다.728x90반응형'AI Agent > flutter' 카테고리의 다른 글
Flutter 성능은 16ms 프레임 예산을 쓰는 방식입니다 (0) 2026.07.03 Flutter 에러는 try/catch 하나로 잡히지 않습니다 (0) 2026.07.02 Flutter 앱의 경계는 Dart 코드 바깥에도 있습니다 (0) 2026.07.02 build()는 명령이 아니라 현재 상태의 선언입니다 (0) 2026.07.01 Flutter 앱 생명주기는 화면보다 먼저 시작됩니다 (0) 2026.07.01