차근차근 이해해 보는 HTML 반응형 이미지

,

반응형 이미지는 세 가지로 생각을 하면 됩니다.

  1. 모니터 픽셀 밀도에 따라서 서로 다른 이미지를 보여 주기(x 단위 사용)
  2. 뷰포트 너비에 따라서 서로 다른 이미지를 보여 주기(picture 태그와 미디어 쿼리 문법 사용)
  3. 뷰포트 너비와 모니터 픽셀 밀도를 동시에 고려해 서로 다른 이미지를 보여 주기(w 단위와 미디어 쿼리 사용)

픽셀 밀도에 따라

이 중 제 생각엔 가장 기본적으로 사용해야 하는 것이 픽셀 밀도에 따라 다르게 보여 주는 것입니다. 스마트폰은 기본적으로 픽셀 밀도가 높죠. 요즘은 맥도 많이 사용하고요.

<img width="120" height="120"
srcset="https://mydomain.com/photo-120px.jpg 1x,
https://mydomain.com/photo-240px.jpg 2x"
src="https://mydomain.com/photos.jpg"
alt="픽셀 밀도에 따른 반응형 이미지, 1x 2x가 픽셀 밀도 표시 부분">

뷰포트 너비에 따라

뷰포트 너비에 따라 다른 이미지를 보여줄 때는 picturesource를 사용합니다. CSS에 익숙한 분들은 금세 이해할 수 있을 겁니다. (사실 정확히 말하면 “미디어 쿼리에 따라”라고 해야겠죠. 대부분의 경우 미디어 쿼리의 용도는 뷰포트 너비일 겁니다. 따라서 쉬운 이해를 위해서는 이렇게 생각하셔도 무방할 듯합니다.)

<picture class="u-12/12">
<source width="480" height="270"
srcset="https://mydomain.com/for-narrow.jpg"
media="(max-width: 640px)">
<source width="1000" height="1000"
srcset="https://mydomain.com/for-wide.jpg"
media="(min-width: 641px)">
<img src="https://mydomain.com/for-wide.jpg"
width="1000" height="1000"
alt="뷰포트 너비에 따른 이미지 교체">
</picture>

픽셀 밀도와 뷰포트 너비를 섞어서

여기까지는 이해하기 쉬운데요. 이제부터 살펴 볼 픽셀 밀도와 뷰포트 너비를 섞는 사용법은 조금 까다롭습니다.

여기서 핵심은 w라는 단위를 이해하는 것입니다. 이 단위만 이해하면 쉽습니다.

일단 코드 모양이 아래 같은 형식이죠. (MDN의 반응형 이미지 설명서에서 가져온 코드입니다.)

<img
srcset="elva-fairy-480w.jpg 480w, elva-fairy-800w.jpg 800w"
sizes="(max-width: 600px) 480px,
800px"
src="elva-fairy-800w.jpg"
alt="요정 옷을 입은 엘바" />

w 단위

위에서 w실제로 필요한 이미지의 픽셀수를 가리킵니다. 웹개발에서 이는 논리적 픽셀수픽셀 밀도를 곱한 수를 가리킵니다.

픽셀 밀도가 2인 스크린을 생각해 보세요. 이런 스크린에서는 논리상 100px짜리인 이미지를 깨짐 없이 표시하려면 실제 사이즈가 200px인 이미지가 필요합니다(100 곱하기 2). 이 때 실제 필요한 이미지의 사이즈인 200을 200w라고 표현합니다.

sizes 규칙의 px 단위

다음으로 sizes 규칙을 알아 봅시다. sizes를 보시면

  1. 조건(max-width: 600px)이 있고 뒤에 480px이라고 돼 있습니다.
  2. 쉼표 뒤엔 조건이 없고 800px이라고 돼 있습니다.
  3. 👉 특정 조건일 때는 480px 이미지를, 그 외엔 800px 이미지를 사용한다는 뜻입니다.

sizes 속성에서는 w가 아니라 다시 px 단위를 사용하고 있습니다. 웹 프론트엔드에서 px 단위는 언제나 화면 밀도와 무관한 논리상 픽셀 수를 가리킵니다. 스크린의 물리적 픽셀 밀도와 상관없는 논리적 단위죠. 이 논리적 px은 뷰포트 너비에서 대상이 차지하는 크기를 나타냅니다.

srcset과 sizes를 조합한 브라우저의 동작

이제 브라우저는 sizes에 정의된 조건에 따라서 srcset에서 이미지를 선택하는 과정을 이해하면 끝입니다.

  1. 위 코드에선 뷰포트 너비가 600px일 때까지는 논리상 너비 480px인 이미지를 고르게 됩니다.
  2. 그 외의 뷰포트 너비에서는 800px인 이미지를 고르게 됩니다(800px 규정 앞엔 조건문이 없으므로).

여기서 주의깊게 볼 부분이 있습니다. 뷰포트가 600px 이하일 때 sizes에서 요구하는 것은 논리상 너비 480px짜리 이미지라는 것입니다. 그러니 픽셀 밀도가 2인 보통의 스마트폰에서 실제로 필요한 이미지 사이즈는 960px입니다. 이 부분을 이해하시면 거의 이해하신 겁니다.

이제 연결해 생각해 봅시다. srcset에는 실제 이미지 너비가 480인 이미지(480w)와 800인 이미지(800w)가 제시돼 있습니다. 그렇다면 뷰포트 600px 이하의 픽셀 밀도 2인 상황에서는 두 이미지 중 어떤 이미지가 선택될까요?

맞습니다. 800w가 선택됩니다.

픽셀 밀도가 1인 경우에는 480w가 선택됩니다.

아래는 실제로 그런지 브라우저에서 픽셀 밀도를 조정하면서 테스트해 보는 영상입니다.

참고로 이 페이지에서 적당한 이미지를 선택하는 모습을 실시간으로 살펴볼 수 있습니다.

나가며

이렇게 세 단계로 나눠서 살피면 이해하기 쉽습니다. (1)화면 밀도에 따라, (2)뷰포트에 따라, (3)둘을 섞어서.

화면 밀도에 따른 반응형 이미지는 모든 경우에 하는 것이 좋습니다.

뷰포트에 따라 이미지를 달리 하는 경우는 모바일용 이미지와 데스크톱용 이미지가 서로 디자인이나 구도 자체가 다른 경우입니다.

그리고 둘을 결합해서 사용할 정도로 복잡한 경우를 저는 아직 만나보지 못했습니다.

이상입니다.

카테고리 글 목록 👉

,

대표글

댓글 남기기