본문 바로가기
HTML+CSS

반응형 이미지 교체 기능, <img>를 <picture>로 감싸보자

by 즐코딩 2023. 1. 2.
반응형

얼마 전 포스팅에서, HTML 문서에 삽입한 이미지를 반응형으로 만드는 아주 간단한 팁을 살펴보았습니다.

 

 

[실무꿀팁] 이미지를 HTML 문서에 반응형으로 넣기 1초컷

 

[실무꿀팁] 이미지를 HTML 문서에 반응형으로 넣기 1초컷

아주 간단하게 이미지 반응형으로 넣기 매년 연말 연시가 되면, 고객분들로부터 신년인사 팝업 게재 요청이 들어옵니다. 매년 반복되는 시즈널한 루틴업무죠. 인사말씀 분량이 많은 경우 팝업

kincoding.com

 

그런데 이처럼 1개의 이미지를 반응형으로 동작하게 하는 것이 아니라, 가로세로 비율이 다른 여러 개의 이미지를 그때 그때 반응형으로 맞처서 아예 교체를 해주려면 어떻게 해야 할까요? 이번 포스팅에서는 바로 이 점을 살펴보도록 해보겠습니다.

 

 

 

반응형 이미지를 교체하려면 <picture> 태그를 사용

 

 

아래 2개의 이미지를 사용해서 예제를 만들어보겠습니다.

같은 이미지로 가로 세로 비율만 다르게 하려 했는데, 이미지가 교체 되는 것을 바로 확인하기 쉽도록 서로 다른 이미지를 사용해보았습니다.

샘플이미지01
landscape.jpg
샘플이미지02
portrait.jpg

 

 

Javascript로 이미지 교체하기 by 자바스크립트

 

이전 Javascript 포스팅에서 자바스크립트의 DOM 조작을 살펴본 내용들이 있습니다.

이와 비슷한 방식으로 브라우저의 가로폭을 구하고, 조건문을 사용해서 특정 가로폭 이하가 될 때 querySelector를 이용해서 원하는 img 태그를 선택한 후 src 속성 값을 변경해주면 되겠죠?

 

그런데 뭔가 좀 복잡해보입니다. 브라우저의 가로폭 변화를 감지하기 위해서 "이벤트 리스너"라는 것도 붙여야하고, 이벤트가 일어날 때마다 조건문으로 계산도 해줘야 합니다. 자바스크립트로 척척해내면 왠지 더 멋져보이는 것 같은 생각이 들기도 하지만, 뭔가 무거운 느낌이 살짝 드는 것도 사실입니다. 미디어 쿼리 같은 게 더 좋지 않을까? 하는 생각이 들지 않나요?

 

 

 

미디어 쿼리로 이미지 교체하기 by CSS

 

CSS가 제공하는 미디어 쿼리를 이용해서도 얼마든지 이미지를 교체할 수 있을 것 같습니다.

코드는 간단하게 다음과 같이 작성해보았습니다.

 

<body>
    <div class="landscape">
      <h1>Merry Christmas and Happy New Year!</h1>
      <img id="landscape" src="landscape.jpg" alt="" />
    </div>
    <div class="portrait">
      <h1>Happy New Year!</h1>
      <img id="landscape" src="portrait.jpg" alt="" />
    </div>
  </body>
    <style>
      @media (max-width: 800px) {
        .landscape {
          display: block;
        }
        .portrait {
          display: none;
        }
      }
      @media (max-width: 500px) {
        .landscape {
          display: none;
        }
        .portrait {
          display: block;
        }
      }
    </style>

 

간단한 테스트를 위해서 가로 800px, 500px을 각각 Break Point로 설정했습니다.

브라우저 가로폭 800px까지는 landscape.jpg가 보여지고(portrait.jpg는 display: none)

landscape.jpg가-잘-표시됩니다.
landscape.jpg가 잘 표시됩니다.

 

 

브라우저 가로폭 500px 이하에서는 portrait.jpg만 보여지게 됩니다. Media Query를 사용했으니 당연한 결과겠죠?

 

portrait.jpg도-잘-표시됩니다.
portrait.jpg도 잘 표시됩니다.

 

TMI - 다만 현재 예제에서는 Breakpoint를 촘촘하게 구성해놓은 게 아니라서, 800px 이상에서는 landscape.jpg와 portrait.jpg 이미지 두 개 모두 보여지게 될 것입니다.

 

 

 

 

<picture>  태그로 이미지 변경하기 by HTML

 

대부분의 사람들은 HTML문서에 이미지를 삽입하는 경우에 <img> 태그를 사용할 것입니다. 당연한 이야기죠. 그런데, 반응형이 기본인 모바일 중심의 시대가 되면서 삽입되는 이미지 또한 '반응형 동작'을 염두에 둘 필요가 있습니다.

 

일단 앞서 살펴본 미디어쿼리 사용의 예와 비교할 수 있도록 다음과 같이 코드를 작성해봅니다.

  <body>
    <picture>
      <source srcset="portrait.jpg" media="(max-width: 500px)" />
      <img src="landscape.jpg" alt="사진설명" />
    </picture>
  </body>

 

특이한 점은 <img> 태그를 <picture> 태그로 감싸줬다는 것이고, <source>라는 태그가 새로 등장했다는 점입니다.

그리고 <source>태그는 srcset 이라는 속성과 media라는 속성을 갖는데, 뭔가 한눈에 들어오는 형태입니다.

그냥 이미지 경로 써주고, 미디어쿼리와 비슷한 형태로 max-width를 설정해주는 방식입니다.

 

결과 화면은 다음과 같습니다.

500px-이하에서는-portrait.jpg를-표시
500px 이하에서는 portrait.jpg를 표시

 

가로폭 500px 이하에서는 portrait.jpg가 잘 표시되고, 800px 이하에서는 landscape.jpg가 잘 표시됩니다.

중요한 것은 가로폭 800px 이상에서도 landscape.jpg 만 표시된다는 것이죠. 바로 이 점이 CSS의 미디어쿼리와 다른 점입니다.

500px-이상에서는-landscape.jpg를-표시합니다.
500px 이상에서는 landscape.jpg를 표시합니다.

 

쉽다고 약간 소홀히 하던 HTML에 등짝 스매시 한대 맞은 느낌입니다.^^ 뭔가 더 쉽게 느껴지지 않나요?

 

 

물론, picture태그를 사용하면서 break point를 촘촘하게 구성할 수도 있습니다.

<picture>
    <source srcset="image-TINY.jpg" media="(max-width: 480px)">
    <source srcset="image-SMALL.jpg" media="(max-width: 768px)">
    <source srcset="image-MIDDLE.jpg" media="(max-width: 1024px)">
    <img src="image-LARGE.jpg" alt="이미지 설명">
</picture>

 

이와 같은 식으로 휴대폰, 태블릿, PC에서 각각 다르게 보여지는 이미지를 지정해줄 수 있게 됩니다.

중요한 것은, 브라우저 가로폭 1024 이상에서는 img-LARGE.jpg가 표시된다는 점입니다.

 

다시 말해서 img 태그로 써주는 이미지가 Default 이미지가 되고, source 태그로 Break Point를 만들어 줄 수 있게 된다는 것이죠. 

 

<picture> 태그에 대해서 조금 더 자세히 알고 싶은 분들은, MDN을 참고하시면 좋습니다.

 

https://www.w3schools.com/html/tryit.asp?filename=tryhtml_images_picture_format 

 

W3Schools online HTML editor

The W3Schools online code editor allows you to edit code and view the result in your browser

www.w3schools.com

 

 

 

마치며

 

<picture> 태그는 아직 많은 사람들이 사용하고 있는 것 같지는 않습니다. 하지만, 반응형에 따른 동작을 간결하고 쉬우면서도 강력하게 구현하는 기능이라는 생각이 듭니다. 왜냐하면 예전에는 img 태그만 존재했거든요.

 

시간이 흐르면서 기능들도 발전을 하게 되고 관련 지식들도 발전을 하게 되는 것 같습니다. 이번에 picture 태그를 새롭게 알게 되면서, 예전에 배워서 머릿속에 꼭꼭 담아두었던 지식들도, 불변의 진리가 아닐 수 있으니 항상 열린 마음으로 살펴보고 업데이트를 이루자는 그런 깨달음 같은 걸 얻게 된 것 같습니다.

 

즐거운 코딩생활, 즐코딩.

KINcoding.

반응형

댓글