WeniVooks

검색

HTML/CSS 에센셜

반응형 이미지

1. 반응형 이미지

(좌)데스크톱 화면 (우)모바일화면 / 출처: 토스(https://toss.im/)

웹페이지는 다양한 디바이스 환경을 고려하여 적절한 이미지를 제공해야 합니다. 이를 위해 네트워크, 메모리, 성능 등을 고려한 다양한 크기의 이미지를 제공해야 하며, 이는 해상도 전환 문제로 이어집니다. 또한 화면 크기, 방향 등을 고려한 다양한 레이아웃의 이미지를 제공해야 하는데, 이는 아트 디렉션 문제로 연결됩니다.

1.1 해상도 전환(resolution switching)

해상도 전환은 단지 크기만 다른 동일한 컨텐츠의 이미지를 보여주고 싶을 때 사용하는 방법입니다. 작은 화면에서 큰 이미지를 표시하는 것은 대역폭을 낭비하게 되어 비효율적이며, 큰 화면에 작은 사이즈의 래스터 이미지(ex.jpg 픽셀단위의 이미지)를 확대하여 깨져 보이게 하는 것 또한 좋은 방법이 아닙니다.

렌더링: 400400px / 실제: (좌)20002000px (우)100*100px

해상도 전환은 다양한 디바이스의 해상도, 크기에 따라 적절한 이미지를 보여주기 위한 방법입니다. 이는 큰 이미지가 필요 없는 좁은 화면에서 더 작은 이미지를 제공하고 싶을 때, 그리고 선택적으로 다양한 해상도의 이미지를 고밀도/저밀도 화면에 제공하고 싶을 때 유용합니다. 이 문제를 해결하기 위한 방법으로는 벡터 그래픽 이미지(SVG 이미지) 사용하기와 요소에 srcsetsizes 속성을 이용하는 방법이 있습니다. 벡터 이미지는 용량도 작고 확대해도 깨지지 않는 장점이 있으나, 그래픽이 복잡해지면 용량이 늘어날 수 있어 주의가 필요합니다. 보통 간단한 그래픽, 패턴, 인터페이스 요소 등에 적합합니다.

1.1.1 srcset

srcset 속성은 브라우저에 제시할 이미지 경로와 그 이미지의 원본 크기를 지정합니다. 각 쉼표(,)로 구분한 목록을 작성하며, 이미지 경로 고유 픽셀너비 의 형태로 작성합니다. 이 속성은 같은 비율의 다양한 이미지 크기(해상도)를 가지는 동일 이미지들을 최소 2개 이상 명시해야 합니다.

원본 사이즈 360px*360px
원본 사이즈 720px*720px
원본 사이즈 1440px*1440px

브라우저는 네트워크, 메모리, 성능, 시간 등을 고려하여 최적의 이미지를 선택합니다. 이때 px 단위가 아닌 w, x 서술자를 사용합니다.

w 서술자

w 서술자는 이미지의 원본 너비를 브라우저에게 알려줍니다. w 서술자가 적용되면 이미지 크기는 기본적으로 뷰포트의 100%를 차지하게 되며, width, sizes 등의 속성으로 이를 변경할 수 있습니다. 주의할 점은 w 서술자를 사용한 경우 src 속성을 무시한다는 것입니다.

x 서술자

x 서술자는 화소의 밀도를 나타냅니다. 이는 디바이스 화소 밀도에 따른 이미지를 로딩하도록 브라우저에게 알려줍니다. 화소밀도(pixel density)는 동일한 면적에 들어가는 화소의 수를 의미하며, 화소의 갯수가 많을수록 더 높은 해상도의 기기입니다. 개발자 도구의 콘솔창에서 window.devicePixelRatio 명령어를 입력하면 현재 보고 있는 화면의 화소밀도를 알 수 있습니다. 서술자를 포함하지 않은 경우 기본값인 1x로 간주됩니다.

주의

  1. w 서술자와 x 서술자는 동시에 사용할 수 없습니다.

  2. srcset속성을 사용할수 없는 브라우저를 대비하여 src 속성은 필수로 입력해주세요.

정리하자면, 디바이스 화면의 넓이에 따라서 어떤 이미지를 랜더링 할지 정하고 싶다면 W 서술자를, 디바이스 화면의 픽셀 밀도에 따라서 어떤 이미지를 랜더링 할지 정하고 싶다면 X서술자를 사용하면 됩니다. 예를 들어 진행하는 프로젝트가 모바일 따로, 데스크탑 따로, 테블릿 따로 앱을 만든다면 x 서술자를 사용하고, 모든 기기에 대응해 반응형 앱을 만든다면 w서술자를 사용하는 것을 고려할 수 있습니다.

srcset은 브라우저에게 이미지 선택권을 위임하는 속성입니다.

srcset 속성을 사용하면 개발자가 원하는 이미지를 선택 및 강제할 수 없습니다. 브라우저가 알아서 네트워크의 속도, 이미지의 용량, 화면의 해상도 등 많은 조건을 고려해서 최적의 이미지를 결정합니다. 만약, 원하는 해상도에 맞게 출력할 결과를 정확히 명시하고 싶다면 CSS의 @media 미디어쿼리를 사용하세요

1.1.2 sizes

sizes 속성은 미디어(뷰포트) 조건문이 참인 경우, 이미지가 차지하게 될 사이즈를 브라우저에게 알려줍니다. 이때 슬롯의 너비에는 % 값을 넣을 수 없으며, px, em 또는 vw를 사용해야 합니다. 미디어 조건문이 없는 마지막 줄은 조건문이 참인 경우가 없을 때의 기본값을 나타냅니다. 주의할 점은 첫번째 조건문이 맞으면 나머지 조건문을 무시한다는 것입니다. 따라서 미디어 조건문의 순서에 유의해야 합니다. srcset이 비어있거나 너비 서술자를 사용하지 않은 경우, 또는 srcset에서 x서술자를 사용할 때는 sizes 속성이 아무 효과도 없습니다. 또한 sizeswidth를 같이 작성할 경우 width를 우선적으로 적용합니다.

CSS 충돌 주의

size 속성을 사용할 때, CSS를 통한 이미지의 사이즈를 컨트롤 하는 방법과 충돌할 수 있는 점에 주의하세요. CSS 스타일이 sizes 속성보다 우선 적용됩니다.

sizes 작성 유무

sizes 속성의 작성 여부에 따라 브라우저의 이미지 선택 방식이 달라질 수 있습니다. 아래 두 코드를 비교해 보겠습니다.

<img
  **srcset**="
/images/html-css/chapter16/05.png **360w**,
/images/html-css/chapter16/06.png **720w**,
/images/html-css/chapter16/07.png **1440w**"
  src="/images/html-css/chapter16/05.png"
  alt="다람쥐 캐릭터 칠리"
/>
<img
  **srcset**="
/images/html-css/chapter16/05.png **360w**,
/images/html-css/chapter16/06.png **720w**,
/images/html-css/chapter16/07.png **1440w**"
  src="/images/html-css/chapter16/05.png"
  alt="다람쥐 캐릭터 칠리"
/>
<img
  srcset="
    /images/html-css/chapter16/05.png  360w,
    /images/html-css/chapter16/06.png  720w,
    /images/html-css/chapter16/07.png 1440w
  "
  sizes="
		(max-width: 360px) 200px, 
		(max-width: 720px) 400px,
											 600px"
  src="/images/html-css/chapter16/05.png"
  alt="다람쥐 캐릭터 칠리"
/>
<img
  srcset="
    /images/html-css/chapter16/05.png  360w,
    /images/html-css/chapter16/06.png  720w,
    /images/html-css/chapter16/07.png 1440w
  "
  sizes="
		(max-width: 360px) 200px, 
		(max-width: 720px) 400px,
											 600px"
  src="/images/html-css/chapter16/05.png"
  alt="다람쥐 캐릭터 칠리"
/>
1.2 아트 디렉션(art direction)

아트 디렉션은 연출 방향을 의미하며, 중요한 부분을 자른 이미지를 보여주는 기법입니다. 반응형 이미지에서 이미지의 의도가 제대로 전달되도록 기기에 따라 사진의 핵심을 확대해서 보여주는 형태의 방법을 말합니다. 이는 다른 비율, 다양한 크기의 이미지를 사용하고 싶을 때 특히 유용합니다. 예를 들어, 데스크톱 환경에서는 전체 풍경을 보여주는 가로 이미지를 사용하고, 모바일 환경에서는 주요 대상을 좀 더 가깝게 확대해서 보여주는 세로 이미지를 사용할 수 있습니다. 이러한 아트 디렉션을 구현하기 위해 사용하는 요소가 바로 입니다.

데스크톱: 전체 풍경을 보여주는 가로 이미지
모바일: 주요 대상을 좀더 가깝게 확대해서 보여주는 세로 이미지
1.2.1 <picture> 요소 사용하기

<picture> 요소는 여러 <source> 요소와 하나의 <img> 요소를 포함합니다. 각 <source> 요소는 다른 이미지 소스를 지정하며, 브라우저는 이 중 가장 적합한 소스를 선택하여 표시합니다. 다음은 <picture> 요소를 사용한 예시입니다:

<picture>
  <source media="(min-width: 1024px)" srcset="/img/lication-chilli.png" />
  <source media="(max-width: 1023px)" srcset="/img/lication-chilli2.png" />
  <img src="lication-chilli.png" alt="위니브 리케이션 속 칠리" />
</picture>
<picture>
  <source media="(min-width: 1024px)" srcset="/img/lication-chilli.png" />
  <source media="(max-width: 1023px)" srcset="/img/lication-chilli2.png" />
  <img src="lication-chilli.png" alt="위니브 리케이션 속 칠리" />
</picture>
  • <source> 요소

<source> 요소는 브라우저가 선택할 수 있는 이미지 소스를 제공합니다. 브라우저는 <source> 요소를 순서대로 검토하여 가장 적합한 요소를 선택합니다. 만약 일치하는 항목이 없거나 브라우저가 <picture> 요소를 지원하지 않는 경우, <img> 요소가 사용됩니다. <source> 요소는 type과 media 속성을 가질 수 있습니다. type 속성은 이미지의 MIME 타입을 지정하며, 브라우저가 해당 타입을 지원하지 않으면 그 <source> 요소를 건너뜁니다. 다음은 type 속성을 사용한 예시입니다.

<picture>
  <source srcset="photo.avif" type="image/avif" />
  <source srcset="photo.webp" type="image/webp" />
  <img src="photo.jpg" alt="photo" />
</picture>
<picture>
  <source srcset="photo.avif" type="image/avif" />
  <source srcset="photo.webp" type="image/webp" />
  <img src="photo.jpg" alt="photo" />
</picture>

media 속성은 미디어 쿼리를 지정하여 특정 조건에서만 해당 소스를 사용하도록 할 수 있습니다. 이 속성은 아트 디렉션에서 주로 사용되며, sizes 속성 내에 미디어 조건문을 제공해서는 안 됩니다.

  • <img> 요소

<picture> 요소 내의 <img> 요소는 필수적으로 포함되어야 하며, src와 alt 속성을 가져야 합니다. 이 요소는 <source> 요소 중 사용 가능한 이미지가 없을 경우 대체 이미지로 사용됩니다.

최신 이미지 포맷 사용하기 <picture> 요소를 사용하면 브라우저 지원 상황에 따라 최신 이미지 포맷을 제공할 수 있습니다. 다음은 SVG, WebP, PNG 포맷을 순차적으로 제공하는 예시입니다.

<picture>
  <source type="image/svg+xml" srcset="pyramid.svg" />
  <source type="image/webp" srcset="pyramid.webp" />
  <img src="pyramid.png" alt="정삼각형 4개로 만든 일반적인 피라미드" />
</picture>
<picture>
  <source type="image/svg+xml" srcset="pyramid.svg" />
  <source type="image/webp" srcset="pyramid.webp" />
  <img src="pyramid.png" alt="정삼각형 4개로 만든 일반적인 피라미드" />
</picture>

1.3 정리

반응형 이미지 기법에는 크게 두 가지 접근 방식이 있습니다. srcsetsizes 속성을 사용하는 방법은 동일한 크기(동일한 비율, 동일한 내용)의 이미지를 다양한 디바이스의 적절한 해상도와 크기로 보여주고 싶을 때 사용합니다. 이 방법은 브라우저가 알아서 이미지를 선택한다는 점에 유의해야 합니다. 반면, <picture><source> 요소를 사용하는 방법은 브라우저의 환경, 화면의 크기와 방향 등을 고려하여 다양한 이미지를 보여주고 싶을 때 사용합니다. 이 방법은 개발자가 더 세밀하게 이미지 선택을 제어할 수 있습니다.

이미지가 정보전달의 역할없이 단순 스타일링이 목적이라면

@media 미디어쿼리를 사용하여 CSS의 background 속성으로 넣어주셔도 됩니다.

🙋‍♀️ 자바스크립트로 처리하면 안되나요?

브라우저 렌더링 시 메인 파서가 CSS와 자바스크립트를 해석하기 전에 이미지들을 미리 불러오기 시작합니다.

자바스크립트로 처리 시 아래와 같이 동작합니다.

  1. <img> 요소를 불러온다
  2. 자바스크립트로 뷰포트 너비를 감지한다
  3. 필요시 더 작은 크기의 이미지로 변경한다

이럴경우 그 시점에 이미지가 로드된 이후이고, 작은 크기의 이미지까지 불러와야 해서 비효율적이라고 할 수 있습니다.

MDN picture 요소MDN source 요소
16.3 미디어 쿼리