CSS에서 요소의 레이아웃 동작을 결정하는 display 속성 중 inline-block은 인라인 요소와 블록 요소의 특성을 동시에 갖는 독특한 표시 유형입니다. 일반적으로 인라인 요소는 텍스트처럼 나란히 배치되지만 너비와 높이를 지정할 수 없고, 블록 요소는 크기를 자유롭게 조절할 수 있지만 항상 새 줄에서 시작합니다. inline-block은 이 두 가지 제약을 동시에 해결하여 요소를 수평으로 나란히 배치하면서도 원하는 크기를 지정할 수 있게 해줍니다. 이 개념을 정확히 이해하면 Flexbox나 Grid가 등장하기 이전의 레거시 레이아웃 코드를 읽고 유지보수할 수 있을 뿐 아니라, 간단한 수평 배치 상황에서 여전히 유용하게 활용할 수 있습니다.
🔑 핵심 특징
- 수평 배치와 크기 지정의 동시 지원: 인라인처럼 나란히 놓이면서도 블록처럼 width, height, margin, padding을 모두 적용할 수 있습니다
- 텍스트 흐름 내 참여: 인라인 레벨 요소로서 텍스트 기준선(baseline)에 맞춰 정렬되며, vertical-align 속성으로 세밀한 수직 정렬이 가능합니다
- 공백 문자에 의한 간격 발생: HTML 소스 코드의 줄바꿈이나 공백이 요소 사이에 의도하지 않은 틈을 만드는 고유한 특성이 있습니다
- 콘텐츠 기반 자동 크기 조절: 별도의 너비를 지정하지 않으면 내부 콘텐츠 크기에 맞춰 자동으로 축소되어, 블록 요소와는 다른 기본 동작을 보입니다
- 부모 요소의 text-align 영향: 인라인 레벨이므로 부모의 text-align 속성에 의해 수평 위치가 결정되어, 중앙 정렬 등의 레이아웃 기법에 활용됩니다
💡 실무에서의 영향
inline-block을 올바르게 이해하는 것은 CSS 레이아웃의 기본 원리를 파악하는 데 핵심적인 역할을 합니다. Flexbox와 Grid가 보편화된 현재에도 내비게이션 메뉴, 버튼 그룹, 태그 목록 같은 간단한 수평 배치에서 inline-block은 여전히 널리 사용됩니다. 특히 레거시 프로젝트를 유지보수하거나, 이메일 템플릿처럼 최신 레이아웃 기법을 사용할 수 없는 환경에서는 inline-block이 사실상 유일한 선택지가 됩니다. 또한 inline-block의 공백 문제, baseline 정렬 동작, 콘텐츠 기반 크기 조절 같은 특성은 CSS가 인라인 서식 컨텍스트(Inline Formatting Context)에서 어떻게 동작하는지를 이해하는 좋은 출발점이 됩니다. 이러한 원리를 숙지하면 레이아웃이 의도대로 동작하지 않을 때 문제의 근본 원인을 빠르게 진단하고, 상황에 맞는 최적의 display 값을 선택하는 판단력을 기를 수 있습니다.
핵심 개념
Inline, Block, Inline-Block의 차이
입문
웹 페이지의 모든 요소는 화면에 놓이는 방식이 정해져 있어요. 크게 세 가지 방식이 있는데, 각각의 차이를 일상 속 물건으로 비교해 볼게요!
📝 인라인(inline)은 뭔가요? 인라인은 글자처럼 옆으로 쭉 이어지는 방식이에요. 마치 노트에 단어를 쓸 때 한 줄에 여러 단어가 나란히 적히는 것과 같아요. 하지만 단어의 크기(폭이나 높이)를 마음대로 바꿀 수는 없죠. 글자 크기만큼만 자리를 차지해요.
📦 블록(block)은 뭔가요? 블록은 택배 상자처럼 한 줄을 통째로 차지하는 방식이에요. 아무리 작은 상자라도 컨베이어 벨트 위에서는 혼자 한 줄을 독점하죠. 대신 상자의 가로 세로 크기를 자유롭게 정할 수 있어요.
🎁 인라인-블록(inline-block)은요? 인라인-블록은 선물 상자를 선반 위에 나란히 놓는 것과 같아요. 상자이기 때문에 크기를 마음대로 정할 수 있고, 선반 위에 놓이기 때문에 다른 상자들과 나란히 배치될 수 있어요. 인라인의 “나란히 놓기”와 블록의 “크기 조절” 장점을 모두 가진 거예요!
🤔 왜 세 가지가 필요한가요? 웹 페이지를 만들다 보면 글자처럼 흘러가야 할 때도 있고, 상자처럼 영역을 차지해야 할 때도 있어요. 그리고 때로는 상자를 나란히 놓고 싶을 때도 있죠. 각 상황에 맞는 배치 방식이 있기 때문에 세 가지가 모두 필요한 거예요.
중급
CSS의 display 속성은 요소가 레이아웃에 참여하는 방식을 결정합니다. 가장 기본적인 세 가지 값인 inline, block, inline-block의 차이를 이해하는 것이 핵심입니다.
inline 요소의 특성
<span>, <a>, <strong> 등 기본적으로 인라인인 요소는 텍스트 흐름 안에서 나란히 배치됩니다. width와 height 속성이 무시되며, 수직 방향의 margin과 padding은 레이아웃에 영향을 주지 않습니다.
block 요소의 특성
<div>, <p>, <h1> 등 블록 요소는 항상 새 줄에서 시작하며, 부모 요소의 전체 너비를 차지합니다. width, height, margin, padding 모두 정상적으로 적용됩니다.
inline-block의 특성 인라인처럼 나란히 배치되면서도, 블록처럼 모든 박스 모델 속성을 적용할 수 있습니다.
/* inline: 나란히 배치, 크기 지정 불가 */
.inline-element {
display: inline;
width: 200px; /* 무시됨 */
height: 100px; /* 무시됨 */
}
/* block: 줄 독점, 크기 지정 가능 */
.block-element {
display: block;
width: 200px; /* 적용됨 */
height: 100px; /* 적용됨 */
}
/* inline-block: 나란히 배치 + 크기 지정 가능 */
.inline-block-element {
display: inline-block;
width: 200px; /* 적용됨 */
height: 100px; /* 적용됨 */
}
심화
CSS Display Module Level 3 명세는 display 속성의 값을 외부 표시 유형(outer display type)과 내부 표시 유형(inner display type)이라는 두 가지 차원으로 재정의합니다.
CSS Display Module Level 3의 2-값 구문
W3C CSS Display Module Level 3 명세에서는 display 속성이 실제로 두 개의 값을 설정한다고 정의합니다. 외부 표시 유형(outer display type)은 요소가 형제 요소들과 어떻게 배치되는지를, 내부 표시 유형(inner display type)은 자식 요소들이 내부에서 어떻게 배치되는지를 결정합니다.
이 관점에서 전통적인 키워드는 다음과 같이 매핑됩니다:
inline→ outer: inline, inner: flowblock→ outer: block, inner: flowinline-block→ outer: inline, inner: flow-root
따라서 inline-block은 “외부적으로는 인라인 레벨로 참여하되, 내부적으로는 독립적인 블록 서식 컨텍스트(Block Formatting Context, BFC)를 생성하는” 요소입니다.
Block Formatting Context(BFC) 생성의 의미
inline-block이 flow-root를 내부 표시 유형으로 가진다는 것은 새로운 BFC(Block Formatting Context, 블록 서식 컨텍스트)를 생성한다는 의미입니다. BFC는 내부 레이아웃이 외부와 독립적으로 동작하는 격리된 환경입니다.
이로 인해 발생하는 구체적인 효과:
- 마진 병합 차단(Margin Collapsing Prevention):
inline-block내부의 자식 요소 마진이 외부로 전파되지 않습니다. 일반 블록 요소에서는 부모-자식 간 마진이 병합될 수 있지만,inline-block은 BFC 경계에서 이를 차단합니다. - 플로트 격리(Float Containment): 내부에
float된 요소가 있어도inline-block의 높이가 자동으로 플로트를 감싸도록 확장됩니다. 별도의 clearfix 기법이 필요 없습니다.
브라우저 렌더링 파이프라인에서의 처리
Blink(Chrome) 렌더링 엔진에서 inline-block 요소는 인라인 서식 컨텍스트(Inline Formatting Context, IFC) 내에서 원자적 인라인 레벨 박스(atomic inline-level box)로 처리됩니다. “원자적”이란 요소가 줄바꿈 시 내부에서 분할되지 않고 하나의 단위로 취급된다는 의미입니다. 이는 <img>나 <input> 같은 대체 요소(replaced element)와 동일한 방식입니다.
Inline-Block의 박스 모델
입문
인라인-블록 요소는 진짜 상자처럼 크기와 여백을 자유롭게 조절할 수 있어요. 일반 인라인 요소와 어떻게 다른지 알아볼까요!
📏 크기를 정할 수 있어요 보통 인라인 요소(글자처럼 배치되는 것)는 내용물 크기에 딱 맞춰져서 가로 세로를 바꿀 수 없어요. 하지만 인라인-블록은 상자니까요! 가로(너비)와 세로(높이)를 원하는 만큼 정할 수 있어요. 마치 택배 상자 크기를 주문할 때 직접 고르는 것과 같죠.
🧱 안쪽 여백(패딩)이 제대로 작동해요 안쪽 여백은 상자 안에서 내용물과 상자 벽 사이의 빈 공간이에요. 인라인 요소에서는 위아래 안쪽 여백이 다른 줄의 글자와 겹치는 이상한 현상이 생기지만, 인라인-블록에서는 깔끔하게 공간을 확보해요. 선물 상자 안에 충전재를 넣으면 내용물이 벽에서 떨어지는 것처럼요.
📐 바깥 여백(마진)도 모두 적용돼요 바깥 여백은 상자와 다른 물건 사이의 거리예요. 인라인 요소는 좌우 바깥 여백만 먹히고 위아래는 무시되지만, 인라인-블록은 상하좌우 모든 방향의 바깥 여백이 정상적으로 적용돼요.
💡 크기를 안 정하면 어떻게 되나요? 크기를 따로 지정하지 않으면 내용물에 딱 맞게 줄어들어요. 블록 요소는 가로로 쭉 늘어나지만, 인라인-블록은 내용물만큼만 차지해요. 마치 고무줄 상자가 안에 든 물건 크기에 맞춰 조여지는 것과 같아요.
중급
inline-block 요소의 핵심 장점은 인라인 흐름에 참여하면서도 블록 요소와 동일한 박스 모델 속성을 모두 적용할 수 있다는 점입니다.
inline vs inline-block의 박스 모델 차이
inline:width/height무시, 수직margin무시, 수직padding은 시각적으로만 적용(레이아웃에 영향 없음)inline-block:width/height적용, 상하좌우margin/padding모두 정상 적용
<span class="inline-el">인라인</span>
<span class="inline-block-el">인라인블록</span>
.inline-el {
display: inline;
width: 150px; /* 무시됨 */
height: 50px; /* 무시됨 */
margin-top: 20px; /* 무시됨 */
padding-top: 20px; /* 시각적으로만 적용, 레이아웃 영향 없음 */
background: lightblue;
}
.inline-block-el {
display: inline-block;
width: 150px; /* 적용됨 */
height: 50px; /* 적용됨 */
margin-top: 20px; /* 적용됨 */
padding-top: 20px; /* 정상 적용, 레이아웃에도 반영 */
background: lightcoral;
}
shrink-to-fit 너비 동작
inline-block 요소에 width를 지정하지 않으면 콘텐츠에 맞게 너비가 축소됩니다. 이는 블록 요소가 부모의 전체 너비를 차지하는 것과 대조적입니다.
/* block: 부모 너비 100%를 차지 */
.block-el {
display: block;
background: lightblue;
/* width를 지정하지 않으면 부모 너비 전체 차지 */
}
/* inline-block: 콘텐츠 너비에 맞춰 축소 */
.inline-block-el {
display: inline-block;
background: lightcoral;
/* width를 지정하지 않으면 콘텐츠만큼만 차지 */
}
심화
inline-block의 박스 모델 동작은 CSS Box Model Module과 CSS Sizing Module 명세에서 정의하는 크기 결정 알고리즘에 의해 제어됩니다.
CSS Sizing Module의 크기 결정 알고리즘
W3C CSS Sizing Module Level 3에서 inline-block 요소의 기본 너비는 shrink-to-fit 알고리즘으로 결정됩니다. 이 알고리즘의 공식은 다음과 같습니다:
width = min(max(preferred minimum width, available width), preferred width)
- 선호 최소 너비(preferred minimum width): 콘텐츠가 강제 줄바꿈 없이 표시될 수 있는 최소 너비로, 가장 긴 단어나 대체 요소의 고유 너비(intrinsic width)에 해당합니다.
- 사용 가능 너비(available width): 포함 블록(containing block)이 제공하는 가용 공간입니다.
- 선호 너비(preferred width): 줄바꿈 없이 콘텐츠를 한 줄에 표시하기 위해 필요한 너비입니다.
이 공식에 의해 inline-block은 콘텐츠에 맞춰 축소되되, 포함 블록의 가용 너비를 초과하지 않습니다.
인라인 요소에서 수직 padding/margin이 레이아웃에 영향을 주지 않는 이유
CSS 인라인 서식 컨텍스트(Inline Formatting Context)에서 줄 상자(line box)의 높이는 내부 인라인 박스들의 line-height와 vertical-align에 의해 결정됩니다. 인라인 비대체 요소(non-replaced inline element)의 수직 padding, border, margin은 줄 상자 높이 계산에 포함되지 않습니다. 시각적으로 렌더링은 되지만, 줄 상자의 높이에 영향을 미치지 않아 주변 줄과 겹칠 수 있습니다.
반면 inline-block은 원자적 인라인 레벨 박스(atomic inline-level box)이므로, 줄 상자 높이 계산 시 요소의 마진 박스(margin box) 전체 높이가 반영됩니다. 이것이 inline-block에서 수직 margin과 padding이 레이아웃에 정상적으로 영향을 주는 근본적인 이유입니다.
공백 문제와 수직 정렬
입문
인라인-블록 요소를 나란히 놓으면 사이에 이상한 틈이 생기고, 높이가 다르면 정렬이 이상해질 수 있어요. 왜 그런지 알아볼까요!
🔍 왜 사이에 틈이 생기나요? HTML 코드를 작성할 때 엔터(줄바꿈)를 누르면, 브라우저는 그 줄바꿈을 빈 칸 하나로 바꿔요. 마치 글을 쓸 때 단어 사이에 자동으로 띄어쓰기가 들어가는 것과 같아요. 인라인-블록도 글자처럼 취급되기 때문에 이 빈 칸이 요소 사이에 작은 틈으로 나타나는 거예요.
📱 이 틈이 왜 문제가 되나요? 예를 들어 가로 100%를 4등분해서 25%씩 4개의 상자를 나란히 놓으려고 해요. 그런데 틈이 생기면 합계가 100%를 넘어서 마지막 상자가 다음 줄로 밀려 내려가요. 분명 계산은 맞는데 결과가 다르니 당황스럽죠!
⬆️ 높이가 다르면 왜 정렬이 이상해지나요? 키가 다른 친구들이 나란히 서 있다고 생각해 보세요. 보통은 발끝을 맞춰 서겠지만, 인라인-블록은 기본적으로 글자의 밑줄(기준선)에 맞춰 정렬돼요. 그래서 키가 다른 상자들이 밑줄에 맞춰지면 위쪽이 들쭉날쭉해 보이는 거예요.
🛠️ 어떻게 해결하나요? 틈 문제는 HTML에서 줄바꿈을 없애거나, 부모 요소의 글꼴 크기를 0으로 설정하는 방법으로 해결할 수 있어요. 정렬 문제는 “위쪽 맞춤”이나 “가운데 맞춤” 같은 정렬 규칙을 바꿔주면 돼요. 요즘은 이런 번거로움 없이 Flexbox라는 더 편리한 도구도 많이 사용해요.
중급
inline-block 요소를 사용할 때 가장 자주 마주치는 두 가지 문제는 공백 간격(whitespace gap)과 수직 정렬(vertical alignment)입니다.
공백 간격 문제
HTML 소스에서 inline-block 요소 사이의 줄바꿈이나 공백 문자가 약 4px의 시각적 간격으로 렌더링됩니다. 이는 인라인 요소가 텍스트로 취급되기 때문에 단어 사이 공백과 동일하게 처리되는 것입니다.
<!-- 문제: 줄바꿈에 의한 공백 간격 발생 -->
<div class="container">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
<!-- 해결 방법 1: 태그를 붙여 쓰기 -->
<div class="container">
<div class="box">1</div><div class="box">2</div><div class="box">3</div>
</div>
.box {
display: inline-block;
width: 33.33%;
/* 공백 때문에 3개가 한 줄에 들어가지 않음 */
}
/* 해결 방법 2: 부모의 font-size를 0으로 설정 */
.container {
font-size: 0; /* 공백 문자 크기를 0으로 */
}
.container .box {
font-size: 16px; /* 자식에서 폰트 크기 복원 */
}
수직 정렬(vertical-align)
inline-block 요소의 기본 vertical-align 값은 baseline입니다. 이는 요소 내 마지막 줄의 텍스트 기준선에 맞춰 정렬됨을 의미하며, 높이가 다른 요소끼리 배치할 때 예상치 못한 정렬 결과를 만듭니다.
/* 기본값: baseline - 텍스트 기준선 정렬 */
.box {
display: inline-block;
vertical-align: baseline; /* 기본값 */
}
/* 실무에서 자주 사용하는 정렬 방식 */
.box-top {
display: inline-block;
vertical-align: top; /* 줄 상자 상단 정렬 */
}
.box-middle {
display: inline-block;
vertical-align: middle; /* 부모의 x-height 중간에 정렬 */
}
심화
inline-block의 공백 문제와 정렬 동작은 CSS Text Module과 CSS Inline Layout Module 명세에서 정의하는 인라인 서식 컨텍스트(IFC)의 동작 원리에서 비롯됩니다.
공백 처리의 명세적 근거
CSS Text Module Level 3의 공백 처리 규칙(white space processing rules)에 따르면, 연속된 공백과 줄바꿈은 단일 공백 문자로 축소(collapse)됩니다. 이 축소된 공백은 인라인 서식 컨텍스트에서 단어 간 간격(inter-word spacing)으로 렌더링됩니다. inline-block 요소는 인라인 레벨로 참여하므로, 텍스트 노드(text node)와 동일한 공백 처리 규칙의 적용을 받습니다.
이 간격의 실제 크기는 부모 요소의 font-size와 word-spacing 속성에 의해 결정됩니다. font-size: 0이 간격을 제거할 수 있는 이유는 공백 문자의 렌더링 너비가 글꼴 크기에 비례하기 때문입니다.
baseline 정렬의 세부 동작
CSS Inline Layout Module Level 3에서 inline-block의 baseline 정렬은 다음 규칙을 따릅니다:
- 내부에 인라인 서식 컨텍스트가 있고
overflow가visible인 경우: 마지막 줄 상자(last line box)의 기준선을 요소의 기준선으로 사용합니다. - 내부에 줄 상자가 없거나
overflow가visible이 아닌 경우: 요소의 마진 박스 하단 모서리(margin edge)를 기준선으로 사용합니다.
이 규칙 때문에 overflow: hidden이 적용된 inline-block 요소는 기준선이 하단으로 이동하여, 동일한 줄의 다른 요소와 정렬이 어긋나는 현상이 발생합니다. 이는 흔히 겪는 “레이아웃이 갑자기 틀어지는” 문제의 원인 중 하나입니다.
Flexbox가 이 문제들을 해결하는 방식
CSS Flexbox Layout Module에서 display: flex는 자식 요소를 플렉스 아이템(flex item)으로 변환합니다. 플렉스 아이템은 인라인 서식 컨텍스트에 참여하지 않으므로 공백 처리 규칙이 적용되지 않고, align-items 속성으로 직관적인 수직 정렬이 가능합니다. 이것이 현대 CSS에서 inline-block 수평 배치 대신 Flexbox가 권장되는 기술적 근거입니다.