CSS

height: auto, object-fit: contain, object-fit: cover [ 콘텐츠의 원본 비율 유지 / 이미지 왜곡안되게 ]

hihiha2 2023. 9. 3. 15:39

➡️ 이미지 비디오가 박스크기에 들어가면서도 가로세로비를 유지하여 찌그러지며 왜곡되는 현상을 방지하기 위해

height: auto; / object-fit: contain; / object-fit: cover; 을 사용한다.

 

 


1. 기능

콘텐츠의 가로세로비 유지

 

 

2. 방법

1️⃣ height: auto;

2️⃣ object-fit: contain; 

3️⃣ object-fit: cover; 


이미지나 비디오를 화면에 그리다보면 원본사진의 사이즈와 콘텐츠가 들어가야하는 박스사이즈가 달라서 찌그러지는 왜곡현상이 발생할 때가 있다. 

 

예를 들면 아래와 같은 상황인데 짱구가 위아래로 조금 찌그러져있는 것을 확인할 수 있다.

인위적으로 찌그러지는 상황을 만들기 위해서 아래의 img에 width: 700px; height 500px;을 주었다.

 

 

이런 경우, 해결방법이 여러가지가 있다.

우선 기본적으로 width와 height의 길이를 조정하는 것이다.

쉽게 생각해서 width와 height의 길이를 정사각형으로 맞춤으로써 사진이 정상적으로 나오게 만드는것이다.

 

width: 700px; height 700px;으로 만들고 확인하면 아래와 같이 정상적으로 이미지가 나오는 것을 확인할 수 있다.

 

🚨 하지만 이렇게 일일이 맞춘다면 이미지가 정사각형이 아닌 경우에는 문제가 발생한다!! 🚨 

(모든 이미지가 정사각형이 아니고, 가로로 긴 이미지, 세로로 긴 이미지등 각각 길이가 다르므로 당연한 결과이다.)

 

예를 들어 이번에는 가로로 긴 이미지를 화면에 띄운다고 해보자.

 

똑같이 width: 700px; height 700px;으로 가로세로의 길이를 지정하면 가로로 긴 사진의 경우에 또 찌그러지게 나온다.

 

 

 

그래서 이렇게 일일이 가로세로를 지정해주는 것은 해결법이라 할 수 없다.

 

➡️ 이럴때 사용해야하는 것이 height: auto;이다.

 

 

1️⃣ height: auto;

height: auto;는 말그래도 자동으로 높이를 맞춰준다는 의미이다. 

width를 임의로 지정하고, height: auto;로 주면 가로세로의 비율이 찌그러지지 않도록 알아서 height의 길이가 지정된다.

 

위와 같이 아주 정상적으로 사진이 화면에 나오는 것을 확인할 수 있다.

 

 

다른 방법은 원리와 화면에 띄워지는 이미지도 다르다. 

우선 다른 방법들을 이해하기 위해서는 object-fit에 대해 알아야한다.

 

 

🧷선행학습

object-fit<img> <video> 요소와 같은 대체 요소의 콘텐츠 크기를 어떤 방식으로 조절해 요소에 맞출 것인지 지정

 

css요소 중 object-fit을 사용하면, 이미지나 비디오와 같은 콘텐츠가 실제로 출력되는 크기와, 콘텐츠박스(img태크의 전체적인 width,height) 사이의 조정을 다룬다.

(최대한 쉽게 풀어쓰려고 했는데, 글로만 쓰면 이해가 안될것같다. 직접 만들어서 그림으로 보면 훨씬 이해가 쉽다) 

 

위의 사진들을 자세히보면 검정색 테두리로 둘러져 있는 것을 알 수 있다. 저 검정색이 내가 img태그에 지정한 width,height이다.

이것을 콘텐츠박스라고 부른다.

일단 콘텐츠 박스는 고정적이다. 그래서 object-fit은 실제이미지를 찌그러지면서까지 콘텐츠 박스를 완전히 다 채울지, 아니면 다 채우지 않더라도 가로세로비율은 유지할지, 가로세로비율을 유지하면서 대신 확대될지.. 등을 디테일하게 조정할 수 있다.

 

 

2️⃣ object-fit: contain; 

contain

대체 콘텐츠의 가로세로비를 유지하면서, 요소의 콘텐츠 박스 내부에 들어가도록 크기를 맞춤 조절.

콘텐츠가 콘텐츠 박스 크기에 맞도록 하면서도 가로세로비를 유지하게 되므로, 서로의 가로세로비가 일치하지 않으면 객체가 "레터박스"된다.

 

contain을 이해하기 위해서 다시 사진을 왜곡했다.

width: 700px;   height: 600px;로 지정하였다.

이런 왜곡현상을 풀기위해 width, height는 그대로두고 object-fit: contain;만 추가하였다.

 

그러면 아래와 같이 이미지가 출력되는 것을 확인할 수 있다.

검정색 테두리가 콘텐츠박스이다. 저 박스의 width가 700px, height가 600px이다.

콘텐츠박스의 크기는 그대로 두고 안에 실제로 들어가는 이미지가 들어가는 방식만 변경한다. 

콘텐츠박스의 크기는 유지하면서 가로세로비를 왜곡되지 않도록 만드므로 아래와 같이 공백이 발생(레터박스화)한다.

 

3️⃣ object-fit: cover; 

cover

대체 콘텐츠의 가로세로비를 유지하면서, 요소 콘텐츠 박스를 가득 채웁니다. 서로의 가로세로비가 일치하지 않으면 객체 일부가 잘려나간다.

 

위의 contain과 유사하면서도 콘텐츠 박스를 가득채운다는 점이 다르다. 보통 가로세로비가 일치하지 않을때 사용하므로 이미지의 일부가 잘리고, 이미지도 확대된 모습으로 나온다.

 

contain과는 다르게 콘텐츠박스를 가득채우면서도 이미지는 확대되면서 잘려나간것을 확인할 수 있다.

 

 

 

🔫 이미지의 가로 크기를 100%로 하면서 왜곡되지 않게 하려면?

프로젝트를 만들다보면 이미지가 가로로 100프로를 모두 차지하게 만들어야할때가 있다.

대표적인 이미지가 바로 배너이다.

이런식으로 이미지가 가로로 길게 화면의 100%를 차지하고 있지만, 높이는 그것보다 훨씬 낮다.

그렇다고해서 이미지가 찌그러지지도 않았다.

이렇게 만들기위해서는 위의 방법들 중 어떤 것을 사용하면 좋을까?

 

 

➡️ width를 100%로 주고 height는 주고 싶은만큼 준 뒤, object-fit: cover;를 해준다.

width: 100%;
height: 600px;
object-fit: cover;

이렇게하면 이미지가 조금은 확대되어 나올 수도 있지만, 왜곡현상이 일어나지도 빈공간이 생기지도 않는다.

 

 

 

이와  같은 방식으로 background-image도 지정할 수 있다.

 

 

🔫 background-image의 경우에는?

 

배경 이미지를 사용하고 싶으면 background-image: url() 속성을 사용한다.

 

사용하고 싶은 영역에 background-imgae를 css로 넣어주면 된다.

예를 들어 header영역에 배경이미지를 지정하고 싶으면,  아래와 같이 태그에 넣어주거나, 아니면 className을 이용해서 해당영역의 배경이미지를 넣는다.

header { 
background-image: url(); 
}

 

이렇게 지정한 배경이미지도 가로세로가 왜곡되지 않으면서 전체영역을 다 채우고 만들고 싶을 수 있다.

이럴때는 아래와 같이 코드를 짠다.

background-image: url();
background-position: top center;
background-size: cover;

object-fit: cover 대신, background-size: cover; 을 한다.

 

리액트를 통해 작업하면서 받아온 API의 데이터에 따라서 다른 이미지가 나오게 해야하는 경우에는 state로 변경되는 값들을 url의 주소안에 넣어야하는 경우가 있다. 

 

그런데 여기서 문제는 movie는 계속해서 변경되는 값이기 때문에 Banner.js안에 useState를 통해서 관리되고 있다.

➡️ 해당 배경이미지는 넣은 style은 Banner.css가 아니라 Banner.js에서 관리하게 해준다

(url로 state로 변경되는 값을 이용하기 위해서)

해당 태그에 바로 style을 주고 거기안에 urlcover속성을 지정한다.

<header
        className="banner"
        style={{
          backgroundImage: `url("https://image.tmdb.org/t/p/original/${movie?.backdrop_path}")`,
          backgroundPosition: "top center",
          backgroundSize: "cover",
        }}
      >

 

 

(배경이미지를 cover로 사용하고 싶어서 object-fit:cover;로 지정하면 cover는 동작하지 않는다. 그래서 대신 background-size속성을 이용한다.)

 

 

 

👩‍💻 내 생각

이미지가 살짝 왜곡되는 것은 사실 기능구현에 어려움을 주거나하는 치명적인 문제는 아니다.

 

하지만 "만약 쇼핑몰에 들어갔는데 사진들이 모두 찌그러져 있다면..?"

아무리 품질이 좋은 옷이더라도 신뢰성이 확 떨어질 것이다.

프론트엔드 개발자로서 화면에 보여지는 것도 어느정도 중요하게 여겨야한다고 생각하고, css공부도 꾸준히 해나갈 예정이다.