• 포스트
  • 도구
  • 작업
  • 포스트
  • 도구
  • 작업
로그인회원가입

© 2005 kaisa.co.kr. All Rights Reserved.

소개개인정보처리방침7083620@hanmail.net
← 목록으로
2023-11-15

CSS 박스 모델과 display 기초

CSS 박스 모델과 display 기초

요약: 박스가 content·padding·border·margin으로 어떻게 커지는지와 display가 흐름을 어떻게 바꾸는지 구분해 레이아웃을 계산한다.


언제 박스 모델을 먼저 보는가

CSS(캐스케이딩 스타일시트)에서 모든 요소는 사각형 박스로 그려진다. 너비가 안 맞거나 간격이 겹치면 장식이 아니라 박스 계산을 의심한다.

레이아웃을 잡기 전에 두 가지만 고정한다. 이 박스의 너비에 padding과 border가 포함되는가. 이 박스는 한 줄을 차지하는가, 글자처럼 흐르는가.


박스는 네 겹이다

안에서 바깥으로 content, padding, border, margin이다.

margin          ← 이웃 박스와의 바깥 간격. 배경이 없다
  border        ← 테두리. width에 포함할지 box-sizing이 정한다
    padding     ← 내용과 테두리 사이 안쪽 여백
      content   ← 텍스트·이미지·자식이 들어가는 영역

기본값 content-box에서는 width: 200px이 content만 200px이다. padding 16px와 border 1px를 더하면 화면에 234px가 된다. 옆 박스가 밀려 난다.

border-box면 width에 padding과 border가 포함된다. 200px이라고 쓰면 테두리까지 합쳐 200px이다. 계산이 예측 가능하다.

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

프로젝트 전역에 이 한 줄을 둔다. 컴포넌트마다 box-sizing을 바꾸지 않는다.


display가 흐름을 정한다

display는 박스가 이웃과 어떻게 줄을 서는지를 정한다.

값 동작 쓸 때
block 가로를 한 줄 차지하고 위아래로 쌓인다 문단, 섹션, 카드
inline 글자처럼 옆에 붙는다. width·height가 거의 안 먹는다 문장 속 강조, 링크
inline-block 옆에 붙으면서 박스 크기를 지정한다 뱃지, 작은 버튼 나열
none 그리지도 않고 자리도 없앤다 닫힌 메뉴, 숨긴 영역
flex / grid 자식 배치용 컨텍스트를 연다 다음 글에서 다룬다

visibility: hidden은 안 보이지만 자리는 남긴다. display: none은 자리까지 없앤다. 레이아웃이 당겨지면 none이고, 자리만 비워 두면 hidden이다.

.badge {
  display: inline-block;
  padding: 0.25rem 0.5rem;
  border: 1px solid #ccc;
}

.is-closed {
  display: none;
}

카드 한 장으로 계산해 보기

<article class="card">
  <h2>제목</h2>
  <p>본문</p>
</article>
*,
*::before,
*::after {
  box-sizing: border-box;
}

.card {
  width: 320px;
  padding: 16px;
  border: 1px solid #ddd;
  margin: 16px;
}

border-box이므로 테두리까지 합쳐 가로 320px이다. 바깥으로 16px 간격이 더해진다. content-box였다면 padding·border만큼 더 넓어져 옆 카드와 줄이 안 맞는다.

이미지가 부모를 넘치지 않게 하는 최소 리셋이다.

html {
  line-height: 1.5;
}

body {
  margin: 0;
}

img,
svg {
  max-width: 100%;
  height: auto;
  display: block;
}

body의 기본 margin을 0으로 두지 않으면 페이지 가장자리에 예상 못 한 여백이 생긴다. img를 block으로 두면 인라인 이미지 아래 틈이 사라진다.


세로 margin이 합쳐지는 이유

인접한 block끼리는 위아래 margin이 더해지지 않고 큰 쪽만 남는다. 이를 margin collapse(마진 병합)라고 한다.

부모의 첫 자식 margin-top이 부모 밖으로 새어 나가기도 한다. 부모에 padding이나 border를 두면 막힌다. overflow를 auto로 두는 방법도 있다.

컴포넌트 사이 간격은 각자 margin을 쌓기보다 부모의 gap으로 통일하는 편이 덜 겹친다. Flexbox나 Grid에서 gap을 쓴다.


흔한 실수

  • width: 100%에 padding을 더하고 가로 스크롤이 생긴다. border-box인지 확인한다.
  • inline 요소에 width·height를 준다. inline-block이나 block으로 바꾼다.
  • 숨길 때 display: none과 visibility: hidden을 혼동한다. 자리가 필요하면 hidden이다.
  • 세로 간격이 의도의 절반만 나온다. margin collapse를 의심한다.
  • 전체 태그 리셋으로 ul·button까지 지운다. 팀이 합의한 최소 세트만 둔다.

정리

레이아웃 버그의 상당수는 박스 크기와 display 오해에서 온다. 먼저 이 박스가 몇 픽셀인지, 한 줄을 차지하는지부터 본다. border-box를 전역으로 두고 나면 나머지는 간격과 흐름이다.


연습

  1. 같은 카드에 content-box와 border-box를 번갈아 적용하고 개발자 도구에서 실제 너비를 비교한다.
  2. inline 링크 세 개에 padding을 준 뒤, inline-block으로 바꿨을 때 줄 높이가 어떻게 달라지는지 본다.
  3. 부모·자식에 margin-top: 20px을 각각 주고, 화면에 40px가 아니라 20px만 생기는지 확인한다.

댓글

0

아직 댓글이 없습니다. 첫 댓글을 남겨보세요.

이전 글시맨틱 HTML로 문서 뼈대 잡기다음 글Flexbox로 한 줄 레이아웃 잡기
← 목록으로