Box sizing/Aspect ratios

김동현·2026년 3월 18일

mdn 학습 번역 - CSS

목록 보기
49/190

멋진 영상이나 썸네일 이미지를 넣을 때, 화면 크기에 따라 찌그러지거나 이상하게 잘려서 당황했던 적이 있으실 거예요. 특히, 예전에는 유튜브 영상을 반응형으로 만들기 위해 padding-bottom 꼼수(이른바 패딩 핵)를 써야 해서 코드가 복잡했죠.

오늘 다룰 '종횡비(aspect-ratio) 이해하고 설정하기' 문서는 그런 고민을 단숨에 날려줄 모던 CSS의 마법 같은 속성을 다룹니다. 자, 실무에서 정말 많이 쓰이는 이 속성을 제가 아주 쉽고 재밌는 구어체로 설명해 드릴게요!


종횡비 이해하고 설정하기 (Understanding and setting aspect ratios)

페이지에 렌더링되는 모든 요소는 너비(width)와 높이(height)를 가지고 있으며, 따라서 이 둘 사이의 비율인 종횡비(aspect ratio)를 갖게 됩니다.

미디어 객체(이미지나 비디오 등)에 CSS로 크기, 배율 조정, 확대, 테두리 등을 아무것도 적용하지 않았을 때 가지는 그 객체 고유의 크기를 자연 크기(natural size) 또는 고유 크기(intrinsic size)라고 부릅니다. 이 고유 크기는 box-sizing이나 테두리(border), 마진(margin), 패딩(padding) 같은 스타일링 때문에 결정되는 것이 아니라, 그 객체 자체가 태생적으로 가지고 있는 크기를 뜻합니다.

웹 사이트를 개발할 때, 우리는 종종 요소의 너비를 브라우저 화면(viewport)이나 부모 컨테이너의 크기에 맞춰 퍼센트(%)로 설정하고, 그 너비에 비례하여 높이도 자동으로 변하게 만들고 싶어 합니다. 즉, 화면 크기가 달라져도 특정한 종횡비(가로세로 비율)를 항상 유지하고 싶은 거죠.

특히 이미지나 비디오 같은 대체 요소(replaced elements)의 경우, 특정한 종횡비를 유지하는 것은 단순히 반응형 웹 디자인(responsive web design)을 구현하기 위해서뿐만 아니라 훌륭한 사용자 경험(UX)을 제공하는 데 있어서도 필수적입니다. 미디어의 종횡비를 미리 설정해 두면, 미디어 파일이 나중에 로딩되면서 이미 다 그려진 페이지 레이아웃을 덜컥 밀어내는 현상(이를 jank 또는 Layout Shift라고 합니다)을 막을 수 있습니다. 미리 비율에 맞춰 공간을 확보(예약)해두기 때문이죠.

CSS를 사용하면 종횡비에 따라 대체 요소(replaced elements)와 비대체 요소(non-replaced elements)의 크기를 조절할 수 있습니다. 이 가이드에서는 aspect-ratio 속성에 대해 알아보고, 두 가지 요소 타입에서의 적용 방법을 논의한 뒤, 실무에서 자주 쓰이는 종횡비 활용 사례들을 살펴보겠습니다.

💡 강사 팁:
"Lighthouse 성능 점수" 들어보셨죠? 거기서 감점 원인 1순위로 꼽히는 것이 CLS(Cumulative Layout Shift)입니다. 이미지가 로딩되면서 글씨가 아래로 밀려버리는 현상이죠. 이 aspect-ratio를 써서 빈 공간을 미리 잡아두면, 여러분의 포트폴리오 사이트 성능 점수가 수직 상승하게 됩니다!


이 문서의 내용 (In this article)


aspect-ratio 속성의 작동 원리 (How the aspect-ratio property works)

CSS aspect-ratio 속성값은 요소 박스의 '선호하는(preferred) 가로세로 비율'을 정의합니다. 이 값은 <ratio>(비율)이거나, auto 키워드이거나, 아니면 이 둘을 띄어쓰기로 함께 적은 조합일 수 있습니다.

<ratio>는 너비와 높이의 비율을 순서대로 나타냅니다. 슬래시(/)로 구분된 두 개의 양수 <number>로 표현하거나, 숫자 하나만 달랑 쓸 수도 있습니다. 숫자 하나만 쓰면 <number> / 1이라고 쓴 것과 똑같이 취급됩니다. 즉, 너비를 높이로 나눈 값을 의미하게 되죠.

아래에 나열된 값들은 전부 완벽하게 똑같은 의미입니다.

aspect-ratio: 3 / 6;
aspect-ratio: 1 / 2;
aspect-ratio: 0.5 / 1;
aspect-ratio: 0.5;

마찬가지로 아래의 값들도 전부 같은 의미입니다.

aspect-ratio: 9/6;
aspect-ratio: 3/2;
aspect-ratio: 1.5;
<div>0.5</div>
<div>1.5</div>
div {
  height: 121px;
  aspect-ratio: 0.5;
  background-color: pink;
  line-height: 100px;
  text-align: center;
  float: left;
  background-image:
    repeating-linear-gradient(to right, black 0px 1px, transparent 1px 20px),
    repeating-linear-gradient(black 0px 1px, transparent 1px 20px);
  background-size:
    181px 5px,
    5px 121px;
  background-repeat: no-repeat;
}

div + div {
  aspect-ratio: 1.5;
  background-color: lightgreen;
  margin-left: 10px;
}

MDN Playground에서 실행해보기 (Live Sample)

auto 키워드의 효과는 이 속성이 적용되는 요소가 대체 요소(replaced element, 예: 이미지/비디오)인지 아닌지에 따라 달라집니다.
고유한 종횡비를 가지고 있는 대체 요소에 auto를 주면, "자신이 원래 가지고 있는 고유 종횡비를 그대로 써라"라는 뜻이 됩니다. 그 외의 모든 일반 요소에 auto를 주면, "이 박스는 선호하는 종횡비가 없다(비율 따위 신경 안 쓴다)"라는 뜻이 되죠. 즉, 이 두 경우 모두 아예 aspect-ratio 속성을 적지 않은 것과 동일한 기본 동작을 합니다.

aspect-ratio: auto 2 / 3;이나 aspect-ratio: 0.75 auto;처럼 auto 키워드와 <ratio> 비율 값을 함께 적으면 어떻게 될까요? 이때는 고유한 종횡비를 가진 대체 요소(이미지 등)를 만나면 auto가 작동해서 원래 이미지의 비율을 지켜주고, 고유 비율이 없는 일반 요소를 만나면 뒤에 명시된 width / height 비율이나 숫자 값을 선호하는 종횡비로 사용하게 됩니다. 아주 스마트하죠!

💡 강사 팁:
방금 "선호하는(preferred)"이라는 단어를 계속 강조했는데요, 이 말이 중요합니다. aspect-ratio를 선언한다고 해서 무조건 그 비율로 렌더링 되는 건 아닙니다. 너비와 높이 중 최소한 하나가 auto로 설정되어 있어야만 (즉, 크기가 열려 있어야만) 브라우저가 남은 한쪽 길이를 이 비율에 맞춰 알아서 계산해 줍니다.

만약 요소의 너비와 높이를 둘 다 명시적으로 100px처럼 고정값으로 줘버리면, aspect-ratio 속성은 쓸모가 없어져서 무시당합니다. 강제로 고정된 치수가 우선순위(precedence)를 가지기 때문이죠.

대체 요소(이미지 등)의 경우, 너비나 높이에 아무런 값도 주지 않으면(또는 둘 다 auto로 두면) 자신의 태생적인 고유 크기(intrinsic size)로 렌더링 되며 aspect-ratio 값은 적용되지 않습니다. 반면 일반 요소(div 등)는 콘텐츠 내용물에 따라 크기가 유동적으로 변하기 때문에, 명시적인 치수를 정해주지 않으면 설정해 둔 aspect-ratio가 작동하여 비율을 잡아줍니다.

아무런 CSS도, HTML 속성도 없는 상태로 페이지에 그려질 때 브라우저는 해당 객체를 자연 크기 그대로 렌더링 한다는 점을 기억하세요.


대체 요소의 종횡비 조절하기 (Adjusting aspect ratios of replaced elements)

<img><video> 같은 대체 요소들은 이미 자신만의 크기가 정해진 미디어 파일로 교체(replaced)되기 때문에, 태생적인 '고유 종횡비'를 가지고 있습니다. JPEG, PNG, GIF 같은 일반적인 이미지를 예로 들어 볼까요? 페이지에 이미지를 넣고 아무런 높이나 너비(HTML 속성이든 CSS든)를 지정하지 않으면, 그 이미지는 원본 크기 그대로 화면에 뜹니다.

<img
  src="https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg?image=good"
  alt="220 pixel square pride flag" />

MDN Playground에서 실행해보기 (Live Sample)

위 코드는 아무 CSS도 주지 않은 220픽셀 정사각형 이미지입니다. 고유 크기 그대로 출력되죠.

그런데 여기서 너비(width) 같이 한쪽 치수만 지정해 주면 어떻게 될까요? 브라우저는 훌륭하게도 미디어 원본의 종횡비를 유지하면서 나머지 한쪽(이 경우엔 높이) 크기를 자동으로 줄이거나 늘려줍니다.

아래 예제는 오직 width 속성만 지정했기 때문에 브라우저가 원본 종횡비를 보호해 주는 모습입니다. 동일한 이미지를 3번 반복해서 각각 55px, 110px, 그리고 auto를 주어 원래 크기인 220px로 나타나게 했습니다.

<img
  src="[https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg](https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg)"
  alt="Pride flag" />
<img
  src="[https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg](https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg)"
  alt="Pride flag" />
<img
  src="[https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg](https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg)"
  alt="Pride flag" />
img {
  width: 55px;
  margin-right: 5px;
}

img + img {
  width: 110px;
}

img + img + img {
  width: auto;
}

MDN Playground에서 실행해보기 (Live Sample)

대체 요소가 찌그러지는(distorting) 참사가 벌어지는 건 여러분이 가로와 세로 길이를 억지로 둘 다 지정했을 때뿐입니다. 예를 들어 이미지에 width: 100vw; height: 100vh;를 줘버리면, 모니터 비율이 이미지 원본 비율과 일치하지 않는 이상 뚱뚱해지거나 홀쭉해지는 괴상한 이미지를 보게 됩니다.

아래 예제에서 똑같은 3개의 이미지를 불렀는데, 높이는 모두 110px로 고정해 두고 너비만 55px, 110px, 220px로 각각 다르게 줘버렸습니다. 첫 번째는 홀쭉해지고, 세 번째는 뚱뚱하게 늘어나버렸죠.

<img
  src="[https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg](https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg)"
  alt="Pride flag" />
img {
  width: 55px;
  height: 110px;
}

img + img {
  width: 110px;
}

img + img + img {
  width: 220px;
}

MDN Playground에서 실행해보기 (Live Sample)

사실 이렇게 찌그러진 이미지는 CSS aspect-ratio 속성으로도 억지로 만들어낼 수 있습니다. 치수 한쪽만 지정해 놓고 비율을 1 / 1이 아닌 다른 값으로 주면 되거든요. 굳이 이렇게 하실 일은 없겠지만, 가능하다는 건 알아두시면 좋습니다.

img {
  height: 90vh;
  aspect-ratio: 3; /* 세로가 1일 때 가로가 3인 뚱뚱한 비율 강제 적용 */
}

대체 요소를 컨테이너에 핏하게 맞추기 (Fitting replaced elements within their containers)

이미지가 찌그러지지 않고 고유 종횡비를 유지하면서도, 내가 원하는 네모 반듯한 박스(컨테이너) 안에 꽉 차게 넣으려면 어떻게 해야 할까요? 바로 그 유명한 object-fit 속성에 covercontain 값을 주는 것입니다. 이렇게 하면 대체 요소의 크기가 조절되면서 컨테이너를 꽉 채우도록 넘치는 부분이 잘리거나(cover), 빈 여백이 남더라도 온전히 다 보이게(contain) 됩니다.

다음 예제에서는 1:1 정사각형 이미지를 5 / 2라는 아주 납작한 종횡비를 가진 3개의 그리드 아이템 안에 집어넣어 보겠습니다.

<div class="grid">
  <div>
    <img
      src="[https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg](https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg)"
      alt="Pride flag" />
  </div>
  <div>
    <img
      class="cover"
      src="[https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg](https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg)"
      alt="Pride flag" />
  </div>
  <div>
    <img
      class="contain"
      src="[https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg](https://mdn.github.io/shared-assets/images/examples/progress-pride-flag.jpg)"
      alt="Pride flag" />
  </div>
</div>
.grid {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}

div div {
  aspect-ratio: 5 / 2; /* 컨테이너의 비율을 5:2로 고정 */
  background-color: #cccccc;
}

img {
  height: 100%;
  width: 100%; /* 부모(5:2 박스)를 꽉 채우도록 설정 */
}

.cover {
  object-fit: cover; /* 찌그러지지 않게 덮기 (위아래 잘림) */
}

.contain {
  object-fit: contain; /* 찌그러지지 않게 쏙 들어가기 (좌우 여백 남음) */
}

MDN Playground에서 실행해보기 (Live Sample)

첫 번째 이미지는 object-fit을 주지 않아 5:2 비율로 억지로 찌그러졌습니다. 두 번째(cover)는 찌그러지지 않고 세로 가운데를 기준으로 꽉 차게 잘려 들어갔고, 세 번째(contain)는 원본 비율 그대로 박스 안에 쏙 들어가면서 양옆에 회색 빈 공간이 남게 되었습니다.

💡 강사 팁:
aspect-ratio로 틀을 잡아두고 width: 100%; height: 100%; object-fit: cover; 조합을 쓰는 것은 프로필 이미지, 카드 UI의 썸네일 등을 만들 때 전 세계 개발자가 공통으로 쓰는 1티어 콤보 기술입니다!


비대체 요소의 종횡비 정의하기 (Defining aspect ratios for non-replaced elements)

대체 요소(이미지)는 가만 놔둬도 자기 비율을 지키지만, <div><p> 같은 비대체 요소(텍스트 등이 들어가는 일반 박스)는 텍스트 양이나 화면 너비에 따라 길쭉해지기도 하고 납작해지기도 합니다. 똑같은 문장이라도 넓은 모니터에선 3줄로 보이지만 모바일 화면에선 8줄이 될 수 있죠. 이 때문에 종횡비가 수시로 변합니다.

만약 우리가 화면 너비에 상관없이 일반 박스를 "무조건 정사각형으로 만들어라"라고 강제하고 싶다면 어떻게 해야 할까요? 바로 이때 CSS aspect-ratio가 빛을 발합니다.

<p>Short text:</p>
<blockquote>Breath.</blockquote>
<p>Longer text:</p>
<blockquote>You're perfect just as you are.</blockquote>
blockquote {
  inline-size: max-content; /* 텍스트 길이에 맞춰 너비 조절 */
  aspect-ratio: 1;          /* 무조건 정사각형으로 만들어버리기! */
  border: 1px solid #cccccc;
  background-color: #ededed;
}

MDN Playground에서 실행해보기 (Live Sample)

첫 번째 박스는 텍스트("Breath.")가 짧아서 너비가 좁게 잡혔고, aspect-ratio: 1 때문에 높이도 똑같이 좁게 잡혀 작은 정사각형이 되었습니다.
두 번째 박스는 문장이 길어서 너비가 넓게 잡혔고, 그에 맞춰 높이도 커지면서 거대한 정사각형이 되었습니다. height를 따로 주지 않았는데도 비율 하나만으로 정사각형이 유지되는 걸 볼 수 있죠!

컨테이너 크기에 맞춰 완벽한 원 만들기 (Creating a circle based on the container size)

프로필 이미지나 아이콘 배경을 동그랗게 만들 때 주로 어떻게 하셨나요? 이전에는 width: 200px; height: 200px; border-radius: 50%; 처럼 가로세로를 일일이 똑같은 숫자로 맞춰줘야 했습니다. 만약 하나라도 수치가 달라지면 타원형이 되어버리죠.

이제는 aspect-ratio: 1 하나면 고민 끝입니다.

<div><p>Hello world</p></div>
<div><p>Hello world</p></div>
div, p {
  aspect-ratio: 1; /* 비율을 1:1로 줘서 무조건 정사각형으로 세팅 */
  border-radius: 50%; /* 50%를 깎아서 완벽한 원 생성 */
}

div:first-of-type {
  overflow: hidden;
}

div:last-of-type p {
  margin-block: 0;
}

MDN Playground에서 실행해보기 (Live Sample)

가로세로 픽셀을 하드코딩해서 맞출 필요 없이, 너비만 정해주고 aspect-ratio: 1을 주면 어떤 반응형 환경에서도 찌그러지지 않는 완벽한 원을 유지할 수 있습니다.


aspect-ratio의 흔한 사용 사례 (Common aspect-ratio use cases)

반응형 디자인을 할 때 aspect-ratio로 골치 아픈 문제들을 얼마나 우아하게 해결할 수 있는지 실전 사례들을 보겠습니다.

외부 에셋(유튜브, 틱톡 등) 반응형으로 만들기

포트폴리오에 유튜브나 틱톡 영상을 임베드(embed)할 때 보통 <iframe> 태그를 복사해서 쓰게 됩니다. <video> 태그는 자기 자신의 영상 비율을 알지만, 껍데기일 뿐인 <iframe>은 자기가 무슨 비율인지 모릅니다. 그래서 모바일에선 잘리거나 검은 여백(레터박스)이 생기는 문제가 발생하죠.

이걸 해결하는 방법은 의외로 간단합니다. iframe의 부모(컨테이너) 혹은 iframe 자체의 width100%로 주고, aspect-ratio로 유튜브(16:9)나 틱톡(9:16) 비율을 명시해 버리면 됩니다!

iframe.youtube {
  aspect-ratio: 16/9;
  width: 100vw;
  height: auto;
}

iframe.instagram,
iframe.tiktok {
  aspect-ratio: 9/16;
  height: 100vh;
  width: auto;
}

/* 화면이 너무 가로로 길어지면 위아래가 잘릴 수 있으니 방어 코드 작성 */
@media (aspect-ratio > 16 / 9) {
  iframe.youtube {
    width: auto;
    height: 100vh;
  }
}

이렇게 @media 쿼리 안에서 aspect-ratio 상태를 감지하여 뷰포트 비율이 영상 비율보다 넓어지거나 좁아질 때 가로/세로 기준을 바꿔주면, 어떤 기기에서도 영상이 꽉 차면서 절대 잘리지 않게 만들 수 있습니다.

💡 강사 팁:
과거에 이 효과를 내려고 그 복잡한 "Padding-bottom 56.25% Hack"이라는 걸 썼었는데, 모던 브라우저에선 이제 그럴 필요가 없습니다. 저 16:9 선언 한 줄이 모든 걸 해결해 주니까요!

그리드(Grid) 셀을 정사각형으로 만들기

CSS Grid를 사용해서 인스타그램 피드처럼 갤러리를 만들 때, 카드가 화면을 꽉 채우게 하려고 auto-fill1fr을 쓰다 보면 각 카드의 너비가 상황마다 달라집니다. 너비가 유동적으로 변하는데 이 카드를 어떻게 항상 정사각형으로 유지할 수 있을까요?

정답은 각 그리드 아이템에 aspect-ratio: 1;을 주는 겁니다.

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(95px, 1fr));
  gap: 20px;
}

.item {
  aspect-ratio: 1; /* 너비가 어떻게 변하든 높이는 너비랑 똑같이 1:1 ! */
  min-height: 0; /* 콘텐츠가 넘쳐도 비율이 깨지며 길어지는 걸 방지 */
  overflow: auto;
}

MDN Playground에서 실행해보기 (Live Sample)

그리드 아이템의 너비가 95px이 되든 200px이 되든, 높이는 무조건 너비를 따라가서 완벽한 정사각형 그리드가 유지됩니다. 이때 내부에 들어가는 텍스트가 너무 길어져서 박스가 세로로 뚱뚱해지는(비율이 깨지는) 걸 막으려면 min-height: 0; overflow: auto; (또는 hidden) 처리를 해주면 깔끔하게 해결됩니다.


참고 자료 (See also)


MDN 개선에 참여하기 (Help improve MDN)

이 페이지가 도움이 되셨나요?
[Yes][No]

기여하는 방법 알아보기(Learn how to contribute)
이 페이지의 마지막 수정일은 2025년 11월 7일이며, MDN 기여자들에 의해 수정되었습니다.


어떠신가요? 프론트엔드 실무에서 이미지나 영상을 다룰 때 aspect-ratio가 얼마나 강력한 무기가 되는지 감이 팍 오시죠?

포트폴리오에 그리드 갤러리나 임베디드 영상을 넣을 때 오늘 배운 이 기법들을 꼭 적용해 보세요. 반응형 웹에서 레이아웃이 요동치지 않고 안정적으로 딱딱 맞아떨어지는 걸 보면 짜릿한 쾌감을 느끼실 수 있을 겁니다. 화이팅입니다!

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

0개의 댓글