모바일에서 가로로 긴 배너가 알아볼 수 없게 작아진 이유
문제 발생
데스크톱용 와이드 배너를 그대로 모바일에 내렸더니 인물이 보이지 않을 만큼 작아졌습니다. srcset으로 해상도를 여러 개 준비했지만 크기만 달라질 뿐 구도는 같았습니다.
AVIF로 바꿔 용량을 줄이고 싶었는데, 지원하지 않는 브라우저에서 이미지가 깨질까 봐 손을 못 대고 있었습니다.
원인 분석
두 요구는 서로 다른 도구가 담당합니다. MDN이 구분해 설명합니다.
해상도 전환은 <img>의 srcset/sizes입니다 — 같은 이미지의 밀도·크기만 다른 버전을 고릅니다. 브라우저가 데이터 절약 모드에서 낮은 밀도를 고를 수 있다는 이점도 여기서 나옵니다.
아트 디렉션은 <picture>입니다 — MDN 표현대로 media 조건에 따라 이미지를 잘라내거나 변형하는 것, 예를 들어 작은 화면에서 디테일이 너무 많은 이미지의 단순한 버전을 로드하는 경우입니다. 즉 다른 이미지를 주는 일입니다.
선택 규칙도 명확합니다. 브라우저는 각 <source>의 srcset, media, type을 순서대로 검사하고 처음 맞는 것을 선택합니다. 그래서 순서가 곧 우선순위입니다.
포맷 폴백은 type이 담당합니다 — user agent가 주어진 타입을 지원하지 않으면 그 <source>는 건너뜁니다.
그리고 <picture>에는 정확히 하나의 <img>가 반드시 있어야 합니다. MDN이 두 역할을 적습니다 — 이미지의 크기와 표시 속성을 기술하고, 어떤 <source>도 쓸 수 없을 때의 폴백이 됩니다.
해결 방안
- 구도가 달라야 하면
<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>-
좁은 조건을 먼저 씁니다. 처음 맞는 것이 이기므로 순서를 바꾸면 조용히 잘못된 이미지가 나갑니다.
-
alt,width,height는<img>에 둡니다.<source>에 쓴 속성은 무시되고, 크기를 비워두면 레이아웃 이동(CLS)이 생깁니다. -
포맷 폴백만 필요하면
media없이type만 씁니다. 구도가 같다면 아트 디렉션이 아니라 포맷 협상입니다. -
프레임워크의 이미지 컴포넌트를 먼저 확인합니다. Next.js의
next/image처럼 해상도 전환과 포맷 협상을 이미 처리하는 도구를 쓰고 있다면, 손으로<picture>를 짜야 하는 건 아트 디렉션이 필요한 자리뿐입니다.
댓글0
댓글을 남기려면 로그인이 필요해요. 로그인
아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.