Sizing items in CSS

김동현·2026년 3월 18일

mdn 학습 번역 - CSS

목록 보기
9/190

사물의 자연스러운 크기, 또는 본질적 크기 (The natural or intrinsic size of things)

HTML 요소들은 CSS의 영향을 받기 전부터 이미 자신만의 자연스러운 크기를 가지고 있습니다. 가장 직관적인 예가 바로 이미지입니다. 이미지 파일은 그 자체로 크기 정보를 포함하고 있는데, 이를 본질적 크기(intrinsic size)라고 부릅니다. 이 크기는 우리가 CSS로 적용하는 포맷팅이 아니라, 이미지 파일 자체에 의해 결정됩니다.

이미지를 페이지에 배치하고 <img> 태그의 속성이나 CSS를 사용해 너비나 높이를 변경하지 않는다면, 이미지는 자신의 본질적 크기 그대로 화면에 표시됩니다. 아래 예제에서는 이미지 파일에 정의된 실제 크기 범위를 여러분이 눈으로 직접 확인할 수 있도록 테두리(border)를 그려 넣었습니다.

<img
  alt="star"
  src="https://mdn.github.io/shared-assets/images/examples/big-star.png" />
img {
  border: 5px solid darkblue;
}

반면, 텅 빈 <div> 요소는 자기 자신의 크기를 전혀 갖지 않습니다. 만약 HTML에 내용물이 없는 <div>를 추가하고 위의 이미지처럼 테두리를 주게 되면, 화면에는 그저 일직선의 선만 보일 것입니다. 이것은 테두리가 위아래로 겹쳐진(collapsed) 상태로, 이 상자를 벌려서 열어줄 내용물(content)이 없기 때문입니다.

아래 예제를 보면, 이 선(빈 div의 테두리)이 컨테이너의 전체 너비를 차지하고 있는 것을 볼 수 있습니다. <div>는 블록 레벨(block-level) 요소이기 때문이죠. (이제 블록 레벨의 특징은 슬슬 익숙해지셨을 겁니다!) 하지만 내용물이 없기 때문에 높이(블록 방향의 크기)는 0입니다.

<div class="box"></div>
.box {
  border: 5px solid darkblue;
}

위 예제의 빈 요소 안에 텍스트를 한 번 추가해 보세요. 내용물이 생기면서 요소의 높이가 내용물에 맞춰 늘어나 테두리가 열리는 것을 볼 수 있을 것입니다. 이것 또한 요소의 본질적 크기(intrinsic size)입니다. 요소의 크기가 그 '내용물(content)'에 의해 결정된 것이죠.

💡 강사의 실무 팁!
내용물이 없으면 높이가 0이 되어 사라지는 현상 때문에 초보자분들이 "어? 분명히 div를 넣었는데 화면에 안 보여요!"라며 당황하는 경우가 많습니다. 내용물이 없을 때 박스 형태를 유지하려면 반드시 다음 섹션에서 배울 명시적 크기(extrinsic size), 즉 고정된 heightmin-height를 주어야 합니다.


특정 크기 지정하기 (Setting a specific size)

물론 우리는 디자인에 맞춰 요소들에 특정한 크기를 부여할 수도 있습니다. 이렇게 요소에 크기를 지정하여 억지로 맞추게 되면(그리고 내용물은 그 지정된 크기 안에 들어가야만 하죠), 이를 명시적 크기(extrinsic size)라고 부릅니다.

다음 예제에서는 두 개의 <div>에 구체적인 widthheight 값을 주었습니다. 이제 이 상자들은 안에 어떤 내용물이 들어가든 무조건 그 크기를 유지하게 됩니다.
오른쪽 <div>를 보면 알 수 있듯이, 억지로 높이를 고정해 버리면 요소 안에 들어갈 내용물이 너무 많을 경우 상자 밖으로 내용물이 넘쳐흐르는 오버플로우(overflow) 현상이 발생할 수 있습니다. (오버플로우를 다루는 방법은 이어지는 다른 레슨에서 더 자세히 배우게 됩니다.)

<div class="wrapper">
  <div class="box"></div>
  <div class="box">
    These boxes both have a height set, this box has content in it which will
    need more space than the assigned height, and so we get overflow.
  </div>
</div>
body {
  font: 1.2em sans-serif;
}
.wrapper {
  display: flex;
}

.wrapper > * {
  margin: 20px;
}

.box {
  border: 5px solid darkblue;
  height: 100px;
  width: 200px;
}

이렇게 길이(px 등)나 백분율(%)로 요소의 '높이'를 고정해버리면 오버플로우 문제가 발생하기 때문에, 웹 개발을 할 때는 요소의 크기를 고정하는 일을 매우 신중하게 처리해야 합니다.

💡 강사의 실무 팁!
그래서 실무에서는 요소의 height를 고정된 픽셀(px)로 지정하는 것을 최대한 지양합니다! 내용물에 따라 상자가 자연스럽게 늘어나도록 내버려 두거나, 정 최소 높이가 필요하다면 height 대신 min-height를 사용하는 것이 반응형 웹(Responsive Web) 디자인의 핵심 원칙입니다.


백분율(%) 사용하기 (Using percentages)

여러 면에서 백분율(percentages)은 길이 단위와 비슷하게 작동합니다. 값과 단위 레슨에서 설명했듯이, 종종 길이 단위(px, em 등)와 서로 바꿔가며 사용할 수 있죠.

하지만 백분율을 사용할 때는 '무엇의 백분율인가?'를 정확히 알아야 합니다. 다른 컨테이너 안에 들어있는 자식 상자에게 백분율로 width를 주게 되면, 그 크기는 부모 컨테이너 너비의 백분율로 계산됩니다.

<div class="container">
  <div class="box">I have a percentage width.</div>
</div>
body {
  font: 1.2em sans-serif;
}

.box {
  border: 5px solid darkblue;
  width: 50%;
}

위의 경우 box 클래스를 가진 <div>가 백분율이 없을 때는 블록 레벨 요소라서 사용 가능한 공간의 100%를 꽉 채우겠지만, 너비를 50%로 주었기 때문에 원래 채울 수 있었던 공간의 절반만 차지하게 됩니다.

위 예제를 이렇게 수정해 보면서 확인해 보세요:
1. box <div>width: 50%; 코드를 지워보세요. 기본적으로 100% 너비를 차지하는지 확인할 수 있습니다.
2. 지웠던 width: 50%; 코드를 다시 원래대로 되돌리세요.
3. 이번에는 container <div> (부모 상자)의 width50%로 줘보세요. box <div>의 너비가 더 작아지는 것을 볼 수 있을 겁니다. 왜냐하면 이제 줄어든 부모 너비의 50%로 계산되기 때문이죠!


백분율로 된 마진과 패딩 (Percentage margins and padding)

margin이나 padding을 백분율(%)로 설정할 때는 아주 이상한(strange) 현상을 목격하게 될 것입니다.

아래 예제에서 박스 하나에 margin 10%와 padding 10%를 주었습니다. 결과를 보면, 박스의 상/하 패딩과 마진 크기가 좌/우 패딩과 마진 크기와 완벽하게 동일합니다.

<div class="box">I have margin and padding set to 10% on all sides.</div>
body {
  font: 1.2em sans-serif;
}
.box {
  border: 5px solid darkblue;
  width: 200px;
  margin: 10%;
  padding: 10%;
}

보통 "상/하 마진이나 패딩은 요소 '높이(height)'의 10%가 되고, 좌/우 마진이나 패딩은 요소 '너비(width)'의 10%가 되겠지?"라고 기대하기 쉽습니다. 하지만 절대 그렇지 않습니다!

백분율로 마진과 패딩을 설정하면, 그 값은 부모 컨테이너(containing block)의 가로 크기(inline size, 너비)를 기준으로 계산됩니다! (우리가 사용하는 언어가 가로 쓰기 방식일 때 기준)
즉, 위 예제에서 상하좌우 모든 마진과 패딩은 "부모 너비의 10%"로 동일하게 계산됩니다. 그래서 박스 사방에 완전히 동일한 크기의 여백을 만들 수 있는 것이죠. 백분율을 사용할 때 이 사실을 꼭 기억해 두세요!

💡 강사의 실무 팁! (단골 면접 질문)
"padding-top: 100% 를 주면 크기가 어떻게 되나요?" 이 질문은 프론트엔드 기술 면접에 정말 단골로 나옵니다! 정답은 "부모 요소의 너비와 동일한 크기가 됩니다." 입니다.
과거에는 이 기법(Padding Hack)을 이용해서 유튜브 영상 등을 16:9 비율로 반응형 렌더링할 때 밥 먹듯이 썼었어요. (지금은 aspect-ratio라는 좋은 속성이 생겨서 잘 안 쓰지만, 원리는 꼭 알고 계셔야 합니다!)


최소 및 최대 크기 지정하기 (min- and max- sizes)

우리는 요소에 고정된 크기를 주는 것 외에도, CSS를 통해 최소(minimum) 크기나 최대(maximum) 크기를 설정할 수도 있습니다.

예를 들어, 내용물의 양이 계속 변할 수 있는 박스가 있는데, 내용이 적더라도 "최소한 이 정도 높이는 유지했으면 좋겠다" 싶다면 min-height 속성을 사용할 수 있습니다. 이렇게 하면 박스는 항상 최소 높이를 유지하다가, 내용물이 그 최소 높이 공간을 넘어설 만큼 많아지면 내용물에 맞춰 자연스럽게 더 길어집니다.

다음 예제에는 두 개의 박스가 있고, 둘 다 min-height가 100픽셀로 설정되어 있습니다. 왼쪽 박스는 내용물이 적어 딱 100픽셀 높이로 나오지만, 오른쪽 박스는 내용물이 많아 100픽셀 이상의 공간이 필요하기 때문에 100픽셀을 넘어서 쑥 늘어난 것을 볼 수 있습니다.

<div class="wrapper">
  <div class="box"></div>
  <div class="box">
    These boxes both have a min-height set. This box has content in it, which
    will need more space than the assigned height, and so it grows from the
    minimum.
  </div>
</div>
body {
  font: 1.2em sans-serif;
}
.wrapper {
  display: flex;
  align-items: flex-start;
}

.wrapper > * {
  margin: 20px;
}

.box {
  border: 5px solid darkblue;
  min-height: 100px;
  width: 200px;
}

이 방법은 양이 불규칙한 내용물을 다룰 때 앞서 본 무서운 오버플로우(overflow) 현상을 피하기 위해 매우매우 유용합니다!

💡 강사의 실무 팁!
실무에서 컨텐츠가 적을 때 웹 페이지 푸터(Footer, 화면 맨 밑 영역)가 붕 뜨는 걸 막기 위해 main { min-height: 100vh; } (또는 calc 이용) 방식을 정말 많이 사용합니다. "아무리 내용이 없어도 최소한 화면 높이만큼은 차지해라!" 라는 명령이죠.


이미지에 max-width 적용하기 (max-width on images)

max-width가 가장 흔하게 쓰이는 곳은 바로 이미지 축소입니다. 이미지가 가진 본질적 크기(원본 크기)보다 화면 공간이 작을 때 이미지가 화면에 맞게 쪼그라들게 하면서도, 절대 원본 크기보다 더 커지지는 않게(화질이 깨지지 않게) 만들고 싶을 때 사용하죠.

예를 들어, 이미지에 width: 100%를 주면 어떻게 될까요? 만약 이미지를 감싸는 컨테이너가 원본 이미지보다 훨씬 크다면, 이미지가 억지로 100%까지 쫙 늘어나서 화질이 왕창 깨지고 픽셀이 도드라져(pixelated) 보일 것입니다.

하지만 대신 max-width: 100%를 사용하면? 컨테이너가 원본보다 크더라도 이미지는 억지로 늘어나지 않고 선명한 원본 크기를 유지합니다. 반대로 컨테이너가 좁아지면 거기에 맞춰 예쁘게 축소되죠.

아래 예제에는 똑같은 이미지가 세 번 삽입되어 있습니다:

  • 첫 번째 이미지는 width: 100%가 주어졌습니다. 이미지를 감싸고 있는 컨테이너가 원본 이미지보다 더 넓기 때문에, 컨테이너 너비에 맞추기 위해 강제로 늘어났습니다. 화질이 깨져 보이죠?
  • 두 번째 이미지는 max-width: 100%가 주어졌습니다. 그래서 컨테이너를 가득 채우기 위해 억지로 찢어지듯 늘어나지 않았습니다.
  • 세 번째 박스는 컨테이너 크기 자체를 작게 만들고(mini-box), 그 안에 max-width: 100%를 가진 이미지를 넣었습니다. 박스 크기에 맞춰 이미지가 얌전하게 축소된 것을 볼 수 있습니다.
<div class="wrapper">
  <div class="box">
    <img
      alt="star"
      class="width"
      src="https://mdn.github.io/shared-assets/images/examples/big-star.png" />
  </div>
  <div class="box">
    <img
      alt="star"
      class="max"
      src="https://mdn.github.io/shared-assets/images/examples/big-star.png" />
  </div>
  <div class="mini-box">
    <img
      alt="star"
      class="max"
      src="https://mdn.github.io/shared-assets/images/examples/big-star.png" />
  </div>
</div>
.wrapper {
  display: flex;
  align-items: flex-start;
}

.wrapper > * {
  margin: 20px;
}

.box,
.mini-box {
  border: 5px solid darkblue;
}

.box {
  width: 200px;
}
.mini-box {
  width: 30px;
}
.width {
  width: 100%;
}
.max {
  max-width: 100%;
}

이 기술은 이미지를 반응형(responsive)으로 만들기 위해 필수적으로 사용됩니다. 화면이 작은 모바일 기기에서 볼 때 이미지가 예쁘게 축소되게 만들어 주거든요.

하지만 주의할 점이 있습니다! 모바일에서 이미지를 축소해서 보여준다고 해서, 애초에 엄청나게 용량이 큰 고화질 이미지를 로드해서 브라우저가 축소하게 만들면 안 됩니다. 디자인에서 필요로 하는 최대 크기에 딱 맞춰서 최적화된 이미지를 사용해야 해요. 무식하게 큰 이미지를 다운로드하게 만들면 웹사이트 속도가 끔찍하게 느려지고, 데이터 요금 폭탄을 맞은 사용자들의 원망을 사게 될 것입니다!

💡 강사의 실무 팁!
실무에서 사용하는 모든 스타일 초기화 파일(Reset CSS)에는 항상 이 코드가 들어갑니다.
img, video { max-width: 100%; height: auto; display: block; }
반응형 웹을 만들기 위한 이미지 세팅의 '성배(Holy Grail)'와도 같은 코드니 눈에 콕 박아두세요!


뷰포트 단위 (Viewport units)

뷰포트(Viewport)란, 여러분이 웹 사이트를 볼 때 사용하는 브라우저의 '실제로 눈에 보이는 화면 영역'을 뜻합니다. 그리고 이 뷰포트 역시 크기를 가지고 있죠.

CSS에는 이 뷰포트의 크기와 직접적으로 연관된 특별한 단위가 있습니다. 바로 뷰포트 너비(viewport width)를 뜻하는 vw와, 뷰포트 높이(viewport height)를 뜻하는 vh입니다. 이 단위들을 사용하면 사용자의 뷰포트 크기에 비례하여 요소의 크기를 잴 수 있습니다.

  • 1vh는 뷰포트 높이의 1%와 같습니다.
  • 1vw는 뷰포트 너비의 1%와 같습니다.

이 단위들은 박스 크기를 잡을 때도 유용하지만, 텍스트 크기를 화면에 비례하게 맞출 때도 아주 요긴합니다. 아래 예제에는 20vw 너비와 20vh 높이를 가진 박스가 있습니다. 그리고 그 안에는 알파벳 A가 들어있는데, 글자 크기(font-size)에 10vh를 주었습니다.

<div class="box">A</div>
body {
  font-family: sans-serif;
}

.box {
  border: 5px solid darkblue;
  width: 20vw;
  height: 20vh;
  font-size: 10vh;
}

이제 여러분이 브라우저 창의 크기를 마우스로 잡고 늘렸다 줄였다 해보세요. vhvw 값을 변경하면 박스와 폰트 크기가 바뀌고, 뷰포트 크기를 변경하면 그에 맞춰 박스와 폰트 크기가 실시간으로 고무줄처럼 반응하여 커졌다 작아졌다 할 것입니다!

디자인을 할 때 뷰포트 기준 크기 조절은 꽤 매력적입니다. 예를 들어, 사용자가 스크롤을 내리기 전 맨 처음 화면에 꽉 차는 풀스크린 배너를 띄우고 싶다면, 그 영역의 높이를 100vh로 주면 됩니다. 그러면 브라우저 높이의 100%를 정확히 채우기 때문에, 나머지 내용들은 스크롤을 내려야만 볼 수 있게 깔끔하게 밀려 내려갑니다.

💡 강사의 실무 팁! (고급 기술)
모바일 브라우저(Safari, Chrome 등)에서 100vh를 사용하면 맨 밑의 주소창이나 툴바 메뉴 때문에 화면이 가려져서 묘하게 스크롤이 생기는 버그 아닌 버그를 겪게 될 겁니다!
이를 해결하기 위해 최근 CSS에는 dvh(동적 뷰포트 높이), svh(최소 뷰포트 높이), lvh(최대 뷰포트 높이) 라는 신규 단위가 추가되었습니다. 실무에서는 모바일 100% 풀화면을 잡을 때 height: 100dvh;를 많이 사용한다는 점, 나중에 꼭 기억해 두세요!


요약 (Summary)

이번 레슨에서는 웹에서 사물의 크기를 다룰 때 마주칠 수 있는 핵심적인 개념들을 쭉 훑어보았습니다. 나중에 CSS 레이아웃(CSS Layout)을 본격적으로 다루게 되면, 이 크기 지정 개념들이 다양한 레이아웃 기법을 정복하는 데 아주 중요한 밑거름이 될 것입니다. 그러니 다음 단계로 넘어가기 전에 확실히 이해하고 가는 것이 좋습니다.

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

0개의 댓글