본문으로 건너뛰기
개발 머꼬
개발 노트CSS
hohyeon.dev16

이미지가 로드될 때마다 아래 내용이 밀려 내려간 이유와 aspect-ratio

  • #CSS
  • #Engineering Note
  • #Performance

문제 발생

목록에서 이미지가 하나씩 로드될 때마다 아래 카드들이 아래로 밀렸습니다. 읽고 있던 줄이 갑자기 움직이고, 누르려던 버튼이 밀려나 다른 것이 눌리기도 했습니다.

<img src="/thumb.webp" alt="" />
img { width: 100%; }   /* 높이는 로드 후에야 결정된다 */

원인 분석

브라우저는 이미지 파일이 도착해야 그 이미지의 크기를 알 수 있습니다. 그 전까지는 높이를 0으로 잡고, 도착한 순간 실제 비율만큼 늘립니다. 그 사이에 있던 모든 콘텐츠가 아래로 밀리고, 이것이 CLS(Cumulative Layout Shift) 로 측정됩니다.

aspect-ratio는 "이 요소는 이 비율이다"를 미리 알려 줍니다. 그러면 브라우저가 로드 전에도 정확한 높이를 계산해 자리를 잡아 둡니다. 2021년 9월부터 Baseline입니다.

한 가지 규칙을 알아야 합니다. 가로·세로 중 최소 하나가 auto여야 aspect-ratio가 동작합니다. 둘 다 명시하면 그 값이 이기고 비율은 무시됩니다.

/* 동작한다 — height가 auto */
div { width: 100px; height: auto; aspect-ratio: 16 / 9; }

/* 동작하지 않는다 — 둘 다 고정 */
div { width: 100px; height: 50px; aspect-ratio: 16 / 9; }

해결 방안

  1. 비율을 CSS로 예약합니다.
img {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
}
  1. HTML의 width/height 속성도 함께 씁니다. 최신 브라우저는 이 두 속성에서 비율을 계산해 스스로 자리를 잡습니다. CSS가 로드되기 전에도 동작하므로 둘 다 두는 편이 안전합니다. 실제 표시 크기와 같을 필요는 없고 비율만 맞으면 됩니다.
<img src="/thumb.webp" alt="" width="1600" height="900" />
  1. 실제 비율을 모르는 이미지에는 auto를 함께 씁니다. 지정한 비율로 자리를 잡았다가, 로드된 뒤에는 이미지의 고유 비율로 전환됩니다.
img { width: 200px; aspect-ratio: 3 / 2 auto; }
  1. 잘림을 어떻게 다룰지 정합니다. 예약한 비율과 실제 비율이 다르면 이미지가 늘어나 보입니다. object-fit: cover로 채우고 필요하면 object-position으로 기준점을 정합니다.
img { aspect-ratio: 16 / 9; object-fit: cover; }
  1. 이미지 말고도 씁니다. 지도 임베드, 비디오 래퍼, 스켈레톤 자리 표시자처럼 "비율이 정해진 상자"에는 예전의 padding-top: 56.25% 트릭 대신 aspect-ratio 한 줄이면 됩니다.

공식 문서

마지막 수정

좋아요북마크

댓글0

아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.