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

모바일에서 가로로 긴 배너가 알아볼 수 없게 작아진 이유

  • #Engineering Note
  • #HTML
  • #Performance

문제 발생

데스크톱용 와이드 배너를 그대로 모바일에 내렸더니 인물이 보이지 않을 만큼 작아졌습니다. srcset으로 해상도를 여러 개 준비했지만 크기만 달라질 뿐 구도는 같았습니다.

AVIF로 바꿔 용량을 줄이고 싶었는데, 지원하지 않는 브라우저에서 이미지가 깨질까 봐 손을 못 대고 있었습니다.

원인 분석

두 요구는 서로 다른 도구가 담당합니다. MDN이 구분해 설명합니다.

해상도 전환<img>srcset/sizes입니다 — 같은 이미지의 밀도·크기만 다른 버전을 고릅니다. 브라우저가 데이터 절약 모드에서 낮은 밀도를 고를 수 있다는 이점도 여기서 나옵니다.

아트 디렉션<picture>입니다 — MDN 표현대로 media 조건에 따라 이미지를 잘라내거나 변형하는 것, 예를 들어 작은 화면에서 디테일이 너무 많은 이미지의 단순한 버전을 로드하는 경우입니다. 즉 다른 이미지를 주는 일입니다.

선택 규칙도 명확합니다. 브라우저는 각 <source>srcset, media, type순서대로 검사하고 처음 맞는 것을 선택합니다. 그래서 순서가 곧 우선순위입니다.

포맷 폴백은 type이 담당합니다 — user agent가 주어진 타입을 지원하지 않으면 그 <source>는 건너뜁니다.

그리고 <picture>에는 정확히 하나의 <img>가 반드시 있어야 합니다. MDN이 두 역할을 적습니다 — 이미지의 크기와 표시 속성을 기술하고, 어떤 <source>도 쓸 수 없을 때의 폴백이 됩니다.

해결 방안

  1. 구도가 달라야 하면 <picture>입니다.
<picture>
  <source srcset="/banner-wide.avif" type="image/avif" media="(width >= 768px)" />
  <source srcset="/banner-wide.jpg" media="(width >= 768px)" />
  <source srcset="/banner-square.avif" type="image/avif" />
  <img src="/banner-square.jpg" alt="가을 시즌 안내" width="800" height="800" />
</picture>
  1. 좁은 조건을 먼저 씁니다. 처음 맞는 것이 이기므로 순서를 바꾸면 조용히 잘못된 이미지가 나갑니다.

  2. alt, width, height<img>에 둡니다. <source>에 쓴 속성은 무시되고, 크기를 비워두면 레이아웃 이동(CLS)이 생깁니다.

  3. 포맷 폴백만 필요하면 media 없이 type만 씁니다. 구도가 같다면 아트 디렉션이 아니라 포맷 협상입니다.

  4. 프레임워크의 이미지 컴포넌트를 먼저 확인합니다. Next.js의 next/image처럼 해상도 전환과 포맷 협상을 이미 처리하는 도구를 쓰고 있다면, 손으로 <picture>를 짜야 하는 건 아트 디렉션이 필요한 자리뿐입니다.

공식 문서

마지막 수정

좋아요북마크

댓글0

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