margin이란
margin은 요소 테두리 바깥의 공간이에요. 항상 투명하고, 다른 요소를 밀어내는 게 역할이에요. 예제에서는 파란 상자 둘레의 margin을 통해 회색 컨테이너가 보여요.
회색 띠는 상자의 일부가 아니에요. 상자 자체의 배경은 테두리에서 멈춰요. 요소의 배경을 가져가는 공간이 필요하면 padding을 쓰세요.
margin 단축 속성
margin은 값을 한 개에서 네 개까지 받고, padding과 같은 시계 방향 순서예요.
| 선언 | 위 | 오른쪽 | 아래 | 왼쪽 |
|---|---|---|---|---|
margin: 10px; | 10 | 10 | 10 | 10 |
margin: 10px 20px; | 10 | 20 | 10 | 20 |
margin: 10px 20px 30px; | 10 | 20 | 30 | 20 |
margin: 10px 20px 30px 40px; | 10 | 20 | 30 | 40 |
방향마다 자기 속성(margin-top, margin-right, margin-bottom, margin-left)도 있고, 텍스트 방향을 따르는 논리적 버전(margin-inline-start, margin-inline-end, margin-block, margin-inline)도 있어요.
padding과 달리 margin은 auto와 음수 값을 받아요.
| 값 | 예시 | 설명 |
|---|---|---|
| 길이 | 16px, 1.5rem | 가장 흔해요 |
| 퍼센트 | 5% | 네 방향 모두 포함 블록 너비 기준 |
auto | margin: 0 auto | 브라우저가 남는 공간을 채워요 |
| 음수 | margin-top: -10px | 요소나 이웃을 가까이 당기고, 겹칠 수 있어요 |
margin: 0 auto로 가운데 정렬
margin: 0 auto는 블록을 가로로 가운데 정렬하는 고전적인 방법이에요. 양쪽의 auto는 브라우저에게 남는 공간을 똑같이 나누라고 알려 줘요. 너비가 컨테이너보다 작아야 해요. 그렇지 않으면 나눌 공간이 없어요.
auto margin은 일반 흐름에서 세로 가운데 정렬을 하지 않고(세로 auto margin은 0이 돼요), 인라인 요소에서는 아무 일도 하지 않아요. 가운데 정렬의 전체 정리는 div 가운데 정렬을 보세요.
마진 상쇄
두 세로 margin이 맞닿으면 더해지지 않아요. 브라우저는 큰 쪽 하나만 남겨요. 여기서 첫 번째 상자는 margin-bottom: 30px, 두 번째 상자는 margin-top: 20px이고, 둘 사이의 간격은 50px이 아니라 30px이에요.
상쇄는 의도된 동작이에요. 문단과 제목이 각자 간격을 가지고 있어도 만나는 곳에서 두 배가 되지 않게 해 줘요. 사람들이 당황하는 두 번째 경우는 자식의 위 margin이 부모 밖으로 빠져나갈 때예요.
첫 번째 부모에서는 자식의 30px margin이 부모의 위쪽 가장자리를 뚫고 상쇄돼서, 안쪽에 회색 공간을 만드는 대신 부모 전체를 아래로 밀어요. 다음 중 하나면 막을 수 있어요.
- 부모에
display: flow-root(overflow: hidden과 달리 아무것도 잘라내지 않아요). - 부모의 위쪽 가장자리에 padding이나 border.
- flex나 grid 부모: flex와 grid 항목의 margin은 절대 상쇄되지 않아요.
가로 margin은 절대 상쇄되지 않고, float이나 absolute 위치 요소의 margin도 마찬가지예요.
음수 margin
음수 margin은 반대 방향으로 당겨요. 위쪽이나 시작 쪽에서는 요소 자체를 움직이고, 아래쪽이나 끝 쪽에서는 다음 요소를 가까이 당겨요. 상자가 겹칠 수 있어요.
flexbox의 margin auto
flex 컨테이너 안에서 auto margin은 그쪽의 빈 공간을 모두 차지해요. 한 항목을 줄의 반대쪽 끝으로 미는 가장 간단한 방법이고, flexbox에서는 auto가 세로로도 동작해요.
margin-inline-start: auto는 "Log in" 앞에 빈 공간을 둬서, 왼쪽에서 오른쪽 페이지와 오른쪽에서 왼쪽 페이지 모두에서 줄의 끝에 놓이게 해요.
자주 하는 실수
- 너비 없는 요소에
margin: 0 auto. 블록은 이미 컨테이너를 채워요.width나max-width를 지정하세요. - 인라인 요소에
margin: auto. 인라인으로 남아 있는span,a,img의 auto margin은 0이에요.display: block으로 만드세요. - 세로 margin 두 개를 더한 값을 기대하기. 큰 쪽 하나로 상쇄돼요. flex나 grid에서
gap을 쓰거나, margin 방향을 한쪽으로 일관되게 쓰세요. - 자식의 margin이 부모를 밀기. 부모와 자식 사이의 상쇄예요. 부모에
display: flow-root를 추가하세요. - 배경이 있어야 하는 공간에 margin 쓰기. margin은 투명해요. padding을 쓰세요.
자주 묻는 질문
CSS에서 margin이란 무엇인가요?
요소 테두리 바깥의 공간이에요. 투명하고, 이웃한 요소를 밀어내요. margin이나 방향별 속성 margin-top, margin-right, margin-bottom, margin-left로 지정해요.
margin: 0 auto는 무엇을 하나요?
위아래 margin을 0으로 하고, 남는 가로 공간을 왼쪽과 오른쪽 margin에 똑같이 나눠서 블록 요소를 가로로 가운데 정렬해요. 요소의 너비가 컨테이너보다 작아야 해요. 예를 들면 max-width: 600px처럼요.
margin auto로 가운데 정렬이 안 되는 이유는 무엇인가요?
보통 요소에 너비가 없거나(블록은 컨테이너를 채워서 나눌 공간이 없어요), 인라인 요소라서(span, a, img는 기본이 인라인이고 auto margin이 0이에요) 그래요. 너비와 display: block을 주거나, 부모에서 flexbox나 grid로 가운데 정렬하세요.
마진 상쇄(margin collapsing)란 무엇인가요?
두 세로 margin이 만나면, 예를 들어 한 문단의 아래 margin과 다음 문단의 위 margin이 만나면, 브라우저는 둘을 더하지 않고 큰 쪽 하나만 써요. 일반 흐름에 있는 블록 상자의 세로 margin에서만 일어나고, flex나 grid 레이아웃에서는 일어나지 않아요.
margin에 음수 값을 쓸 수 있나요?
네. 음수 margin은 요소를 그쪽으로 당기거나 다음 요소를 그 위로 끌어와서 상자가 겹칠 수 있어요. 작은 정렬 보정이나, 요소가 컨테이너의 padding 밖으로 나가게 할 때 유용해요.