짧은 답
div를 부모 안에서 가로와 세로 모두 가운데 정렬하려면 부모를 grid로 만들고 콘텐츠를 가운데 정렬하세요.
.parent {
display: grid;
place-items: center;
min-height: 200px; /* the parent needs room to center in */
}
자식 크기와 상관없이 동작하고, 자식 자체에는 아무것도 필요 없어요. 아래에 여섯 가지 방법을 나란히 놓았어요. 각 상자는 렌더링된 뒤 스스로를 측정해서, 자기 중심이 부모의 중심에서 얼마나 떨어져 있는지 보여 줘요.
여섯 가지 모두 두 축에서 0px을 보여 줘요(무대의 1px 테두리는 사방이 같아서 중심을 옮기지 않아요). 상자의 너비나 텍스트를 바꾸고 다시 실행해 보세요. 고정 크기에 의존하지 않는 방법은 0을 유지해요.
어떤 방법을 쓸까
| 방법 | 가운데 정렬 축 | 자식에 고정 크기가 필요한가요? | 어울리는 곳 |
|---|---|---|---|
Grid place-items: center | 두 축 | 아니요 | 기본 선택: 상자 안의 자식 하나 |
Flexbox justify-content + align-items | 두 축 | 아니요 | 항목들의 행이나 열을 묶음으로 가운데 정렬 |
flex나 grid 부모 안의 margin: auto | 두 축 | 아니요 | 형제들은 다르게 배치하면서 항목 하나만 가운데 정렬 |
margin: 0 auto | 가로만 | width나 max-width | 일반 흐름의 페이지 컨테이너, 글, 폼 |
Absolute + translate(-50%, -50%) | 두 축 | 아니요 | 다른 콘텐츠 위의 오버레이, 배지, 모달 |
Absolute + inset: 0; margin: auto | 두 축 | 예, 너비와 높이 | 고정 크기 대화상자 |
블록의 align-content: center | 세로 | 아니요 | 부모의 display를 바꾸지 않는 세로 가운데 정렬 |
방법 1: flexbox
flexbox는 속성 두 개로 두 축을 가운데 정렬해요. justify-content는 주축(행에서는 가로)을, align-items는 교차축을 맡아요.
자식이 여러 개면 flexbox는 한 줄로 유지한 채 묶음으로 가운데 정렬해요. 세 항목을 가운데 정렬된 한 열로 쌓아 버리는 grid보다 나은 점이에요. 모든 정렬 값은 justify-content 페이지에서 다뤄요.
방법 2: grid
place-items: center는 align-items: center와 justify-items: center의 단축 속성이에요. 자식이 하나인 grid 컨테이너에서는 그 자식을 두 방향으로 가운데 정렬해요.
height 대신 min-height를 쓰면 카드가 180px보다 커질 때 카드가 넘치지 않고 부모가 커져요.
방법 3: margin: 0 auto (가로)
컨테이너보다 너비가 작은 블록 요소는 자동 좌우 margin으로 가로 가운데 정렬할 수 있어요. 브라우저가 빈 공간을 양쪽에 똑같이 나눠요.
두 번째 상자는 전체 너비를 채워서 빈 공간이 없고 아무것도 움직이지 않아요. margin: 0 auto가 "안 되는" 흔한 이유예요. 또 일반 흐름에서는 가로로만 가운데 정렬해요. 거기서는 세로 auto margin이 0이 돼요. 하지만 flex나 grid 부모 안에서는 margin: auto가 두 방향으로 가운데 정렬하고, 위 비교의 세 번째 상자가 그거예요.
방법 4: absolute position과 transform
요소가 다른 콘텐츠 위에 놓여야 할 때(사진 위의 배지, 페이지 위의 모달)는 50% 위치에 absolute로 배치하고 자기 크기의 절반만큼 되돌리세요.
top: 50%; left: 50%는 요소의 왼쪽 위 모서리를 가운데에 놓아요. translate() 안의 퍼센트는 요소 자신의 크기를 가리켜서, -50%는 너비와 높이가 얼마든 그 절반만큼 되돌려요. 부모에 위치가 지정되어 있어야 해요(position: relative). 그렇지 않으면 요소가 페이지를 기준으로 가운데 정렬돼요. 위치 지정은 position 페이지에서 다뤄요.
크기를 아는 요소를 위한 변형도 있어요. position: absolute; inset: 0; margin: auto;에 width와 height를 더하면, auto margin이 사방의 공간을 나눠 가져요.
방법 5: 일반 블록의 align-content
이제 align-content: center는 flex와 grid뿐 아니라 일반 블록 컨테이너에서도 동작해요. 자식의 배치 방식을 바꾸지 않고 콘텐츠를 세로로 가운데 정렬해요.
.parent {
min-height: 200px;
align-content: center; /* vertical centering, still display: block */
}
.child {
max-width: 300px;
margin-inline: auto; /* horizontal centering */
}
최신 Chrome, Firefox, Safari에서 지원해요. 오래된 브라우저는 무시하니, 그런 브라우저를 지원해야 한다면 grid를 쓰세요.
화면 전체에서 가운데 정렬
스크롤과 상관없이 뷰포트에서 대화상자를 가운데 정렬하려면 화면 전체를 덮는 fixed 레이어와 grid를 조합하세요.
.overlay {
position: fixed;
inset: 0; /* covers the viewport */
display: grid;
place-items: center;
background: rgb(0 0 0 / 50%);
}
페이지 전체 콘텐츠를 세로로 가운데 정렬할 때는 부모에 100vh가 아니라 min-height: 100dvh를 쓰세요. 휴대폰에서 100vh는 브라우저 툴바 뒤 영역까지 포함해서 "가운데"가 너무 아래에 놓여요.
텍스트 가운데 정렬은 다른 일이에요
위의 모든 방법은 상자를 가운데 정렬해요. 상자 안의 텍스트를 가운데 정렬하려면 HTML 텍스트 가운데 정렬 페이지에서 보여 주듯 그 상자에 text-align: center를 쓰세요. 둘 다 필요할 때가 많아요. 카드를 가운데 정렬하는 grid와, 그 안의 줄을 가운데 정렬하는 text-align이에요.
자주 하는 실수
- 높이 없는 부모. 세로 가운데 정렬에는 빈 공간이 필요해요. 콘텐츠에 맞게 줄어드는 부모에는 빈 공간이 없어요.
- 전체 너비 블록에
margin: 0 auto. 먼저width나max-width를 주세요. - 일반 흐름에서 세로 가운데 정렬하려고
margin: auto쓰기. 거기서는 세로 auto margin이 0이에요. flex나 grid를 쓰세요. - 위치 지정된 부모 없는 absolute 가운데 정렬. 요소가 상자가 아니라 페이지에서 가운데 정렬돼요.
- 자식에
align-items: center쓰기. 정렬 속성은 부모(flex나 grid 컨테이너)에 들어가요. 예외는margin: auto와align-self예요. - 블록을 가운데 정렬하려고
text-align: center쓰기. 블록 자식이 아니라 인라인 콘텐츠(텍스트, 이미지, inline-block 자식)를 가운데 정렬해요.
자주 묻는 질문
div를 가로와 세로로 가운데 정렬하려면 어떻게 하나요?
부모를 grid로 만들고 콘텐츠를 가운데 정렬하세요. .parent { display: grid; place-items: center; } flexbox 버전은 display: flex; justify-content: center; align-items: center;예요. 어느 쪽이든 부모가 div보다 높아야 해요.
div를 가로로만 가운데 정렬하려면 어떻게 하나요?
너비와 auto 좌우 margin을 주세요. .box { width: 300px; margin: 0 auto; } (반응형 블록이라면 max-width) margin-inline: auto는 논리적 속성으로 쓴 같은 방법이에요.
margin: 0 auto로 div가 가운데 정렬되지 않는 이유는 무엇인가요?
div에 컨테이너보다 작은 너비가 없어서 나눌 빈 공간이 없기 때문이에요(블록은 기본적으로 전체 너비를 채워요). width나 max-width를 지정하세요. 인라인 요소에서도 아무 일도 하지 않고, 일반 흐름에서는 절대 세로로 가운데 정렬하지 않아요.
div가 세로로 가운데 정렬되지 않는 이유는 무엇인가요?
부모가 콘텐츠만큼만 높아서 가운데 정렬할 여분의 공간이 없기 때문이에요. 부모에 높이(또는 min-height)를 주고 grid나 flexbox 가운데 정렬을 쓰세요.
div를 가운데 정렬하는 가장 쉬운 방법은 무엇인가요?
부모에 display: grid; place-items: center;예요. 선언 두 개로 두 축 모두, 자식 크기와 상관없이 돼요. 부모가 다른 항목들도 한 줄로 배치한다면 flexbox를 쓰세요.
div 안의 텍스트는 어떻게 가운데 정렬하나요?
텍스트와 인라인 콘텐츠에는 div에 text-align: center를 쓰세요. div 자체를 가운데 정렬하는 것과 그 안의 텍스트를 가운데 정렬하는 것은 별개의 일이에요.