CSS aspect-ratio 속성

반응형 레이아웃에서 간격을 유지하는 데 도움이 되는 CSS 속성입니다.

가로세로 비율

Browser Support

  • Chrome: 88.
  • Edge: 88.
  • Firefox: 89.
  • Safari: 15.

Source

가로세로 비율은 일반적으로 너비:높이 또는 x:y의 치수로 두 개의 정수와 콜론으로 표현됩니다. 사진의 가장 일반적인 가로세로 비율은 4:3과 3:2이며, 동영상과 최신 소비자 카메라의 경우 16:9 가로세로 비율을 사용하는 경향이 있습니다.

가로세로 비율이 동일한 두 이미지 하나는 634x951px이고 다른 하나는 200x300px입니다. 두 이미지 모두 가로세로 비율이 2:3입니다.
가로세로 비율이 동일한 이미지 2개. 하나는 634x951px이고 다른 하나는 200x300px입니다. 두 이미지 모두 가로세로 비율이 2:3입니다.

반응형 디자인이 등장하면서 웹 개발자에게 가로세로 비율을 유지하는 것이 점점 더 중요해졌습니다. 특히 사용 가능한 공간에 따라 이미지 크기가 달라지고 요소 크기가 바뀌기 때문입니다.

종횡비 유지가 중요한 몇 가지 예는 다음과 같습니다.

  • 상위 요소의 너비가 100% 이고 높이는 특정 표시 영역 비율로 유지되는 반응형 iframe 만들기
  • 항목이 로드되고 공간을 차지할 때 레이아웃이 다시 지정되지 않도록 이미지, 동영상, 삽입을 위한 내장 자리표시자 컨테이너 만들기
  • 대화형 데이터 시각화 또는 SVG 애니메이션을 위한 균일한 반응형 공간 만들기
  • 카드나 캘린더 날짜와 같은 다중 요소 구성요소에 균일하고 반응형 공간 만들기
  • 다양한 크기의 여러 이미지에 균일한 반응형 공간을 만듭니다 (object-fit와 함께 사용 가능).

object-fit

가로세로 비율을 정의하면 반응형 컨텍스트에서 미디어 크기를 조정하는 데 도움이 됩니다. 이 버킷의 또 다른 도구는 object-fit 속성으로, 사용자가 블록 내 객체 (예: 이미지)가 블록을 채우는 방식을 설명할 수 있습니다.

object-fit 데모 시각화
다양한 object-fit 값을 보여줍니다. CodePen의 데모를 참고하세요.

initialfill 값은 공간을 채우도록 이미지를 다시 조정합니다. 이 예에서는 픽셀이 다시 조정되므로 이미지가 압축되고 흐려집니다. 이상적이지 않습니다. object-fit: cover는 이미지의 가장 작은 크기를 사용하여 공간을 채우고 이 크기에 따라 이미지를 잘라 맞춥니다. 가장 낮은 경계에서 '확대'됩니다. object-fit: contain는 이미지가 항상 전체적으로 표시되도록 합니다. cover와는 반대입니다. cover는 가장 큰 경계(위 예에서는 너비)의 크기를 가져와 공간에 맞추면서 고유한 가로세로 비율을 유지하도록 이미지의 크기를 조정합니다. object-fit: none 사례는 이미지가 자연스러운 크기로 중앙(기본 객체 위치)에서 잘린 것을 보여줍니다.

object-fit: cover는 다양한 크기의 이미지를 처리할 때 멋진 균일한 인터페이스를 보장하기 위해 대부분의 상황에서 작동하는 경향이 있지만, 이 방법으로는 정보가 손실됩니다 (이미지가 가장 긴 가장자리에서 잘림).

이러한 세부정보가 중요한 경우 (예: 미용 제품의 플랫 레이 작업 시) 중요한 콘텐츠를 자르는 것은 허용되지 않습니다. 따라서 이상적인 시나리오는 잘리지 않고 UI 공간에 맞는 다양한 크기의 반응형 이미지입니다.

이전 방식: padding-top로 가로세로 비율 유지

padding-top을 사용하여 캐러셀 내 게시물 미리보기 이미지에 1:1 가로세로 비율을 설정합니다.
padding-top을 사용하여 캐러셀 내 게시물 미리보기 이미지의 가로세로 비율을 1:1로 설정합니다.

더욱 반응성이 높게 만들기 위해 가로세로 비율을 사용할 수 있습니다. 이를 통해 특정 비율 크기를 설정하고 나머지 미디어를 개별 축 (높이 또는 너비)에 기반할 수 있습니다.

현재 널리 사용되는 교차 브라우저 솔루션으로 이미지의 너비를 기반으로 가로세로 비율을 유지하는 방법은 'Padding-Top Hack'이라고 합니다. 이 솔루션에는 상위 컨테이너와 절대 위치가 지정된 하위 컨테이너가 필요합니다. 그런 다음 가로세로 비율을 백분율로 계산하여 padding-top로 설정합니다. 예를 들면 다음과 같습니다.

  • 1:1 가로세로 비율 = 1 / 1 = 1 = padding-top: 100%
  • 4:3 가로세로 비율 = 3 / 4 = 0.75 = padding-top: 75%
  • 가로세로 비율 3:2 = 2 / 3 = 0.66666 = padding-top: 66.67%
  • 가로세로 비율 16:9 = 9 / 16 = 0.5625 = padding-top: 56.25%

이제 가로세로 비율 값을 확인했으므로 이를 상위 컨테이너에 적용할 수 있습니다. 다음 예를 참고하세요.

<div class="container">
  <img class="media" src="..." alt="...">
</div>

그런 다음 다음과 같은 CSS를 작성할 수 있습니다.

.container {
  position: relative;
  width: 100%;
  padding-top: 56.25%; /* 16:9 Aspect Ratio */
}

.media {
  position: absolute;
  top: 0;
}

aspect-ratio로 가로세로 비율 유지

가로세로 비율을 사용하여 캐러셀 내 게시물 미리보기 이미지에 1:1 가로세로 비율을 설정합니다.
aspect-ratio을 사용하여 캐러셀 내 게시물 미리보기 이미지의 가로세로 비율을 1:1로 설정합니다.

아쉽게도 이러한 padding-top 값을 계산하는 것은 직관적이지 않으며 추가 오버헤드와 포지셔닝이 필요합니다. 새로운 내장 aspect-ratio CSS 속성을 사용하면 가로세로 비율을 유지하는 언어가 훨씬 더 명확해집니다.

동일한 마크업을 사용하여 padding-top: 56.25%aspect-ratio: 16 / 9로 대체하고 aspect-ratiowidth / height의 지정된 비율로 설정할 수 있습니다.

padding-top 사용
.container {
  width: 100%;
  padding-top: 56.25%;
}
aspect-ratio 사용
.container {
  width: 100%;
  aspect-ratio: 16 / 9;
}

padding-top 대신 aspect-ratio를 사용하면 훨씬 명확하며, 일반적인 범위를 벗어난 작업을 수행하기 위해 패딩 속성을 전면적으로 개편하지 않아도 됩니다.

이 새로운 속성은 가로세로 비율을 auto로 설정하는 기능도 추가합니다. 여기서 '내장 가로세로 비율이 있는 대체 요소는 해당 가로세로 비율을 사용합니다. 그렇지 않으면 상자에 기본 가로세로 비율이 없습니다.' auto<ratio>가 함께 지정된 경우 기본 종횡비는 widthheight로 나눈 지정된 비율입니다. 단, 내장 종횡비가 있는 대체 요소인 경우에는 해당 종횡비가 대신 사용됩니다.

예: 그리드의 일관성

이 기능은 CSS 그리드 및 Flexbox와 같은 CSS 레이아웃 메커니즘과도 잘 작동합니다. 스폰서 아이콘 그리드와 같이 1:1 가로세로 비율을 유지하려는 하위 요소가 있는 목록을 고려해 보세요.

<ul class="sponsor-grid">
  <li class="sponsor">
    <img src="..." alt="..."/>
  </li>
  <li class="sponsor">
    <img src="..." alt="..."/>
  </li>
</ul>
.sponsor-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}

.sponsor img {
  aspect-ratio: 1 / 1;
  width: 100%;
  object-fit: contain;
}
다양한 가로세로 비율의 상위 요소가 있는 그리드의 이미지 CodePen에서 데모 보기

예: 레이아웃 변경 방지

aspect-ratio의 또 다른 유용한 기능은 누적 레이아웃 이동을 방지하고 더 나은 Web Vitals를 제공하기 위해 자리표시자 공간을 만들 수 있다는 것입니다. 이 첫 번째 예시에서는 Unsplash와 같은 API에서 애셋을 로드하면 미디어 로드가 완료될 때 레이아웃 시프트가 발생합니다.

로드된 애셋에 가로세로 비율이 설정되지 않은 경우 발생하는 누적 레이아웃 시프트 동영상 이 동영상은 에뮬레이트된 3G 네트워크로 녹화되었습니다.

반면 aspect-ratio를 사용하면 이 레이아웃 변경을 방지하는 자리표시자가 생성됩니다.

img {
  width: 100%;
  aspect-ratio: 8 / 6;
}
로드된 애셋에 설정된 가로세로 비율이 있는 동영상 이 동영상은 에뮬레이트된 3G 네트워크로 녹화되었습니다. CodePen에서 데모 보기

보너스 팁: 가로세로 비율의 이미지 속성

이미지 속성을 통해 이미지의 가로세로 비율을 설정할 수도 있습니다. 이미지의 크기를 미리 알고 있다면 이러한 크기를 widthheight로 설정하는 것이 권장사항입니다.

위의 예에서 크기가 800x600픽셀이므로 이미지 마크업은 <img src="image.jpg" alt="..." width="800" height="600">와 같습니다. 전송된 이미지의 가로세로 비율이 동일하지만 정확한 픽셀 값은 아닐 수 있습니다. 그래도 이미지 속성 값을 사용하여 비율을 설정하고 width: 100% 스타일과 결합하여 이미지가 적절한 공간을 차지하도록 할 수 있습니다. 모두 합치면 다음과 같습니다.

<!-- Markup -->
<img src="image.jpg" alt="..." width="8" height="6">
/* CSS */
img {
  width: 100%;
  height: auto;
}

결과적으로 효과는 CSS를 통해 이미지에 aspect-ratio를 설정하는 것과 동일하며 누적 레이아웃 시프트가 방지됩니다 (Codepen의 데모 참고).

결론

여러 최신 브라우저에서 출시되는 새로운 aspect-ratio CSS 속성을 사용하면 미디어 및 레이아웃 컨테이너에서 적절한 가로세로 비율을 유지하는 것이 좀 더 간단해집니다.

사진: 에이미 샴블렌리오넬 구스타브(Unsplash 제공)