The box model

김동현·2026년 3월 17일

mdn 학습 번역 - CSS

목록 보기
6/190

블록 박스와 인라인 박스 (Block and inline boxes)

CSS에는 크게 블록 박스(block boxes)인라인 박스(inline boxes)라는 범주로 나뉘는 몇 가지 유형의 박스가 있습니다. 이 '유형(type)'은 박스가 페이지의 흐름(page flow) 속에서 어떻게 동작하는지, 그리고 페이지의 다른 박스들과 어떤 관계를 맺는지를 나타냅니다. 박스들은 내부 디스플레이 유형(inner display type)외부 디스플레이 유형(outer display type)을 가집니다.

일반적으로 display 속성을 사용하여 디스플레이 유형에 다양한 값을 설정할 수 있습니다.

박스의 display 값이 block인 경우:

  • 박스는 새로운 줄(new line)로 줄바꿈되어 시작합니다.
  • widthheight 속성이 존중되어 크기가 적용됩니다.
  • 패딩(Padding), 마진(Margin), 테두리(Border)가 주변의 다른 요소들을 밀어냅니다.
  • width가 지정되지 않은 경우, 박스는 부모 컨테이너에서 사용 가능한 공간을 채우기 위해 인라인(가로) 방향으로 쭉 늘어납니다. 대부분의 경우 박스는 컨테이너만큼 넓어지며, 사용 가능한 공간의 100%를 차지하게 됩니다.

<h1>이나 <p> 같은 일부 HTML 요소들은 기본적으로 외부에 block 디스플레이 유형을 사용합니다.

박스의 디스플레이 유형이 inline인 경우:

  • 박스는 새로운 줄로 줄바꿈되지 않고 글자처럼 흐릅니다.
  • widthheight 속성을 주어도 아무런 효과가 없습니다 (적용되지 않음).
  • 위아래(Top and bottom) 패딩과 테두리는 박스의 크기를 변경시키긴 하지만, 주변 콘텐츠의 위치에는 영향을 주지 않으므로 요소끼리 겹치는 현상(overlapping)이 발생할 수 있습니다.
  • 좌우(Left and right) 패딩, 마진, 테두리는 주변 인라인 콘텐츠의 위치에 영향을 미쳐 주변 글자들을 옆으로 밀어냅니다.

<a>, <span>, <em>, <strong> 같은 일부 HTML 요소들은 기본적으로 외부에 inline 디스플레이 유형을 사용합니다.

블록 및 인라인 레이아웃은 웹에서 요소들이 동작하는 기본 방식입니다. 별도의 지시사항이 없는 한, 박스 안의 요소들은 정상 흐름(normal flow)에 따라 배치되며 블록 또는 인라인 박스로 동작합니다.

💡 강사의 실무 팁!
블록과 인라인을 가장 쉽게 기억하는 방법! 블록(Block)은 '벽돌'입니다. 하나 놓으면 그 옆에 다른 걸 놓을 수 없고 무조건 아래로 쌓이죠. 게다가 가로 길이를 100% 차지하려 듭니다. 반면 인라인(Inline)은 '물 흐르는 글자'입니다. 텍스트 중간에 끼어 들어갈 수 있고, 내용물(텍스트 등)의 크기만큼만 자리를 차지합니다. 너비와 높이를 줘도 듣지 않는 녀석들이죠!


내부와 외부 디스플레이 유형 (Inner and outer display types)

blockinline 디스플레이 값은 외부 디스플레이(outer display) 유형이라고 부릅니다. 이들은 박스가 주변의 다른 박스들과의 관계 속에서 어떻게 배치될지를 결정합니다. 박스들은 또한 해당 박스 '안에 있는' 요소들이 어떻게 배치될지를 결정하는 내부 디스플레이(inner display) 유형도 가지고 있습니다.

내부 디스플레이 값을 설정하여 내부 디스플레이 유형을 변경할 수 있습니다. 예를 들어 display: flex;처럼 말이죠. 이렇게 설정하면 요소 자체는 여전히 외부 디스플레이 유형으로 block을 사용하지만, 내부 디스플레이 유형은 flex로 바뀝니다. 이 박스의 직계 자식들은 플렉스 아이템(flex items)이 되어 Flexbox 스펙에 따라 동작하게 됩니다.

나중에 CSS 레이아웃에 대해 더 자세히 배우게 되면, flex를 비롯해 박스가 가질 수 있는 grid 같은 다양한 다른 내부 값들을 만나게 될 것입니다.

지금은 내부와 외부라는 용어에 너무 얽매이지 않으셔도 됩니다. 이는 내부적으로 일어나는 일을 설명한 것이며, 다른 곳에서 이 용어를 마주칠 경우를 대비해 여기서 언급한 것입니다. 일반적으로는 그냥 단일 display 값만 다루게 될 것이므로 크게 신경 쓰지 않으셔도 괜찮습니다.

💡 강사의 실무 팁!
display: flex;를 줬을 때 헷갈리기 쉬운 부분입니다. display: flex;를 주면 컨테이너 자체는 마치 block처럼 화면 전체 너비를 차지하며 아래로 떨어집니다. 하지만 그 안에 있는 알맹이들은 가로로 나란히(flex 방향에 따라) 정렬되죠. 즉 겉모습은 벽돌(block)인데, 속사정은 유연하다(flex)고 이해하시면 완벽합니다!


다양한 디스플레이 유형 예시 (Examples of different display types)

아래 예제에는 세 개의 다른 HTML 요소가 있으며, 이들 모두 외부 디스플레이 유형으로 block을 가지고 있습니다.

  • CSS로 테두리가 추가된 문단(<p>). 브라우저는 이를 블록 박스로 렌더링합니다. 문단은 새로운 줄에서 시작하며 가로로 쭉 확장되어 사용 가능한 전체 너비를 채웁니다.
  • display: flex를 사용하여 배치된 목록(<ul>). 이는 컨테이너의 자식들을 위한 플렉스 레이아웃을 설정하며, 자식들은 플렉스 아이템이 되어 기본적으로 한 줄(가로 방향)로 배치됩니다. 목록 자체는 블록 박스이므로 — 문단과 마찬가지로 — 컨테이너의 전체 너비로 확장되고 새로운 줄에서 시작합니다.
  • 두 개의 <span> 요소를 내부에 가지고 있는 블록 레벨 문단(<p>). 이 <span> 요소들은 보통 inline이겠지만, 그중 하나에 block이라는 클래스를 주고 display: block으로 설정했습니다. 그 결과, 해당 단어 하나가 부모의 전체 너비를 차지하며 새로운 줄에서 시작하게 됩니다.
<p>I am a paragraph. A short one.</p>
<ul>
  <li>Item One</li>
  <li>Item Two</li>
  <li>Item Three</li>
</ul>
<p>
  I am another paragraph. Some of the <span class="block">words</span> have been
  wrapped in a <span>span element</span>.
</p>
body {
  font-family: sans-serif;
}
p,
ul {
  border: 2px solid rebeccapurple;
  padding: 0.2em;
}

.block,
li {
  border: 2px solid blue;
  padding: 0.2em;
}

ul {
  display: flex;
  list-style: none;
}

.block {
  display: block;
}

다음 예제에서는 inline 요소가 어떻게 동작하는지 볼 수 있습니다.

  • 첫 번째 문단 안에 있는 <span> 요소들은 기본적으로 인라인 요소이므로 강제로 줄바꿈을 만들지 않습니다.
  • display: inline-flex로 설정된 <ul> 요소는 플렉스 아이템들을 포함하는 '인라인 박스'를 생성합니다.
  • 두 문단 모두 display: inline으로 설정되어 있습니다. 이 인라인 플렉스 컨테이너와 문단들은 새로운 줄로 줄바꿈되지 않고(만약 블록 레벨 요소였다면 줄바꿈이 일어났겠지만), 모두 하나의 줄에 이어서 표시됩니다.

디스플레이 모드를 전환하려면 코드를 만져보세요. display: inlinedisplay: block으로 바꾸거나, display: inline-flexdisplay: flex로 변경해보면서 어떻게 달라지는지 확인해보세요.

<p>
  I am a paragraph. Some of the
  <span>words</span> have been wrapped in a <span>span element</span>.
</p>
<ul>
  <li>Item One</li>
  <li>Item Two</li>
  <li>Item Three</li>
</ul>
<p class="inline">I am a paragraph. A short one.</p>
<p class="inline">I am another paragraph. Also a short one.</p>
body {
  font-family: sans-serif;
}
p,
ul {
  border: 2px solid rebeccapurple;
}

span,
li {
  border: 2px solid blue;
}

ul {
  display: inline-flex;
  list-style: none;
  padding: 0;
}

.inline {
  display: inline;
}

지금 당장 기억해야 할 핵심은 이것입니다. display 속성의 값을 변경하면 박스의 외부 디스플레이 유형을 블록이나 인라인으로 바꿀 수 있다는 것. 그리고 이로 인해 레이아웃 내에서 다른 요소들과 나란히 표시되는 방식이 달라진다는 점입니다.


CSS 박스 모델이란? (What is the CSS box model?)

CSS 박스 모델은 전체적으로 블록 박스에 적용되며, 박스의 각기 다른 부분들 — 마진(margin), 테두리(border), 패딩(padding), 그리고 콘텐츠(content) — 이 어떻게 함께 작동하여 페이지에서 볼 수 있는 하나의 박스를 만들어내는지를 정의합니다. 인라인 박스의 경우에는 박스 모델에서 정의된 동작 중 일부만 사용합니다.

상황을 조금 더 복잡하게 만드는 것은, 박스 모델에 표준(standard) 모델과 대체(alternate) 모델 두 가지가 있다는 점입니다. 브라우저는 기본적으로 표준 박스 모델을 사용합니다.

박스의 구성 요소 (Parts of a box)

CSS에서 블록 박스를 구성하는 요소는 다음과 같습니다:

  • 콘텐츠 박스 (Content box): 여러분의 내용물(텍스트, 이미지 등)이 표시되는 실제 영역입니다. widthheight 같은 속성을 사용해 크기를 조절합니다.
  • 패딩 박스 (Padding box): 콘텐츠 주위를 감싸는 여백(빈 공간)입니다. padding 및 관련 속성들로 크기를 조절합니다.
  • 테두리 박스 (Border box): 콘텐츠와 패딩을 감싸는 테두리 선입니다. border 및 관련 속성들로 크기와 스타일을 조절합니다.
  • 마진 박스 (Margin box): 가장 바깥쪽 레이어로, 콘텐츠, 패딩, 테두리 전체를 감싸며 이 박스와 다른 요소 사이의 빈 공간(거리)을 만듭니다. margin 및 관련 속성들로 크기를 조절합니다.

아래 다이어그램은 이 레이어 구조를 보여줍니다:

박스 모델 다이어그램

💡 강사의 실무 팁!
마진과 패딩을 은근히 헷갈려하시는 분들이 많은데요. 패딩(Padding)은 내 몸을 키우는 살점(안쪽 여백)이고, 마진(Margin)은 다른 사람과 거리두기를 하는 간격(바깥쪽 여백)이라고 생각하세요! 패딩을 주면 내 박스 자체가 뚱뚱해지지만, 마진을 주면 내 박스 크기는 그대로인데 옆 요소가 저 멀리 밀려납니다.

표준 CSS 박스 모델 (The standard CSS box model)

표준 박스 모델에서 박스에 widthheight 속성값을 설정하면, 이 값들은 오직 콘텐츠 박스(content box)의 너비와 높이만을 정의합니다. 그리고 추가로 부여한 패딩과 테두리의 크기가 이 콘텐츠 크기에 더해져서 박스가 차지하는 전체 크기(total size)가 결정됩니다. (아래 이미지 참고)

박스에 다음과 같은 CSS가 적용되어 있다고 가정해 보겠습니다:

.box {
  width: 350px;
  height: 150px;
  margin: 10px;
  padding: 25px;
  border: 5px solid black;
}

이 박스가 페이지에서 실제로 차지하는 공간의 크기는 너비 410px (콘텐츠 350 + 좌우 패딩 25+25 + 좌우 테두리 5+5)이고, 높이는 210px (콘텐츠 150 + 상하 패딩 25+25 + 상하 테두리 5+5)가 됩니다.

표준 박스 모델을 사용할 때 박스의 크기

📝 참고사항 (Note):
마진(Margin)은 박스의 실제 크기에 합산되지 않습니다. 물론 마진이 페이지 상에서 박스가 차지하는 총 공간에 영향을 미치긴 하지만, 이는 어디까지나 박스 '외부'의 공간일 뿐입니다. 박스 자체의 면적은 테두리(border)에서 끝납니다. 마진 영역으로 박스가 확장되는 것은 아닙니다.

대체 CSS 박스 모델 (The alternative CSS box model)

대체 박스 모델에서는 지정한 너비(width) 값이 페이지에 표시되는 보이는 박스 전체의 너비가 됩니다. 즉, 콘텐츠 영역의 너비는 여러분이 지정한 전체 너비에서 패딩과 테두리의 너비를 뺀 값이 됩니다. (아래 이미지 참조) 이 모델은 박스의 실제 크기를 구하기 위해 테두리와 패딩 수치를 더할 필요가 없어서 매우 편리합니다.

요소에 이 대체 모델을 켜려면, 요소에 box-sizing: border-box를 설정해주면 됩니다:

.box {
  box-sizing: border-box;
}

아까와 똑같은 CSS가 이 박스에 적용되었다고 해봅시다:

.box {
  width: 350px;
  height: 150px;
  margin: 10px;
  padding: 25px;
  border: 5px solid black;
}

이제 이 박스가 실제로 차지하는 공간은 인라인(가로) 방향으로 딱 350px, 블록(세로) 방향으로 딱 150px가 됩니다. (우리가 처음 지정한 width, height 크기 그대로 유지되는 것이죠!)

대체 박스 모델을 사용할 때 박스의 크기

모든 요소에 이 대체 박스 모델을 사용하려면 (현업 개발자들 사이에서 아주 흔하고 필수적인 선택입니다), 요소에 box-sizing 속성을 설정하고, 다른 모든 요소들이 그 값을 상속(inherit)받도록 설정하면 됩니다:

html {
  box-sizing: border-box;
}

*,
*::before,
*::after {
  box-sizing: inherit;
}

💡 강사의 실무 팁!
"가로 100% 짜리 헤더를 만들었는데 자꾸 가로 스크롤이 생겨서 페이지가 흔들려요!" 초보 프론트엔드 개발자들이 가장 많이 겪는 눈물의 에러입니다. 가로 100%에 패딩을 10px 주면 실제 크기가 100% + 20px이 되어서 브라우저 창을 뚫고 나가버리거든요.

그래서 실무에서는 프로젝트를 시작할 때 무조건 위 코드 블록처럼 모든 요소에 box-sizing: border-box;를 적용하고 시작합니다. 이 설정을 기본으로 깔고 가는 것이 정신 건강과 완벽한 레이아웃에 큰 도움이 됩니다. 면접에서도 "box-sizing: border-box의 역할이 무엇인가요?"는 단골 질문이니 꼭 외워두세요!

그 이면의 아이디어를 이해하고 싶다면, CSS Tricks의 box-sizing 관련 기사를 읽어보시길 권합니다. (외부 링크)


박스 모델 가지고 놀기 (Playing with box models)

아래 예제에는 두 개의 박스가 있습니다. 둘 다 .box라는 클래스를 가지고 있어서 동일한 width, height, margin, border, padding을 적용받고 있습니다. 유일한 차이점은 두 번째 박스가 대체 박스 모델(border-box)을 사용하도록 설정되었다는 것입니다.

.alternate 클래스에 CSS를 추가해서 두 번째 박스의 크기를 첫 번째 박스의 너비와 높이와 똑같아지도록 변경해 보실 수 있나요? (수학 계산이 조금 필요합니다!)

<div class="box">I use the standard box model.</div>
<div class="box alternate">I use the alternate box model.</div>
.box {
  border: 5px solid rebeccapurple;
  background-color: lightgray;
  padding: 40px;
  margin: 40px;
  width: 300px;
  height: 150px;
}

.alternate {
  box-sizing: border-box;
}

📝 참고사항 (Note):
이 연습 문제의 정답은 저희 css-examples 저장소에서 확인하실 수 있습니다. (외부 링크)

브라우저 개발자 도구를 사용하여 박스 모델 확인하기 (Using browser DevTools to view the box model)

여러분의 브라우저 개발자 도구(browser developer tools)를 사용하면 박스 모델을 훨씬 더 쉽게 이해할 수 있습니다. 개발자 도구는 요소의 크기와 함께 여백(margin), 패딩(padding), 테두리(border) 수치를 모두 시각적으로 보여줍니다. 이 방식으로 요소를 검사(Inspect)해 보는 것은 내 박스가 진짜로 내가 생각한 크기로 나오고 있는지 확인하는 가장 좋은 방법입니다!

Firefox 개발자 도구를 사용해 요소의 박스 모델을 검사하는 모습

💡 강사의 실무 팁!
"단축키 F12 (또는 Ctrl+Shift+I / Cmd+Option+I)"
프론트엔드 개발자라면 마우스보다 키보드로 이 단축키를 누르는 횟수가 더 많을 겁니다. 화면 구조가 이상하게 틀어졌다면 CSS 코드를 뚫어져라 쳐다보지 마시고, 바로 개발자 도구를 열어서 해당 요소를 찍어보세요. 대부분의 버그는 개발자 도구 박스 모델 패널에서 빨갛게(마진), 초록색(패딩)으로 칠해진 영역을 보는 순간 5초 만에 해결됩니다.


마진, 패딩, 테두리 (Margins, padding, and borders)

위 예제들에서 이미 margin, padding, border 속성이 작동하는 걸 보셨을 겁니다. 해당 예제에서 사용된 속성들은 단축 속성(shorthands)으로, 박스의 네 면을 한 번에 모두 설정할 수 있게 해줍니다. 이 단축 속성들은 동등한 풀이 속성(longhand properties)도 가지고 있어서, 박스의 각 면을 개별적으로 통제할 수도 있습니다.

이 속성들에 대해 좀 더 자세히 알아봅시다.

마진 (Margin)

마진(여백)은 박스 주변에 있는 눈에 보이지 않는 공간입니다. 박스로부터 다른 요소들을 밀어내는 역할을 하죠. 마진은 양수 값뿐만 아니라 음수(negative) 값도 가질 수 있습니다. 박스의 한쪽 면에 음수 마진을 설정하면, 페이지의 다른 요소들과 의도적으로 겹치게(overlap) 만들 수도 있습니다. 여러분이 표준 박스 모델을 쓰든 대체 박스 모델을 쓰든 상관없이, 마진은 항상 눈에 보이는 박스의 크기 계산이 모두 끝난 후에 그 외부에 추가됩니다.

우리는 margin 속성을 사용해 요소의 모든 마진을 한 번에 제어하거나, 다음과 같은 개별 속성들로 각 면을 따로따로 제어할 수 있습니다:

마진 가지고 놀기 (Playing with margins)

아래 예제를 수정해 보세요. 마진 값을 다양하게 바꿔보면서, 이 요소와 겉을 감싸고 있는 컨테이너 요소 사이에 마진이 공간을 어떻게 만들고 없애는지(음수 마진의 경우) 관찰해 보세요. 박스가 어떻게 이리저리 밀리는지 알 수 있습니다.

<div class="container">
  <div class="box">Change my margin.</div>
</div>
.container {
  border: 5px solid blue;
  margin: 40px;
}

.box {
  border: 5px solid rebeccapurple;
  background-color: lightgray;
  padding: 10px;
  height: 100px;
  /* try changing the margin properties: */
  margin-top: -40px;
  margin-right: 30px;
  margin-bottom: 40px;
  margin-left: 4em;
}

마진 상쇄 현상 (Margin collapsing)

두 요소의 마진이 서로 맞닿을 때, 그 마진들이 양수인지 음수인지에 따라 결과가 확 달라집니다:

  • 두 개의 양수 마진이 만나면, 두 마진은 하나로 합쳐집니다(병합됩니다). 이때 크기는 두 마진 중 더 큰 쪽의 값과 같아집니다.
  • 두 개의 음수 마진이 만나면 상쇄되며, 둘 중 0에서 더 먼 값(더 작은 음수, 즉 절댓값이 더 큰 쪽)이 사용됩니다.
  • 하나의 마진이 음수인 경우, 양수 값에서 음수 값이 빼기(subtract) 계산되어 총합이 됩니다.

아래 예제에는 두 개의 문단이 있습니다. 위쪽 문단은 margin-bottom이 50픽셀이고, 아래쪽 문단은 margin-top이 30픽셀입니다. 두 마진이 더해져서 80픽셀이 되어야 할 것 같지만, 마진 상쇄 현상 때문에 두 박스 사이의 실제 공간은 두 마진의 총합이 아닌 50픽셀이 됩니다. (둘 중 더 큰 값 적용)

직접 확인해보고 싶다면 두 번째 문단의 margin-top0으로 바꿔보세요. 두 문단 사이의 보이는 간격은 변하지 않을 겁니다. 첫 번째 문단이 가진 50픽셀의 margin-bottom이 그대로 유지되기 때문이죠. 만약 두 번째 문단의 margin-top-10px로 주면, 50에서 10을 뺀 40px로 총 마진이 변하는 걸 볼 수 있습니다.

<div class="container">
  <p class="one">I am paragraph one.</p>
  <p class="two">I am paragraph two.</p>
</div>
.container {
  border: 5px solid blue;
  margin: 40px;
}

p {
  border: 5px solid rebeccapurple;
  background-color: lightgray;
  padding: 10px;
}
.one {
  margin-bottom: 50px;
}

.two {
  margin-top: 30px;
}

💡 강사의 실무 팁! (매우 중요)
마진 상쇄(Margin Collapsing) 현상은 프론트엔드 개발 면접에 단골로 등장하는 핵심 질문입니다!

꼭 기억해야 할 사실: 마진 상쇄 현상은 오직 "블록(Block) 요소의 위(top)와 아래(bottom) 마진에서만" 발생합니다. 좌우(left, right) 마진은 서로 합쳐지지 않습니다. 게다가 만약 부모 요소가 display: flex;display: grid;라면 그 내부의 아이템들은 더 이상 마진 상쇄를 겪지 않고 곧이곧대로 값이 다 더해집니다. 이 점을 이해하면 레이아웃을 짤 때 불필요한 공백 때문에 받는 스트레스가 절반으로 줄어들 거예요!

언제 마진 상쇄가 발생하고 발생하지 않는지를 결정하는 데에는 여러 가지 규칙이 있습니다. 자세한 내용은 마진 상쇄 완전 정복(mastering margin collapsing) 페이지를 참고하세요. 가장 중요한 핵심은, 마진으로 공간을 만들려고 했는데 생각한 대로 여백이 생기지 않는다면 '아, 이게 그 마진 상쇄 현상이구나!' 하고 깨닫는 것입니다.

📝 참고사항 (Note):
Scrimba의 깃발을 통한 마진 학습(Learn margins via flags) MDN 학습 파트너라는 인터랙티브 레슨에서 마진을 다루는 유용한 연습을 해볼 수 있습니다.

테두리 (Borders)

테두리(border)는 박스의 마진과 패딩 사이에 그려지는 선입니다. 표준 박스 모델을 사용 중이라면 테두리의 두께는 콘텐츠 박스의 widthheight에 추가로 더해집니다. 하지만 대체 박스 모델(border-box)을 사용 중이라면, 테두리가 두꺼워질수록 콘텐츠 영역이 사용할 수 있는 크기가 줄어들게 됩니다. (우리가 처음 지정해 둔 전체 widthheight 크기를 유지하기 위해 테두리가 안쪽으로 파고들기 때문이죠.)

테두리를 꾸미기 위한 속성은 아주 다양합니다. 4개의 면이 있고, 각 면마다 스타일, 두께, 색상을 마음대로 조작할 수 있거든요.

border 속성을 사용하면 네 면의 두께, 스타일, 색상을 단번에 한 줄로 설정할 수 있습니다.

각 면의 속성을 개별적으로 설정하려면 다음을 사용합니다:

네 면 전체의 두께, 스타일, 색상 중 특정 '특성'만 설정하려면 다음을 사용합니다:

특정 면(예: 윗면)의 특정 특성(예: 색상) 하나만 콕 집어서 세밀하게 설정하고 싶다면 가장 구체적인 속성을 사용합니다:

테두리 가지고 놀기 (Playing with borders)

아래 예제에서는 테두리를 만들기 위해 단축 속성과 개별 속성을 다양하게 섞어서 사용해 봤습니다. 값들을 이리저리 수정해 보면서 어떻게 작동하는지 확인해 보세요. border 속성에 대한 MDN 페이지를 찾아보시면 solid, dashed, dotted, double 등 사용할 수 있는 다양한 테두리 스타일 정보도 얻을 수 있습니다.

<div class="container">
  <div class="box">Change my borders.</div>
</div>
body {
  font-family: sans-serif;
}
.container {
  margin: 40px;
  padding: 20px;
  border-top: 5px dotted green;
  border-right: 1px solid black;
  border-bottom: 20px double rgb(23 45 145);
}

.box {
  padding: 20px;
  background-color: lightgray;
  border: 1px solid #333333;
  border-top-style: dotted;
  border-right-width: 20px;
  border-bottom-color: hotpink;
}

패딩 (Padding)

패딩(Padding)은 테두리와 콘텐츠 영역 사이에 위치하며, 콘텐츠를 테두리 선으로부터 안쪽으로 밀어 넣기(띄워주기) 위해 사용됩니다. 마진과 달리 패딩에는 음수 값을 줄 수 없습니다. 요소에 배경색이나 배경 이미지를 적용했다면, 그 배경은 패딩 영역 아래까지 꽉 차게 표시됩니다.

padding 단축 속성은 요소의 네 면 모두에 대한 패딩을 한 번에 제어합니다. 각 면을 따로 제어하려면 개별 속성들을 사용합니다:

패딩 가지고 놀기 (Playing with padding)

아래 예제에서 .box 클래스의 패딩 값을 수정해 보면서, 박스의 테두리와 실제 글자가 시작되는 부분 사이의 공간이 어떻게 변하는지 관찰해 보세요.
또한 .container 클래스에 있는 패딩을 변경하면 컨테이너의 테두리와 그 안에 있는 박스 사이에 어떻게 공간이 생기는지 확인하실 수 있습니다. 어떤 요소에든 패딩을 변경하면 '해당 요소의 테두리'와 '그 안에 들어있는 알맹이' 사이의 거리를 넓히거나 좁힐 수 있습니다.

<div class="container">
  <div class="box">Change my padding.</div>
</div>
body {
  font-family: sans-serif;
}
.box {
  border: 5px solid rebeccapurple;
  background-color: lightgray;
  padding-top: 0;
  padding-right: 30px;
  padding-bottom: 40px;
  padding-left: 4em;
}

.container {
  border: 5px solid blue;
  margin: 40px;
  padding: 20px;
}

박스 모델과 인라인 박스 (The box model and inline boxes)

지금까지 살펴본 모든 내용은 블록 박스에 100% 적용되는 개념입니다. 하지만 패딩, 테두리, 마진 같은 속성 중 일부는 <span> 같은 요소가 만드는 인라인 박스에도 적용될 수는 있습니다. (단, 동작 방식이 조금 다릅니다!)

아래 예제를 보면 문단 안에 <span> 요소가 들어있습니다. 이 <span>width, height, margin, border, padding을 모두 줘봤어요.
결과를 보시면 width, height, 그리고 상하(top, bottom) 마진<span>에 전혀 영향을 주지 못합니다.
반면에 상하 패딩과 상하 테두리는 인라인 박스의 크기를 늘려놓긴 하지만 주변 요소들의 줄 간격이나 위치를 전혀 밀어내지 못합니다. 오히려 문단 내의 다른 글자들을 위아래로 가려버리고 겹치는 불상사를 만들죠. 오직 좌우(left, right) 패딩, 마진, 테두리만이 해당 <span> 주변에 있는 텍스트들을 양옆으로 밀어내어 공간을 만듭니다.

<p>
  I am a paragraph and this is a <span>span</span> inside that paragraph. A span
  is an inline element and so does not respect width and height.
</p>
body {
  font-family: sans-serif;
}
p {
  border: 2px solid rebeccapurple;
  width: 200px;
}
span {
  margin: 20px 30px;
  padding: 10px 20px;
  width: 80px;
  height: 150px;
  background-color: lightblue;
  border: solid blue;
  border-width: 7px 1px;
}

display: inline-block 사용하기 (Using display: inline-block)

display: inline-blockdisplay 속성에 줄 수 있는 아주 특별한 값으로, inlineblock의 성질을 반씩 섞어놓은 훌륭한 타협점을 제공합니다. 요소를 새로운 줄로 떨어뜨리고 싶지는 않지만, widthheight 값을 먹게 하고 싶고 위에서 본 끔찍한 겹침 현상(overlap)도 방지하고 싶을 때 바로 이 속성을 쓰면 됩니다.

display: inline-block이 적용된 요소는 우리가 이미 배운 블록(block)의 성질 중 일부를 수행합니다:

  • widthheight 속성이 존중되어 크기가 늘어납니다.
  • padding, margin, border가 다른 요소들을 정상적으로 밖으로 밀어냅니다.

하지만 블록처럼 새로운 줄로 뚝 떨어지지 않고 인라인 요소처럼 글자 옆에 얌전히 나란히 붙어있습니다. 또한 부모의 너비를 100% 다 채우려고 하지도 않고, 여러분이 명시적으로 widthheight를 지정했을 때만 내부 콘텐츠보다 커지게 됩니다.

inline-block 가지고 놀기 (Playing with inline-block)

이번 예제에서는 방금 전의 <span> 요소에 display: inline-block을 띡 추가해 주었습니다. 이 한 줄을 display: block으로 바꿔보거나 아예 지워버리면서 화면 표시 모델이 어떻게 달라지는지 확연한 차이를 느껴보세요.

<p>
  I am a paragraph and this is a <span>span</span> inside that paragraph. A span
  is an inline element and so does not respect width and height.
</p>
body {
  font-family: sans-serif;
}
p {
  border: 2px solid rebeccapurple;
  width: 300px;
}

span {
  margin: 20px;
  padding: 20px;
  width: 80px;
  height: 50px;
  background-color: lightblue;
  border: 2px solid blue;
  display: inline-block;
}

이 속성이 진짜 빛을 발하는 순간은, <a> 링를 버튼처럼 만들고 싶어서 padding을 더해 클릭 영역을 넓히려 할 때입니다. <a> 요소는 <span>과 같은 전형적인 인라인 요소이므로, 그냥 패딩을 주면 다른 줄을 침범해버리죠. 이때 display: inline-block을 주면 패딩과 크기가 제대로 먹히면서 사용자가 클릭하기 아주 좋은 예쁜 버튼을 나란히 배열할 수 있습니다.

웹사이트 내비게이션 바에서 이런 패턴을 아주 흔하게 보실 수 있습니다. 아래 내비게이션은 플렉스박스(flexbox)를 사용해 가로로 배치된 상태입니다. 여기서 우리는 <a> 요소에 마우스를 올렸을 때(hover) background-color를 예쁘게 채우기 위해 패딩을 듬뿍 주었습니다. 그런데 이 패딩이 부모인 <ul> 요소의 윗선을 비집고 튀어나가는 현상이 보입니다. 왜일까요? <a>가 인라인 요소이기 때문입니다.

.links-list a 선택자 규칙 안에 display: inline-block;을 추가해 보세요. 짜잔! 튀어나갔던 패딩이 정상적으로 주변 요소들을 밀어내면서 완벽하게 고쳐지는 것을 확인하실 수 있습니다.

<nav>
  <ul class="links-list">
    <li><a href="">Link one</a></li>
    <li><a href="">Link two</a></li>
    <li><a href="">Link three</a></li>
  </ul>
</nav>
ul {
  font-family: sans-serif;
  display: flex;
  list-style: none;
  border: 1px solid black;
}

li {
  margin: 5px;
}

.links-list a {
  background-color: rgb(179 57 81);
  color: white;
  text-decoration: none;
  padding: 1em 2em;
}

.links-list a:hover {
  background-color: rgb(66 28 40);
  color: white;
}

💡 강사의 실무 팁!
최근에는 display: flex;가 너무 강력해서 가로 배치를 할 때 플렉스박스 하나로 다 해결하는 추세이긴 합니다. 하지만 여전히 텍스트 흐름 중간에 들어가는 배지(Badge)나 소형 아이콘, 버튼 등을 처리할 때는 이 inline-block이 최고 효율을 발휘합니다. 꼭 자유자재로 다루실 수 있어야 해요!


요약 (Summary)

이 정도면 박스 모델에 대해 알아야 할 대부분의 핵심을 파악하셨습니다. 나중에 여러분이 직접 짠 레이아웃에서 "도대체 내 박스 크기가 왜 이 모양이야?"라며 혼란에 빠졌을 때, 이 레슨으로 돌아와 다시 한번 개념을 복습해 보시면 큰 도움이 될 것입니다.

profile
프론트에_가까운_풀스택_개발자

0개의 댓글