본문 바로가기

박스 모델과 요소 배치

content·padding·border·margin의 크기 계산과 box-sizing을 이해하고 display별 배치 차이를 익힙니다.

앞 글에서는 색상, 글꼴, 텍스트 스타일을 다뤘습니다. 이 글에서는 요소가 화면에서 공간을 차지하는 방식의 바탕인 CSS 박스 모델(box model)을 살펴봅니다. 화면에 보이는 요소의 크기와 여백은 상자(box)로 생각하면 계산할 수 있습니다. 상자를 이루는 네 영역과 그 크기를 정하는 속성, 크기 계산 방식을 바꾸는 box-sizing, 그리고 요소가 배치되는 방식을 정하는 display 속성을 차례로 익힙니다.

box-sizing은 width에 포함할 영역을 바꿉니다

BOX MODEL

box-sizing은 width에 포함할 영역을 바꿉니다

같은 width: 200px, padding: 20px, border: 5px이어도 테두리까지의 폭은 달라집니다. margin은 width에 포함되지 않습니다.

같은 박스의 안팎 포함 관계안에서 밖으로 content, padding, border와 그 바깥 margin의 관계다. margin 외곽은 투명한 윤곽이며 요소의 배경이 아니다. border는 border-box 경계다. 그림의 크기 비율은 정량 수치가 아니다.MARGIN배경 없는 바깥 간격BORDERborder-box 경계PADDING내부 여백CONTENT
같은 박스의 안팎 포함 관계안에서 밖으로 content, padding, border와 그 바깥 margin의 관계다. margin 외곽은 투명한 윤곽이며 요소의 배경이 아니다. border는 border-box 경계다. 그림의 크기 비율은 정량 수치가 아니다.MARGIN배경 없는 바깥 간격BORDERborder-box 경계PADDING내부 여백CONTENT

content-box · 테두리까지 250px

width 200 + 좌우 padding 20×2 + 좌우 border 5×2 = 250px. 콘텐츠 폭은 200px입니다.

border-box · 테두리까지 200px

지정 width 200px 안에 padding과 border를 포함합니다. 콘텐츠 폭은 200−40−10 = 150px입니다.

위 예시의 margin은 별도입니다. 아주 작은 지정 크기에서는 콘텐츠 폭이 0 아래로 줄지 않아 padding·border가 지정 width보다 커질 수 있습니다.

바깥 역할 · block / inline

자신이 normal flow에 참여하는 방식을 정합니다. flex는 block flex, inline-flex는 inline flex의 역할입니다.

안쪽 배치 · flow / flex / grid

자식을 어떤 레이아웃 문맥으로 배치할지 정합니다. 박스 크기 계산과는 별개의 책임입니다.

위 그림은 한 요소의 상자가 안에서 밖으로 내용(content), 안쪽 여백(padding), 테두리(border), 바깥 여백(margin)으로 둘러싸인 관계를 보여 줍니다. 바깥 여백은 배경이 칠해지지 않는 투명한 간격입니다. 그림 아래는 width: 200px, padding: 20px, border: 5px인 같은 상자도 box-sizing에 따라 테두리까지의 폭이 달라진다는 것을 보여 줍니다. 기본값인 content-box에서는 200 + 20 × 2 + 5 × 2 = 250px이고, border-box에서는 지정한 200px 안에 안쪽 여백과 테두리가 들어가 내용 폭이 200 − 40 − 10 = 150px이 됩니다. 두 경우 모두 바깥 여백은 width에 들어가지 않습니다.

그림의 마지막 두 칸은 display가 두 가지 일을 한다는 점을 보여 줍니다. 바깥쪽 역할은 이 요소가 블록이나 인라인으로 주변 흐름에 참여하는 방식을 정하고, 안쪽 배치는 자식 요소를 일반 흐름, Flexbox, Grid 중 어떤 방식으로 놓을지 정합니다. 두 가지는 상자의 크기 계산과 별개의 일입니다.


박스 모델

div, p, img, a 같은 요소는 화면에서 눈에 보이지 않는 사각형 상자로 둘러싸여 있다고 생각할 수 있습니다. 이 상자는 내용, 안쪽 여백, 테두리, 바깥 여백의 네 영역으로 이루어집니다. display: none처럼 상자를 아예 만들지 않는 경우는 뒤의 요소 숨기기에서 따로 살펴봅니다.

내용 영역은 글, 이미지, 비디오처럼 요소의 실제 내용이 들어가는 곳입니다. 기본값인 box-sizing: content-box에서는 width와 height가 이 영역의 크기를 뜻합니다.

안쪽 여백(padding)은 내용과 테두리 사이의 공간으로, 액자 속 그림 둘레의 여백과 같습니다. 요소의 배경색은 안쪽 여백까지 칠해집니다. padding-top, padding-right, padding-bottom, padding-left로 방향마다 정하거나, padding 단축 속성으로 한꺼번에 정합니다. 값을 하나 쓰면 네 방향 모두에, 두 개 쓰면 위아래와 좌우에, 세 개 쓰면 위, 좌우, 아래에, 네 개 쓰면 위에서부터 시계 방향으로 위, 오른쪽, 아래, 왼쪽에 적용됩니다. 예를 들어 padding: 10px 20px은 위아래 10px, 좌우 20px이고, padding: 10px 20px 30px 40px은 위 10px, 오른쪽 20px, 아래 30px, 왼쪽 40px입니다.

테두리(border)는 안쪽 여백을 둘러싼 선입니다. border-width는 두께, border-style은 solid, dotted, dashed, double 같은 모양, border-color는 색이며, border: 1px solid black처럼 단축 속성으로 한 번에 적을 수 있습니다. border-top, border-right, border-bottom, border-left로 방향마다 따로 정할 수도 있습니다. border-style을 정하지 않으면 기본값이 none이라 두께와 색을 줘도 테두리가 보이지 않습니다.

바깥 여백(margin)은 테두리 바깥의 공간으로, 요소와 요소 사이의 간격을 정합니다. 배경색이 칠해지지 않고 투명합니다. margin-top 같은 방향별 속성과 margin 단축 속성은 padding과 같은 규칙으로 씁니다. margin: 0 auto는 위아래 바깥 여백을 0으로, 좌우를 auto로 두는데, 너비가 정해진 블록 요소에서는 남는 가로 공간을 좌우에 똑같이 나눠 요소를 가운데에 놓습니다.

box-sizing: 크기 계산 방식 바꾸기

기본값인 content-box에서는 width와 height가 내용 영역만 뜻하므로, 안쪽 여백과 테두리를 더하면 요소가 지정한 크기보다 커집니다. 테두리까지의 너비는 width + padding-left + padding-right + border-left-width + border-right-width입니다. 이 방식은 레이아웃을 계산하기 어렵게 만듭니다.

border-box로 바꾸면 width와 height가 안쪽 여백과 테두리까지 포함한 크기가 되고, 내용 영역은 그 값에서 안쪽 여백과 테두리를 뺀 나머지가 됩니다. 지정한 크기가 곧 화면에서 차지하는 크기라 예측하기 쉬우므로, 요즘의 CSS 프레임워크와 프로젝트는 대부분 * { box-sizing: border-box; }로 모든 요소의 계산 방식을 바꾸고 시작합니다.

/* 모든 요소에 border-box 적용 */
* {
    box-sizing: border-box;
}

.my-box {
    width: 200px;
    height: 100px;
    padding: 20px;
    border: 5px solid blue;
    /*
    content-box일 경우 실제 너비: 200 + 20*2 + 5*2 = 250px
    border-box일 경우 실제 너비: 200px (패딩과 보더가 200px 안에 포함됨)
    */
}

요소의 실제 크기를 계산할 때는 먼저 box-sizing을 확인하고, 내용, 안쪽 여백, 테두리, 바깥 여백을 나눠 계산합니다. 위에서 말한 너비는 테두리 바깥까지의 폭이며, 다른 요소와의 간격까지 보려면 좌우 바깥 여백을 따로 더합니다. border-box도 바깥 여백은 지정한 너비에 넣지 않습니다. 계산한 값은 개발자 도구의 Elements 패널에서 요소를 고른 뒤 Computed 영역의 상자 그림으로 확인할 수 있습니다.


display: 요소의 배치 방식

모든 HTML 요소에는 display 속성의 기본값이 있고, 이 값이 요소가 화면에 놓이는 방식을 정합니다. CSS로 이 값을 바꾸면 배치 방식도 바뀝니다.

블록 요소

블록(block) 요소는 일반 흐름에서 새 줄에 놓이고, 너비를 정하지 않으면 부모의 가로 폭을 모두 차지합니다. width, height, margin, padding, border를 모두 쓸 수 있습니다. <div>, <h1>부터 <h6>, <p>, <ul>, <li>, <form>, <header>, <footer>, <section>, <article>, <aside>가 대표적인 블록 요소입니다. 나중에 배울 Flexbox나 Grid의 자식이 되거나 위치를 지정하면, 그 배치 방식의 규칙을 따릅니다.

div {
    background-color: lightblue;
    width: 200px; /* 너비를 지정해도 새로운 줄에서 시작 */
    height: 100px;
    margin-bottom: 10px; /* 마진 적용 가능 */
}

이 div는 너비를 200px로 줄여도 옆에 다른 요소가 오지 않고, 다음 요소는 10px 아래의 새 줄에서 시작합니다.

인라인 요소

인라인(inline) 요소는 새 줄을 만들지 않고 글의 흐름을 따라 앞 요소 바로 옆에 놓이며, 내용만큼만 공간을 차지합니다. <span>, <a>, <strong>, <em>, <label>이 대표적입니다. <span> 같은 일반 인라인 요소에는 width와 height가 적용되지 않고 내용에 따라 크기가 정해집니다. 좌우의 margin과 padding은 적용되지만, 위아래 margin은 적용되지 않습니다. 위아래 padding과 border는 그려지기는 하지만 줄의 높이를 늘리지 않아, 위아래 줄과 겹쳐 보일 수 있습니다.

span {
    background-color: lightgreen;
    padding: 5px; /* 좌우 패딩은 적용 */
    margin-right: 5px; /* 좌우 마진은 적용 */
    /* width, height는 적용되지 않음 */
}

<img>와 <input>도 인라인으로 놓이지만 width와 height가 적용됩니다. <img>처럼 요소 바깥의 내용으로 그려지는 대체 요소(replaced element)는 자기 고유의 크기를 가지고, <input> 같은 폼 컨트롤은 브라우저가 처음부터 뒤에서 볼 inline-block 상자로 그리기 때문입니다. 배치는 여전히 글의 흐름을 따릅니다.

인라인 블록 요소

display: inline-block을 주면 인라인 요소처럼 글의 흐름을 따라 옆으로 놓이면서도, 블록 요소처럼 width, height, margin, padding, border를 모두 쓸 수 있습니다. 메뉴 항목, 버튼, 작은 카드처럼 가로로 나열하면서 크기와 여백을 따로 정해야 하는 요소에 씁니다.

.card {
    display: inline-block; /* 옆으로 나열되면서 */
    width: 150px; /* 너비와 높이 지정 가능 */
    height: 180px;
    background-color: #f0f0f0;
    margin: 10px; /* 마진도 자유롭게 */
    padding: 15px;
    border: 1px solid #ddd;
}

.card를 붙인 요소를 여러 개 이어 쓰면 줄 너비가 허락하는 만큼 가로로 놓이고, 자리가 모자라면 다음 줄로 내려갑니다. 이때 HTML에서 요소 사이에 둔 줄 바꿈이 글자 사이의 공백처럼 그려지므로, 카드 사이에 margin보다 조금 넓은 틈이 생기는 것도 흔히 만나는 현상입니다.

요소 숨기기

display: none은 요소를 화면에서 완전히 없애, 공간도 차지하지 않고 상자도 만들지 않습니다. 스크린 리더도 이 요소를 읽지 않습니다. 반면 visibility: hidden은 요소를 보이지 않게만 하고 공간은 그대로 남깁니다.

.hidden-element {
    display: none; /* 요소가 보이지 않고 공간도 차지하지 않음 */
}
.invisible-element {
    visibility: hidden; /* 요소는 보이지 않지만 공간은 차지함 */
}

바깥 여백 상쇄

일반 흐름의 블록 요소에서는 위아래 바깥 여백이 하나로 합쳐지기도 하며, 이를 바깥 여백 상쇄(margin collapsing)라고 합니다. 두 여백이 모두 양수라면 두 값 가운데 큰 값 하나만 간격이 됩니다. 다음 세 경우에 일어납니다.

  • 형제 사이: 위 요소의 margin-bottom과 아래 요소의 margin-top이 만날 때
  • 부모와 자식 사이: 부모의 margin-top과 첫 번째 자식의 margin-top이, 또는 부모의 margin-bottom과 마지막 자식의 margin-bottom이 둘 사이에 안쪽 여백이나 테두리 없이 맞닿을 때. 아래쪽은 부모에 height나 min-height를 정하지 않았을 때만 합쳐집니다.
  • 빈 블록: 안쪽 여백, 테두리, 내용이 없는 블록의 margin-top과 margin-bottom이 만날 때
<div style="margin-bottom: 20px; background-color: lightcoral;">첫 번째 박스</div>
<div style="margin-top: 30px; background-color: lightgreen;">두 번째 박스</div>

이 두 상자 사이의 간격은 20px과 30px을 더한 50px이 아니라, 큰 값인 30px입니다. 예상과 달라 헷갈리기 쉽지만, 문단처럼 위아래에 같은 여백을 둔 요소들이 이어질 때 간격이 두 배로 벌어지지 않게 하려는 의도된 규칙입니다.

부모와 첫 자식 사이의 상쇄는 부모에 padding이나 border를 주면 막을 수 있지만, 이것이 형제 사이의 상쇄까지 막지는 않습니다. 나중에 배울 Flexbox나 Grid 컨테이너의 자식 사이에서는 바깥 여백 상쇄가 일어나지 않습니다.

더 깊이: 상쇄를 막는 블록 서식 맥락

바깥 여백 상쇄는 블록 상자들이 같은 블록 서식 맥락(block formatting context, BFC) 안에서 위아래로 쌓일 때 일어납니다. BFC는 블록 상자를 배치하는 하나의 독립된 구역이라고 생각하면 되며, 문서의 루트인 html이 첫 BFC를 만듭니다. 어떤 요소가 새 BFC를 만들면 그 안과 밖의 여백은 서로 상쇄되지 않으므로, 부모가 새 BFC를 만들면 부모와 첫 자식 사이의 상쇄도 일어나지 않습니다.

새 BFC를 만드는 조건은 여러 가지입니다. float가 있는 요소, position: absolute인 요소, inline-block, 표의 셀, overflow가 visible이나 clip이 아닌 블록, 그리고 그 자신이 다시 Flex나 Grid 컨테이너가 아닌 Flex와 Grid의 아이템이 모두 새 BFC를 만듭니다. 그래서 예전에는 상쇄를 막거나 안쪽의 float를 부모가 감싸게 하려고 overflow: hidden을 자주 썼습니다. 하지만 overflow는 넘치는 내용을 어떻게 다룰지 정하는 속성이라, 원하지 않는 스크롤 막대가 생기거나 그림자가 잘리는 부작용이 따랐습니다.

이 목적만을 위해 생긴 값이 display: flow-root입니다. 다른 동작은 바꾸지 않고 새 BFC만 만들므로, 부모에 display: flow-root를 주면 안쪽 여백이나 테두리를 더하지 않고도 첫 자식과의 상쇄를 막고 안쪽의 float도 감쌀 수 있습니다. BFC를 만드는 전체 조건은 MDN의 블록 서식 맥락 설명에 있습니다.


실습: 제품 목록 페이지

박스 모델과 display를 활용해 제품 목록 페이지를 만들어 봅니다. 다음 구조로 파일을 준비합니다.

products.html
product.css

products.html에는 다음 코드를 씁니다.

products.html
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>박스 모델과 Display 실습 - 제품 목록</title>
    <link rel="stylesheet" href="css/product.css">
</head>
<body>
    <header>
        <h1>우리 가게 인기 상품</h1>
        <p>다양한 제품을 만나보세요!</p>
    </header>

    <main>
        <div class="product-grid">
            <div class="product-item">
                <h3>멋진 제품 A</h3>
                <p>이 제품은 정말 멋집니다. 한 번 사용해 보세요!</p>
                <span class="price">25,000원</span>
                <a href="#" class="buy-button">구매하기</a>
            </div>

            <div class="product-item">
                <h3>매력적인 제품 B</h3>
                <p>당신을 더욱 빛나게 할 아이템입니다.</p>
                <span class="price">40,000원</span>
                <a href="#" class="buy-button">구매하기</a>
            </div>

            <div class="product-item">
                <h3>실용적인 제품 C</h3>
                <p>일상에 편리함을 더해줄 제품!</p>
                <span class="price">15,000원</span>
                <a href="#" class="buy-button">구매하기</a>
            </div>
        </div>

        <div class="info-section">
            <p>더 많은 제품 정보는 <a href="#">제품 안내 페이지</a>에서 확인하세요.</p>
            <span class="contact-info">문의: [email protected]</span>
            <span class="notice-info">공지사항: 배송 지연 안내</span>
        </div>
    </main>

    <footer>
        <p>&copy; 2026 우리 가게. 모든 권리 보유.</p>
    </footer>
</body>
</html>

css/product.css에는 다음 CSS를 씁니다. 제품 카드를 가로로 나열하는 데 쓴 display: flex는 다음 글에서 자세히 배우므로, 지금은 카드 안쪽의 박스 모델과 display에 집중합니다.

css/product.css
/* 모든 요소에 border-box 적용하여 박스 크기 계산을 쉽게 함 */
* {
    box-sizing: border-box;
}

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    margin: 0;
    background-color: #f4f7f6;
    color: #333;
    line-height: 1.6;
}

/* 헤더 스타일 */
header {
    background-color: #4CAF50; /* 초록색 */
    color: white;
    text-align: center;
    padding: 30px 20px;
    margin-bottom: 30px; /* 헤더 아래 여백 */
    box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}

header h1 {
    font-size: 2.8em;
    margin-bottom: 10px; /* h1 아래 여백 */
}

header p {
    font-size: 1.2em;
    margin: 0; /* p 태그 기본 마진 제거 */
}

/* 메인 콘텐츠 영역 */
main {
    max-width: 1000px;
    margin: 0 auto 50px auto; /* 좌우 auto로 중앙 정렬 */
    padding: 20px;
}

/* 제품 목록 (카드를 가로로 나열) */
.product-grid {
    display: flex; /* Flexbox는 다음 글에서 자세히 배우며, 여기서는 카드를 가로로 놓는 데 사용 */
    flex-wrap: wrap; /* 공간이 부족하면 다음 줄로 넘어가도록 함 */
    justify-content: center; /* 가로 중앙 정렬 */
    gap: 30px; /* 카드 사이의 간격 */
    margin-bottom: 40px;
}

/* 각 제품 카드 스타일 */
.product-item {
    width: 280px; /* 각 제품 카드의 고정 너비 */
    background-color: white;
    border: 1px solid #ddd;
    border-radius: 8px;
    padding: 20px;
    text-align: center;
    box-shadow: 0 2px 10px rgba(0,0,0,0.08);
    transition: transform 0.2s ease-in-out; /* 호버 애니메이션 */
}

.product-item:hover {
    transform: translateY(-5px); /* 호버 시 살짝 위로 이동 */
}

.product-item h3 {
    font-size: 1.5em;
    color: #2c3e50;
    margin-bottom: 10px; /* 제목 아래 마진 */
}

.product-item p {
    font-size: 0.95em;
    color: #666;
    margin-bottom: 15px; /* 문단 아래 마진 */
}

/* 가격 (인라인 요소 span을 블록으로) */
.price {
    display: block; /* 인라인 요소였던 span을 블록 요소처럼 동작하게 함 */
    font-size: 1.3em;
    font-weight: bold;
    color: #e67e22; /* 주황색 */
    margin-bottom: 20px; /* 가격 아래 마진 */
}

/* 구매 버튼 (인라인 요소인 a 태그를 인라인 블록으로) */
.buy-button {
    display: inline-block; /* 글의 흐름에 놓이면서 크기와 여백을 가짐 */
    background-color: #3498db; /* 파란색 */
    color: white;
    padding: 10px 25px;
    border-radius: 5px;
    text-decoration: none; /* 밑줄 제거 */
    font-weight: bold;
    transition: background-color 0.3s ease;
}

.buy-button:hover {
    background-color: #2980b9; /* 호버 시 색상 변경 */
}

/* 정보 섹션 */
.info-section {
    text-align: center;
    padding: 20px;
    background-color: #ecf0f1; /* 연한 회색 배경 */
    border-radius: 8px;
    margin-top: 40px;
    box-shadow: 0 2px 5px rgba(0,0,0,0.05);
}

.info-section p {
    margin-bottom: 10px;
}

.info-section a {
    color: #3498db;
    text-decoration: none;
    font-weight: bold;
}

.info-section a:hover {
    text-decoration: underline;
}

/* 인라인 요소들의 배치 (display: inline-block 활용) */
.contact-info, .notice-info {
    display: inline-block; /* 옆으로 나열되면서 패딩, 마진 적용 가능 */
    background-color: #fff;
    padding: 8px 15px;
    border: 1px solid #c9d9e4;
    border-radius: 20px;
    font-size: 0.9em;
    margin: 5px 10px; /* 요소들 간의 간격 */
}

/* 푸터 스타일 */
footer {
    background-color: #2c3e50;
    color: #ecf0f1;
    text-align: center;
    padding: 20px 0;
    margin-top: 30px; /* 푸터 위 여백 */
    font-size: 0.9em;
}

Live Server로 products.html을 열면 세 제품 카드가 흰 상자로 가지런히 놓입니다. 개발자 도구에서 카드 하나를 골라 Computed 영역의 상자 그림을 보면, 내용, 안쪽 여백 20px, 테두리 1px이 어떻게 나뉘었는지 확인할 수 있습니다. 가격(span.price)은 display: block이라 새 줄을 차지하고, 구매하기 버튼(a.buy-button)은 inline-block이라 글의 흐름에 놓이면서도 안쪽 여백만큼 크기를 가집니다.

아래 정보 영역의 .contact-info와 .notice-info는 공간이 충분하면 나란히 놓이고, 화면이 좁으면 다음 줄로 넘어갑니다. inline-block은 한 줄에 고정하는 것이 아니라, 글의 흐름 안에서 자기 상자의 크기를 가지는 방식이기 때문입니다.


정리

  • 요소의 상자는 안에서 밖으로 내용, 안쪽 여백, 테두리, 바깥 여백으로 이루어지며, 배경은 안쪽 여백까지 칠해지고 바깥 여백은 투명합니다.
  • padding과 margin의 단축 속성은 값의 개수에 따라 네 방향, 위아래와 좌우, 위와 좌우와 아래, 시계 방향의 네 값으로 적용됩니다.
  • content-box에서는 width가 내용 영역만, border-box에서는 테두리까지를 뜻하며, 어느 쪽이든 바깥 여백은 따로 더합니다.
  • 블록 요소는 새 줄에서 폭을 채우고, 인라인 요소는 글의 흐름에 놓이며 width와 height가 적용되지 않고, inline-block은 흐름에 놓이면서 크기를 가집니다.
  • display: none은 공간까지 없애고, visibility: hidden은 공간을 남깁니다.
  • 일반 흐름의 블록에서 위아래 바깥 여백이 만나면 큰 값 하나로 합쳐지며, Flexbox와 Grid에서는 합쳐지지 않습니다.

연습 문제

1. 들어가는 상자와 넘치는 상자

width: 200px, 좌우 안쪽 여백 각 20px, 좌우 테두리 각 5px, 좌우 바깥 여백 각 10px인 상자를 가로 260px의 공간에 놓습니다. content-box와 border-box에서 각각 테두리까지의 폭, 내용 폭, 바깥 여백까지 포함한 폭을 구하고, 어느 쪽이 공간에 들어가는지 판단해 보세요.

해설 보기

content-box에서는 내용 폭이 200px, 테두리까지 200 + 40 + 10 = 250px, 바깥 여백까지 270px이므로 260px을 넘습니다. border-box에서는 테두리까지 200px, 내용 폭 200 − 40 − 10 = 150px, 바깥 여백까지 220px이므로 들어갑니다.

넘치는 부분을 overflow: hidden으로 감추는 것으로 계산을 대신하지 말고, 개발자 도구의 상자 그림에서 각 영역의 값을 확인합니다.

2. 제품 카드의 내용 폭

실습의 .product-item은 border-box에 width: 280px, padding: 20px, border: 1px입니다. 카드 안의 글이 쓸 수 있는 내용 폭은 얼마일까요? box-sizing을 content-box로 바꾸면 카드가 화면에서 차지하는 폭은 얼마가 될까요?

해설 보기

border-box에서는 280 − 20 × 2 − 1 × 2 = 238px이 내용 폭입니다.

content-box로 바꾸면 280px이 내용 폭이 되고, 테두리까지의 폭은 280 + 40 + 2 = 322px로 늘어납니다. 그래서 카드 사이의 gap 30px까지 계산하면, 같은 화면에 한 줄로 들어가는 카드 수가 줄어들 수 있습니다.

3. 마진 상쇄 막기

바깥 여백 상쇄 예제의 두 상자를 display: flex와 flex-direction: column을 준 부모로 감쌌습니다. 두 상자 사이의 간격은 얼마가 될까요?

해설 보기

20 + 30 = 50px입니다. Flexbox 컨테이너의 자식 사이에서는 바깥 여백 상쇄가 일어나지 않으므로, 두 여백이 그대로 더해집니다.

일반 흐름에서는 같은 두 상자의 간격이 큰 값인 30px이었습니다. 같은 CSS라도 부모의 배치 방식에 따라 결과가 달라지므로, 간격이 예상과 다르면 부모의 display부터 확인합니다.

다음 글 Flexbox 레이아웃에서는 요소를 한 줄이나 한 열로 나열하고 정렬하는 Flexbox를 자세히 다룹니다.