이미지가 로드될 때마다 아래 내용이 밀려 내려간 이유와 aspect-ratio
문제 발생
목록에서 이미지가 하나씩 로드될 때마다 아래 카드들이 아래로 밀렸습니다. 읽고 있던 줄이 갑자기 움직이고, 누르려던 버튼이 밀려나 다른 것이 눌리기도 했습니다.
<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; }해결 방안
- 비율을 CSS로 예약합니다.
img {
width: 100%;
height: auto;
aspect-ratio: 16 / 9;
}- HTML의
width/height속성도 함께 씁니다. 최신 브라우저는 이 두 속성에서 비율을 계산해 스스로 자리를 잡습니다. CSS가 로드되기 전에도 동작하므로 둘 다 두는 편이 안전합니다. 실제 표시 크기와 같을 필요는 없고 비율만 맞으면 됩니다.
<img src="/thumb.webp" alt="" width="1600" height="900" />- 실제 비율을 모르는 이미지에는
auto를 함께 씁니다. 지정한 비율로 자리를 잡았다가, 로드된 뒤에는 이미지의 고유 비율로 전환됩니다.
img { width: 200px; aspect-ratio: 3 / 2 auto; }- 잘림을 어떻게 다룰지 정합니다. 예약한 비율과 실제 비율이 다르면 이미지가 늘어나 보입니다.
object-fit: cover로 채우고 필요하면object-position으로 기준점을 정합니다.
img { aspect-ratio: 16 / 9; object-fit: cover; }- 이미지 말고도 씁니다. 지도 임베드, 비디오 래퍼, 스켈레톤 자리 표시자처럼 "비율이 정해진 상자"에는 예전의
padding-top: 56.25%트릭 대신aspect-ratio한 줄이면 됩니다.
댓글0
댓글을 남기려면 로그인이 필요해요. 로그인
아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.