<img>
태그로 반응형 이미지 구현하기
HTML의 <img>
태그로 반응형 이미지(브라우저의 가로 사이즈와 해상도에 따라)를 자동 조절하고 구현하게 할 수 있는 srcset
속성과 sizes
속성의 개념 이해와 사용법에 대해 알아보겠습니다.
HTML에서 제공하는 반응형 이미지 기술
요즘은 다양한 디바이스로 웹을 탐색하기 때문에 반응형 웹 디자인(Responsive web design)을 구현하는 원리를 이해하고 다룰 수 있는 기술을 익히는 것이 웹 디자인에 있어서 매우 중요한 자리로 매김하였습니다.
반응형 웹 디자인을 구현하기 위한 방법으로 대표적인 것은 CSS로 반응형 웹 디자인을 구현하는 방법입니다. 물론 자바스크립트의 도움을 받으면 좀 더 세련된 반응형 웹 디자인을 구현할 수도 있습니다. 또 하나의 방법을 말하자면 HTML에서 제공하는 반응형 이미지 기술를 이용하는 것입니다. 이 방법은 CSS로 반응형 웹 디자인을 구현하는 방법과 함께 사용하는 것이 효율적이며, 반응형 웹 디자인을 구현하는 방법 중 일부분의 기술입니다.
HTML에서 제공하는 반응형 이미지 기술은 두 가지가 있습니다.
<img>
태그에srcset
속성과sizes
속성을 이용하는 방법- <picture> 태그의 <source>태그와 srcset 속성, media 속성 및 type 속성을 사용하는 방법
이 글에서는 <img>
태그에 srcset
속성과 sizes
속성을 사용하는 방법에 대해 다룹니다.
<img>
태그로 반응형 이미지를 구현하기 위해 srcset
속성과 sizes
속성 도입
<img>
태그의 기본 속성
<img src="image-path.jpg" width="200" height="500" alt="이미지 대체 텍스트">
위 예제 코드는 <img>
태그의 기본 속성을 마크업한 것입니다.
이 속성들 중에서 src
속성과 width
속성을 주목하기 바랍니다.
src
속성: 불러올 이미지 소스의 경로를 지정합니다.width
속성: 불러올 이미지 소스의 너비(가로 사이즈)를 지정합니다.
srcset
속성과 sizes
속성은 <img>
태그로 반응형 이미지를 구현하기 위해 도입된 속성입니다.
srcset
속성은 src
속성과 관련이 있고,
sizes
속성은 width
속성과 관련이 있습니다.
srcset
속성 →src
속성으로 구현할 수 없는 브라우저의 뷰포트 너비나 디스플레이 해상도에 대한 반응형 이미지 소스 지정을 위해 도입된 속성입니다.sizes
속성 →width
속성으로 구현할 수 없는 브라우저의 뷰포트 너비와srcset
속성으로 지정한 반응형 이미지 너비와의 관계를 지정하기 위해 도입된 속성입니다.
뷰포트(viewport)는 웹 브라우저 용어로, 현재 창(또는 전체 화면 모드로 문서를 보고 있는 경우 화면)에 표시되는 문서의 부분으로 웹 페이지가 보여지는 영역을 의미합니다.
srcset
속성과 sizes
속성으로 반응형 이미지를 구현한다는 의미
브라우저의 뷰포트 너비나 디스플레이 해상도에 대해 반응하는 이미지 소스를 srcset
속성으로 지정하고, 브라우저의 뷰포트 너비와 srcset
속성으로 지정한 반응형 이미지 너비와의 관계를 sizes
속성으로 지정해서 반응형 이미지를 구현한다는 의미입니다.
여기에서 sizes
속성을 사용하더라도 sizes
속성은 필요하지 않으면 사용하지 않아도 됩니다. 이 부분은 차차 설명할 예정입니다.
<img>
태그 srcset
속성
<img>
태그에서 사용하는 srcset
속성은 브라우저의 뷰포트 너비나 디스플레이 해상도에 대한 반응형 이미지 소스(들)를 지정합니다. 이미지 소스는 여러 개로 지정할 수 있습니다. 이는 반응형 이미지를 위해 브라우저에게 여러 개의 이미지 중에서 최적의 이미지를 선택하도록 도와주는 속성으로 디스플레이 해상도나 브라우저의 뷰포트 너비에 따라 적절한 이미지를 렌더링하도록 하여 최적의 페이지의 로딩 속도와 이미지 해상도를 제공하기 위함입니다.
알아두세요!
srcset
속성은 <img>
뿐만 아니라, <picture>
태그의 <source>
태그에서도 사용합니다.
<picture>
태그의 <source>
태그에서 사용하는 srcset
속성은 미디어 쿼리를 이용하여 다양한 상황에 맞춰 다른 이미지를 선택하는 데 사용하지만, <img>
태그에서 사용하는 srcset
속성은 단순히 브라우저가 디스플레이 해상도나 브라우저의 뷰포트 너비에 적절한 이미지를 선택하는 데 사용합니다.
길게 설명한 <img>
태그 srcset
속성에 대한 내용을 간추려 보겠습니다.
<img>
태그 srcset
속성은
1. 디스플레이 해상도나
2. 브라우저 뷰포트의 너비에 맞춘
최적의 반응형 이미지 소스를 설정하기 위해 사용하는 속성이다.
srcset
속성 구문
구문 설명에 앞서 <img>
태그에서 srcset
속성은
브라우저의 뷰포트 너비나
디스플레이 해상도에 대한 반응형 이미지 소스를 지정하기 위해서 도입된 속성이라는 것을 잊지 마세요!
<img>
태그 srcset
속성 서식
<img
srcset="
랜더링할후보이미지url-1 랜더링할후보이미지url-1이랜더링할뷰포트최대너비혹은최대디스플레이해상도1,
랜더링할후보이미지url-2 랜더링할후보이미지url-2가랜더링할뷰포트최대너비혹은최대디스플레이해상도2,
랜더링할후보이미지url-3 랜더링할후보이미지url-3이랜더링할뷰포트최대너비혹은최대디스플레이해상도3,
랜더링할후보이미지url-n 랜더링할후보이미지url-n이랜더링할뷰포트최대너비혹은최대디스플레이해상도n,
"
src="default.jpg"> <!-- srcset이 올바르게 설정되었다면 src 속성은 없어도 무방함 -->
srcset
속성 구문은 복잡해 보이지만 위에서 보여 준 것처럼 각 행에 속성 값을 나눠 적으면 이해하기 어렵지 않습니다. 각 값은 쉼표로 구분한 목록으로 적고, 목록의 각 부분은 세 부분으로 구성됩니다. 이제 각 내용을 살펴 보겠습니다.
<img>
태그에서 srcset
속성은 브라우저에게 제시할 이미지 목록과 그 반응형 이미지 조건인 뷰포트 너비를 기준으로 랜더링해야 하는 최대 너비나 최대 디스플레이 해상도를 정의합니다. 각 쉼표 앞에 이렇게 적습니다.
- 이미지 파일 경로(랜더링할후보이미지url-n)
- 공백
- 랜더링할후보이미지url-n이랜더링할뷰포트최대너비혹은최대디스플레이해상도n
아직까지는 생소하고 어렵게 느껴질 것입니다. 다음 세 개의 예제를 통해 살펴 보면 좀 더 이해가 갈 것입니다.
- 브라우저의 뷰포트 너비에 대한 이미지 소스를 지정한 예제 코드
- 디스플레이 해상도에 대한 이미지 소스를 지정한 예제 코드
- 브라우저의 뷰포트 너비에 대한 이미지 소스와 디스플레이 해상도에 대한 이미지 소스를 함께 지정한 예제 코드
브라우저의 뷰포트 너비에 대한 이미지 소스를 지정한 예제 코드
<img>
태그 srcset
속성 서식에 브라우저의 뷰포트 너비에 대한 이미지 소스를 지정한 예제 코드
<img
srcset="
heart-small-480px.jpg 480w,
heart-medium-700px.jpg 700w,
heart-large-1000px.jpg 1000w
"
src="heart-large-1000px.jpg"
alt="하트"> <!-- srcset이 설정되었다면 src 속성은 무시됨 -->
위 예제는 브라우저의 뷰포트 너비에 대한 이미지 소스를 지정한 것입니다.
heart-small-480px.jpg 480w
: 뷰포트 너비가400w
이하일 때heart-small-480px.jpg
가 랜더링됩니다.heart-medium-700px.jpg 700w
: 뷰포트 너비가700w
이하일 때heart-medium-700px.jpg
가 랜더링됩니다.heart-large-1000px.jpg 1000w
: 뷰포트 너비가1000w
이하일 때heart-large-1000px.jpg
가 랜더링됩니다.
480w
,
700w
,
1000w
에서 사용된
w
단위를 주목하시기 바랍니다. 이 w
단위는 w
descriptor라 부르는데, viewport width(뷰포트 너비)의 약자이며, 길이 단위로 환산하면 px
과 동일합니다.
480w
는 뷰포트 최대 너비 480px이라는 뜻입니다. 즉, 뷰포트 너비 480px 이하라는 뜻과 동일합니다. 이를 CSS의 미디어 쿼리로 표현한다면 @media (max-width: 480px)
라고 표현할 수 있습니다. 즉, heart-small-480px.jpg 480w
의 의미는 "뷰포트 너비 480px 이하에서는 heart-small-480px.jpg
가 랜더링된다"라는 의미입니다.
700w
는 뷰포트 최대 너비 700px이라는 뜻입니다. 즉, 뷰포트 너비 700px 이하라는 뜻과 동일합니다. 이를 CSS의 미디어 쿼리로 표현한다면 @media (max-width: 700px)
라고 표현할 수 있습니다. 즉, heart-medium-700px.jpg 700w
의 의미는 "뷰포트 너비 700px 이하에서는 heart-medium-700px.jpg
가 랜더링된다"라는 의미입니다.
1000w
는 뷰포트 최대 너비 1000px이라는 뜻입니다. 즉, 뷰포트 너비 1000px 이하라는 뜻과 동일합니다. 이를 CSS의 미디어 쿼리로 표현한다면 @media (max-width: 1000px)
라고 표현할 수 있습니다. 즉, heart-large-1000px.jpg 1000w
의 의미는 "뷰포트 너비 1000px 이하에서는 heart-large-1000px.jpg
가 랜더링된다"라는 의미입니다.
srcset
속성이 설정되어 있다면 src
속성은 무시됩니다.
srcset
속성이 설정되어 있지만 조건에 부합되는 이미지가 없다면 가장 근사치에 있는 조건값의 이미지가 랜더링 됩니다. 만약에 뷰포트의 너비가 1800px이라고 가정합시다. 위 예제 코드를 기준으로 조건에 부합되는 이미지는 없습니다. 이럴 경우 heart-large-1000px.jpg 1000w
가 가장 근사치의 조건값이 되므로 heart-large-1000px.jpg
가 랜더링됩니다.
주의 하세요!
만약에 뷰포트의 너비가 500px이라고 가정합시다.
이럴 경우 위 예제 코드를 기준으로 heart-medium-700px.jpg 700w
과 heart-large-1000px.jpg 1000w
둘 다 조건에 부합됩니다. 어떤 이미지가 랜더링 될까요? 이렇게 여러 개의 기준이 부합될 경우에는 속성의 값을 마크업한 순서 기준으로 위에서 아래 기준, 혹은 왼쪽에서 오른쪽 기준으로 조건에 부합되는 첫 번째로 만나는 조건이 랜더링됩니다. 즉 heart-medium-700px.jpg 700w
가 랜더링됩니다. 따라서, 뷰포트 너비 기준으로 w
descriptor를 사용할 경우 작은 값부터 지정해야 합니다. 그렇지 않을 경우 예상치 못한 결과가 발생할 수있습니다.
꼭 알아두세요!
명세서에서는 랜더링할 후보 이미지에 w
descriptor를 사용할 경우 뷰포트 너비를 랜더링할 후보 이미지의 실제 가로 사이즈로 지정하라도 되어 있습니다. 이는 혹시나 랜더링할 후보 이미지 사이즈보다 큰 w
descriptor값이 설정되어 있을 경우 이미지가 확대되는 현상이 발생하여 해상도가 떨어지는 문제(이를 픽셀화 현상이라고 합니다.)가 발생할 수 있기 때문입니다.
srcset 속성에 대한 명세서를 참조하시기 바랍니다.
하지만 이는 랜더링할 이미지가 뷰포트 기준의 너비의 해상도가 필요 없을 경우(CSS나 width
속성으로 랜더링할 이미지의 width값을 조정하는 경우)에는 문제가 되지 않습니다.
디스플레이 해상도에 대한 이미지 소스를 지정한 예제 코드
<img>
태그 srcset
속성 서식에 디스플레이 해상도에 대한 이미지 소스를 지정한 예제 코드
<img
srcset="
heart-small-480px.jpg 1x,
heart-medium-700px.jpg 2x,
heart-large-1000px.jpg 3x
"
src="heart-large-1000px.jpg"
alt="하트"> <!-- srcset이 설정되었다면 src 속성은 무시됨 -->
우선 디스플레이 해상도부터 설명하겠습니다.
디스플레이 해상도는 전문적인 용어로 이미지 밀도(이미지 장치 픽셀 비율, Image Pixel Density)라고 부르기도 하며, 디스플레이 장치의 픽셀 밀도를 나타내는 값(이미지의 픽셀 수와 이미지의 너비와 높이의 비율을 나타내는 값)입니다. 이미지 밀도가 높을수록 이미지의 픽셀 수가 많아져서 이미지가 더 선명하게 보입니다.
일반적으로 브라우저에서 사용되는 디바이스 픽셀 비율은 1x, 2x, 3x 등으로 표시됩니다. 디바이스 픽셀 비율은 디스플레이의 물리적인 픽셀 수와 CSS 픽셀 수 간의 비율을 나타내며, 고해상도 디스플레이의 경우 2x 이상의 픽셀 비율을 가질 수 있습니다. 모바일 디바이스나 고해상도(Retina) 디스플레이는 디스플레이 해상도가 높습니다.
위 예제는 디스플레이 해상도에 대한 이미지 소스를 지정한 것입니다.
heart-small-480px.jpg 1x
: 디스플레이 해상도가1x
이하일 때heart-small-480px.jpg
가 랜더링됩니다.heart-medium-700px.jpg 2x
: 디스플레이 해상도가2x
이하일 때heart-medium-700px.jpg
가 랜더링됩니다.heart-large-1000px.jpg 3x
: 디스플레이 해상도가3x
이하일 때heart-large-1000px.jpg
가 랜더링됩니다.
1x
,
2x
,
3x
에서 사용된
x
단위를 주목하시기 바랍니다. 이 x
단위는 x
descriptor라 부르는데, 배수라는 뜻입니다. 1x
는 1배, 2x
는 두배, 3x
세배라는 뜻입니다. 예를 들어, 1x
인 경우, 이미지의 픽셀 수는 이미지의 실제 크기와 동일하며, 2x
는 이미지의 픽셀 수가 이미지의 실제 크기보다 두 배 높은 고해상도 이미지를 나타냅니다.
디스플레이 해상도에 따른 이미지 소스를 설정하는 것은 주로 고해상도 디스플레이에서 사용되는 것이 일반적입니다. 고해상도 디스플레이는 픽셀 밀도가 높아서 일반 디스플레이보다 더 많은 픽셀을 사용하여 화면을 표시합니다. 따라서 이러한 디스플레이에서는 고해상도 이미지를 사용하여 더 선명하고 고품질의 이미지를 제공하는 것이 좋습니다. 예를 들어 모바일 디바이스나 애플에서 판매하는 디스플레이 등이 이에 해당합니다. 애플은 Retina 디스플레이라고 불리는 고해상도 디스플레이를 자사의 많은 제품에 탑재하고 있습니다.
브라우저의 뷰포트 너비에 대한 이미지 소스와 디스플레이 해상도에 대한 이미지 소스를 함께 지정한 예제 코드
<img>
태그 srcset
속성 서식에 브라우저의 뷰포트 너비에 대한 이미지 소스와 디스플레이 해상도에 대한 이미지 소스를 함께 지정한 예제 코드
<img
srcset="
heart-small-480px.jpg 480w,
heart-medium-700px.jpg 2x,
heart-large-1000px.jpg 1000w
"
src="heart-large-1000px.jpg"
alt="하트"> <!-- srcset이 설정되었다면 src 속성은 무시됨 -->
위의 예제 코드처럼 <img>
태그 srcset
속성 서식에 브라우저의 뷰포트 너비에 대한 이미지 소스와 디스플레이 해상도에 대한 이미지 소스를 함께 지정할 수 있습니다.
하지만 다음 예제 코드는 잘못된 예입니다.
<img>
태그 srcset
속성 서식에 w
descriptor와 x
descriptor를 동시에 하나의 랜더링할 후보 이미지에 적용하는 것은 올바른 구문이 아닙니다.
<img
srcset="
heart-small-480px.jpg 480w 1x,
heart-medium-700px.jpg 700w 2x,
heart-large-1000px.jpg 1000w 3x
"
src="heart-large-1000px.jpg"
alt="하트"> <!-- srcset이 설정되었다면 src 속성은 무시됨 -->
아쉽게도 w
descriptor와 x
descriptor를 동시에 하나의 이미지 후보에 적용하는 것은 올바른 구문이 아닙니다. 각 이미지 후보는 w
descriptor 또는x
descriptor 중 하나만 사용해야 합니다. 브라우저는 이러한 디스크립터들을 사용하여 이미지를 선택하므로, 디스크립터를 올바르게 사용하는 것이 중요합니다.
<img>
태그 sizes
속성
<img>
태그에서 사용하는 sizes
속성은 미디어 쿼리(Media Query)를 통해 w
discriptor를 사용한 srcset
속성이 제공하는 랜더링할 후보 이미지들을 어떻게 사용할지에 대한 규칙을 정의하는데 사용합니다.
따라서, sizes
속성은 srcset
속성이 없이 단독으로 사용할 수 없으며 srcset
속성과 함께 사용할 수 있습니다.
sizes
속성 구문
<img
srcset="
heart-small-480px.jpg 480w,
heart-medium-700px.jpg 700w,
heart-large-1000px.jpg 1000w
"
sizes="
(max-width: 너비) 너비,
(max-width: 너비) 너비,
너비
...
"
src="heart-large-1000px.jpg"
alt="하트"> <!-- srcset이 설정되었다면 src 속성은 무시됨 -->
- 이미지 너비를 나타내는 쉼표로 구분한 하나 이상의 문자열. 각각의 문자열은 다음 구성요소로 이루어집니다.
- 미디어 쿼리(Media Query) - 마지막 목록에서는 생략이 가능합니다.
- 이미지 너비 -
%, cm, mm, in, pt, pc
등의 상대적인 단위와 다른 특정 단위들입니다. 따라서sizes
속성에서는 상대적인 단위와 특정 단위를 사용할 수 없으며, 뷰포트를 기준으로 한 상대적인 단위들(px 포함)과 함께 사용해야 합니다.
아래의 예제를 통해 살펴보겠습니다.
<img>
태그 srcset
속성 서식에 브라우저의 뷰포트 너비에 대한 이미지 소스를 지정한 예제 코드
<img
srcset="
heart-small-480px.jpg 480w,
heart-medium-700px.jpg 700w,
heart-large-1000px.jpg 1000w
"
sizes="
(max-width: 480px) 480px,
(max-width: 700px) 700px,
1000px
"
src="heart-large-1000px.jpg"
alt="하트"> <!-- srcset이 설정되었다면 src 속성은 무시됨 -->
(max-width: 480px) 480px
: 뷰포트의 너비가 480px 이하일 때srcset
속성에서 설정한480w
값과 가장 근사치의 랜더링할 이미지 후보가 랜더링됩니다. 단 근사치의 값이480w
이하인 것이 랜더링됩니다. 여기에서는heart-small-480px.jpg
가 랜더링합니다.(max-width: 700px) 700px
: 뷰포트의 너비가 700px 이하일 때srcset
속성에서 설정한700w
값과 가장 근사치의 랜더링할 이미지 후보가 랜더링됩니다. 여기에서는heart-medium-700px.jpg
가 랜더링합니다.- 조건과 상관없이 가장 근사치의
w
descriptor의 값이 랜더링됩니다. 여기에서는heart-large-1000px.jpg
가 랜더링됩니다.
브라우저 호환성
속성 |
데스크탑 Chrome
|
데스크탑데스크탑 Edge
|
데스크탑 Firefox
|
Safari
|
---|---|---|---|---|
srcset
|
34 | 18 | 38 | 8 |
sizes
|
38 | 12 | 38 | 9.1 |
참고문헌
아래의 참고문헌을 확인해 보세요. 이 글에서 다루지 못한 반응형 이미지에 관련된 속성에 관련된 유용한 정보가 많습니다.
대부분의 참고문헌은 매우 권위있거나, 전 세계 웹 개발자들이 참고하고 있는 문서입니다.