본문 바로가기
C++ 200제/코딩 IT 정보

HTML srcset sizes 한국에서 제일 쉽게 설명 (retina 포함)

by vicddory 2020. 3. 28.

html 반응형 이미지(responsive image) 핵심인 srcset sizes 두 속성에 대해 자세히 알아보겠습니다. 이미지 크기를 다루는데 필요한 핵심 속성이며, html 기초에 해당하니 끝까지 정독해 주세요.


반응형 이미지(Responsive Image 리스폰시브 이미지)

  • 화면 폭과 단말기(PC, 스마트 폰 등)에 따라 이미지 변환


왜 중요한가

  • 스마트폰 같은 작은 화면에 표시할 때 5000 x 2500 같은 큰 이미지 파일을 보내면, 의미 없는 통신 시간 때문에 사용자가 불쌍
  • 스마트폰에 어울리는 작은 이미지를 PC로 열면 이미지가 흐릿
  • 그래서 표시 장치에 따라 이미지를 바꿀 필요가 있음 : Responsive Image 필요

무엇을 알아야 할까

  • HTML5에서 추가된 속성 img srcset 과 sizes
  • 브라우저는 어떻게 이미지를 선택할까
  • Retina


바로 구현해보자

크기가 다른 플라밍고 사진 4개는 여기서 인용했습니다.


일반적인 img src 사용법

먼저 img 파일에 src를 설정합니다.


<img src="flamingo-fallback.jpg" />


브라우저에서 보겠습니다.



flamingo-fallback.jpg가 표시 되었습니다. 당연하죠?


srcset 지정해보기

img srcset 사용하여 기기의 폭에 따라 다른 이미지를 표시합니다.


    <img
    src="flamingo-fallback.jpg"
    srcset="
    flamingo1x.jpg 1000w,
    flamingo2x.jpg 2000w,
    flamingo3x.jpg 3000w"
    />


여기서 주목할 점은 1000w 2000w 같은 숫자입니다.

이해하기 쉽게, 지금 단계에선 ( w ) = "픽셀 수"라고 생각하셔도 됩니다.



붉은 1000w = "1000 픽셀 폭의 이미지"

파란색 2000w = "2000 픽셀 폭의 이미지"

녹색 3000w = "3000 픽셀 폭의 이미지"


이미지 자신이 폭(픽셀 수)을 브라우저에 전달합니다.


브라우저는 전달받은 정보를 바탕으로 어떤 이미지를 표시할지 선택합니다.

브라우저는 자신의 화면 너비와 이미지 폭을 비교한다

예를 들어 브라우저의 폭이 1920px 이라고 합시다.

브라우저는 이런 생각을 합니다.


"1920px 너비 화면에 이미지를 표시해야지. 근데, 이미지 픽셀 수가 부족하지 않을까?"


방금 전의 html img를 다시 봅시다.



빨간색은 1000 픽셀이라서 1920 화면에 표시하기엔 픽셀 수가 부족합니다.

그래서 이 이미지는 사용할 수 없습니다. 사용할 수 있지만, 이미지가 깨질 겁니다.


"픽셀 수 부족하네"라고 생각하며, 프로세스는 이런 식으로 픽셀을 계산합니다.


1920px 화면 폭에 1000w 이미지 표시 => 1000/1920 => 0.52

1920px 화면 폭에 2000w 이미지 표시 => 2000/1920 => 1.04

1920px 화면 폭에 3000w 이미지 표시 = > 3000/1920 => 1.56


1을 밑도는 숫자(예 : 0.52)는 "이미지의 픽셀 수가 부족" 하다는 뜻입니다.


그래서 브라우저는 "음, 빨간색은 깨지니깐 못 쓰겠네. 비율이 1 이상(픽셀 수가 충분)이면서 가장 작은 이미지는 어떤 것일까"라고 생각한 뒤, 파란색 2000w 이미지를 선택합니다. 녹색 3000w도 비율은 1을 초과해서 사용할 수 있습니다. 하지만 같은 조건을 만족하는 파란색 이미지가 더 작기 때문에 파란색을 선택합니다.


이런 식으로 브라우저는 표시할 이미지를 선택합니다.

실제로 브라우저에서 확인해 보면, flamingo2x가 선택된 것을 알 수 있습니다.


flamingo3x 표시하자

읽기 전에 잠깐 생각해 보세요.

flamingo3x를 표시하려면 어떡해야 할까요?


    <img
    src="flamingo-fallback.jpg"
    srcset="
    flamingo1x.jpg 1000w,
    flamingo2x.jpg 1919w, <-- 여기 주목!
    flamingo3x.jpg 3000w"
    />


그렇습니다!

2x 이미지가 "미안 미안, 나는 1919 픽셀이었어"

라고 전하면 브라우저는 "그럼 너는 1920 픽셀의 화면엔 부족한 이미지구나"라고 판단해서, 다음으로 큰 3x를 선택합니다.



flamingo 1x 표시하자

flamingo 1x는 어떻게 표시할까요?



    <img
    src="flamingo-fallback.jpg"
    srcset="
    flamingo1x.jpg 1921w, <-- 여기 주목!!
    flamingo2x.jpg 2000w,
    flamingo3x.jpg 3000w"
    />


그렇죠!

1x 이미지가 "미안 미안, 사실 나는 1921 픽셀이야"

라고 전하면 브라우저는 "오, 1920 픽셀 화면에 표시하기에 충분하네"라고 생각하여, 1x 이미지를 표시합니다.



어떻습니까. 조금씩 img srcset이 이미지 선택하는 방법 아시겠나요?

왜 화면 너비를 꽉 채울까?

그런데 여기서 한 가지 의문점이 생깁니다.

"브라우저 화면 폭이 1920 픽셀인 건 알았어. 근데, 왜 화면 너비를 꽉 채운다는 조건으로 찾을까? 모든 이미지를 화면 너비에 딱 맞춰서 표시할 필요는 없잖아?" 라고요.


사실, 어디까지나 기본이 화면 너비를 맞춘다는 것뿐이지, 그냥 원하는 데로 뿌려도 됩니다.


그래서 등장한 것이 sizes 라는 html attribute (속성) 입니다.

이렇게 사용합니다.


    <img
    src="flamingo-fallback.jpg"
    srcset="
    flamingo1x.jpg 1000w,
    flamingo2x.jpg 2000w,
    flamingo3x.jpg 3000w"
    sizes="10vw" <-- 여기 주목!!
    />


처음으로 새로운 정보가 브라우저에 전달됩니다.


"나는 화면 폭 가득 채우는 것 말고, 화면 폭의 1/10 크기로 표시할 수 있으면 충분해!"

라는 것을 sizes가 전달합니다.


sizes = "10vw" vw는 "viewport width" 약자로, 100vw가 화면을 가득 채운다고 했을 때의 비율을 나타냅니다.


10vw = 10vw / 100vw = 화면폭의 1/10

50vw= 50vw / 100vw = 화면폭의 절반


이런 느낌입니다.

그래서 sizes=10vw는 "나는 화면폭의 1/10 정도의 사진이야"라는 것을 전달하는 것입니다.


전체 폭의 1/10 정도? 더 작은 이미지로도 충분하잖아!

브라우저가 계산하는 방법이 조금 달라집니다.


"뭐야, 1920 픽셀의 화면을 가득 채워야 한다고 생각했어. 1/10, 192 픽셀로 충분하구나. 그럼 1x 이미지로도 충분하네"


아까는 1920 픽셀의 폭이 필요했으므로 2x 이미지를 선택했지만, 192 픽셀로도 충분하다면, 1x 이미지를 선택합니다.



좀 더 여러 가지 숫자를 사용해 볼까요?

flamingo 3x 표시

그럼, sizes 만 바꿔 3x 이미지를 표시해 볼까요?


    <img
    src="flamingo-fallback.jpg"
    srcset="
    flamingo1x.jpg 1000w,
    flamingo2x.jpg 2000w,
    flamingo3x.jpg 3000w"
    sizes="150vw" <-- 여기 주목!!
    />


"우오오! 나는 화면 폭의 1.5배 이미지가 아니면 안돼!!!"


라는 것을 브라우저에게 알립니다.


브라우저는 "오, 그럼 1920 픽셀의 1.5배, 2880 픽셀이 필요하구나. 2x 이미지는 픽셀이 부족하네!"


라고 생각하며, flamingo3x를 선택합니다.


참고로 sizes를 지정하지 않은 경우 기본값은 100vw이므로, "화면 너비에 딱 맞춰 나를 표시해라"라고 전합니다.


어떻습니까, sizes 사용법도 알게 되셨나요?


끝!

이상, img srcset과 sizes 설명이었습니다. 이것으로 끝!


이라고 생각했는데, Retina

알아야 할 포인트가 하나 남아 있습니다. Retina 입니다.

Retina는 "픽셀이 보통의 2배 이상이며 꽉 찬 이미지"라고 생각하세요.


예를 들어 이런 모바일 기기가 있다고 해볼게요.

  • 10cm의 폭
  • 100 픽셀로 폭을 채움


Retina 적용하면 이렇게 됩니다.

  • 10cm의 폭
  • 200 픽셀로 폭을 채움


요점은 "물리적으로 같은 폭이라 해도 픽셀 2배로 채우는 것"이 Retina 입니다.

엄밀히 다르며, 나중에 보충합니다만, 편의상 이렇게 생각해 주세요.


레티나는 브라우저 픽셀 계산에 큰 영향을 줍니다.


Retina는 픽셀이 부족

    <img
    src="flamingo-fallback.jpg"
    srcset="
    flamingo1x.jpg 1000w,
    flamingo2x.jpg 2000w,
    flamingo3x.jpg 3000w"
    />


여기서 퀴즈!

1920 픽셀 화면에선 어떤 img 이미지 파일이 보일까요?


네. flamingo2x 입니다.

1000w는 픽셀수가 부족해 1920 다음으로 큰 2000w 이미지가 선택됩니다.



똑같은 화면 폭 1920에서 Retina 디스플레이라면 어떤 이미지가 선택될까요?


flamingo3x이 선택됩니다.


Retina 디스플레이는 2배의 픽셀로 채우기 때문에, 1920 픽셀 화면 폭에 표시하려고 1920 x 2 = 3840 픽셀이 필요하죠.


그래서 사실 3x도 픽셀이 부족합니다만, 더 큰 이미지가 없으므로, 브라우저가 "쳇, 이번엔 봐준다"라면서 2배가 안 되는 이미지라도 표시하는 것입니다.

Retina와 Retina 아닌 것을 비교

예를 들어 제 MacBook Pro는 레티나 입니다.

개발자 콘솔에서 이런 명령어를 입력하면 픽셀 비율이 2.0인 것이 확인됩니다.



그리고 외부 모니터에서 같은 명령어를 입력하면 이렇게 됩니다.



그래서 처음 Retina 단말기에서 html img srcset 결과를 확인하면 "어? Retina 랑 결과가 다르네"라고 느낄 수 있습니다.


srcset의 w란 어떤 단위?

처음에 "w는 일단 픽셀이라고 생각하세요"라고 했습니다.

더욱 정확히 말씀드리자면, "이미지의 실제 크기"입니다.

여기서, 아까 flamingo1x.jpg를 finder에서 열어 봅시다.



여기에 적혀있는 "1006"이 w 정체입니다. 그래서 단말기가 1006px을 표현할 수 있습니다.


마지막 1x 2x 3x 표기법

여기까지가 srcset과 sizes에 대한 글이었습니다.


추가로 srcset에는 이런 사용법도 있습니다


    <img
    src="flamingo-fallback.jpg"
    srcset="
    flamingo1x.jpg 1x,
    flamingo2x.jpg 2x,
    flamingo3x.jpg 3x"
    />


어, 뭐야, 1x 뭐야!? x는 또 뭐야!?


혼란스러울지도 모르겠습니다만, 여기까지 읽은 분은 자연스레 아래처럼 읽을 수 있습니다!


  • 픽셀 비율 1 = flamingo1x 사용
  • 픽셀 비율 2 = flamingo2x 사용
  • 픽셀 비율 3 = flamingo3x 사용


라는 것입니다.


그래서 내 MacBook Pro(Retina 픽셀 비율 2)라면 flamingo2x를 표시하고, 외부 모니터(픽셀 비 1)라면 flamingo1x를 표시합니다.


덧붙여 Retina는 어디까지나 Apple 상표이며, 픽셀비 1 이외를 전부 Retina라고 부르는 것은 아닙니다.

그래서 Retina 아니다 = 픽셀 비율 1이 아니다!! 주의하세요.


마지막으로

html srcset과 sizes의 설명을 마칩니다. 오랫동안 읽어 주셔서 감사합니다.


프로그래머로서 아직도 부족한 면이 있기 때문에, HTML 반응형 이미지(Responsive Image) 관련해 잘못된 정보가 있으면 언제든지 지적해 주세요. 저에게도 공부가 되니깐 지적도 감사히 받겠습니다.



댓글