본문으로 바로가기

CSS로 유동적인 컨테이너 너비에 기반한 이미지 비율 유지, 가운데 정렬, 자르기

이미지 요소나 비디오 요소를 특정 비율에 맞춰 확장 또는 축소되길 원할때 사용되는 기법에 대해 알아보고 스크립트의 사용없이 오직 CSS만을 이용하여 이를 구현해보면서 원리의 이해를 돕고자 합니다.




이미지 비율 유지(keep image ratio)

이미지의 비율을 유지하면서 크기 조정을 하는 방법은 이미지의 너비와 높이 둘 중 어느 하나를 auto 값을 유지한 채로 크기 조정을 하는 것입니다. 

흔히 반응형 이미지에 사용되는 방법은 아래와 같습니다.

css
img {
    max-width: 100%;
    height: auto;
}


반응형 이미지의 너비를 자유롭게 조정하기 위해서는 아래 코드와 같이 이를 감싸는 컨테이너를 추가 해주고 적절한 너비를 부여할 수도 있습니다.

html
<div class="thumbnail-wrapper">
    <img src="xxxx">
</div>
css
.thumbnail-wrappper {
    width: 25%;
}

img {
    max-width: 100%;
    height: auto;
}


이미지 원본의 비율을 유지하기 위해 너비만 부여했기 때문에 이미지는 각각 통일되지 못한 높이를 가지고 있게 됩니다.

또한 유동적인 너비를 갖도록 %(percentage) 너비값을 부여했지만 높이는 그럴 수 없습니다.


일반적으로 고정된 높이값을 부여하고 넘치는 부분을 자른다면 아래와 같은 결과를 얻게 될 것입니다.

css
.thumbnail-wrappper {
    width: 25%;
    height: 200px;
    overflow: hidden;
}

img {
    max-width: 100%;
    height: auto;
}


유동적인 너비에는 대응하지 못하는 결과를 가져오기 때문에 추천되지 않는 방법입니다.

컨테이너 또한 일정한 비율 유지가 필요함을 느끼게 됩니다.




컨테이너 비율 유지

컨테이너의 비율 유지를 위해 사용되는 기법은 2009년 Creating Intrinsic Ratios for Video에 기고된 내용인 아래의 내용을 이해하는 것이 핵심입니다.


퍼센테이지(%, 백분율)은 컨테이너 블럭의 너비를 참조한다.


이미 알다시피, 퍼센테이지 단위는 부모 요소를 기준으로 계산되어 집니다. 

의외인 것은 자식 요소의 수직적인 패딩 값도 부모 요소의 너비에 영향을 받는 다는 것입니다. 

그 이유를 불문하고 그렇게 만들어졌고 브라우저들의 공통사항이라고 합니다.

이 특징을 이용하여 상,하 어느 방향의 패딩값을 이용해서 특정 비율을 유지하는 컨테이너를 만들 수 있습니다.

html
<div class="thumbnail-wrapper">
    <div class="thumbnail">
        <img src="xxxx">
    </div>
</div>
css
.thumbnail-wrappper {
    width: 25%; 
}

.thumbnail {
    position: relative;
    padding-top: 100%;  /* 1:1 ratio */
    overflow: hidden;
}

img {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    max-width: 100%;
    height: auto;
}



이는 각각의 높이를 가지고 있는 이미지들을 absolute 포지셔닝을 통해 문서의 흐름에서 제외시켜 이미지의 높이가 컨테이너의 높이에 영향을 줄 수 없게 만들고 새로 추가된 .thumbnail 요소의 상단 패딩값으로 높이를 조절하게 만들고 있습니다. 

즉, 상단 패딩값 만큼만 이미지가 노출되고 나머지 넘치는 부분은 overflow:hidden; 으로 보이지 않게 되어 컨테이너는 일정한 비율을 유지하게 되며 유동적인 너비 변화에 대응하게 하는 방법입니다.


다양한 비율 만들기

padding-top 의 값을 아래와 같이 변화시켜 다양한 비율을 얻을 수 있습니다.

  • 2:1  :  padding-top: 50% 
  • 1:2  :  padding-top: 200% 
  • 4:3  :  padding-top: 75% 
  • 16:9  :  padding-top: 56.25%




이미지 중앙 정렬 및 가득 채우기

출력할 이미지의 크기가 어느정도 예상 가능하다면 컨테이너의 너비와 비율을 적당히 수정해 이미지가 컨테이너에 가득차도록 만들 수 있을 것입니다. 

위의 비율 예에서는 4:3 비율이 출력할 이미지의 추천형태가 될 것입니다. 

만일, 이미지의 크기를 예상할 수 없는 경우라면 적어도 이를 가운데 정렬이 되도록 만들어 볼 수 있습니다. 

위에서 사용한 코드에 수정이 필요합니다. 아래와 같이 이미지를 한번더 감싸주도록 합니다.

html
<div class="thumbnail-wrapper">
    <div class="thumbnail">
        <div class="centered">
            <img src="xxxx">
        </div>
    </div>
</div>
css
.thumbnail-wrappper {
    width: 25%; 
}

.thumbnail {
    position: relative;
    padding-top: 100%;  /* 1:1 ratio */
    overflow: hidden;
}

.thumbnail .centered  {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    -webkit-transform: translate(50%,50%);
    -ms-transform: translate(50%,50%);
    transform: translate(50%,50%);
}

.thumbnail .centered img {
    position: absolute;
    top: 0;
    left: 0;   
    max-width: 100%;
    height: auto;
    -webkit-transform: translate(-50%,-50%);
    -ms-transform: translate(-50%,-50%);
    transform: translate(-50%,-50%);
}



물론 translate 속성을 지원하지 않는 IE8 이하는 가운데 정렬되지 않는다. CSS 만으로는 한계에 봉착하는 부분이다.



portrait 와 landscape 이미지 구분

위의 예제들에서 사용된 이미지는 반응형 이미지의 기본 값을 사용하고 있습니다. 

너비를 max-width 속성으로 제한해 왔기 때문에 너비는 최대치가 되더라도 높이는 경우에 따라 화면을 가득 채우지 못하곤 합니다. 

컨테이너의 너비를 이미지 원본보다 키우고 반응형 이미지 설정을 제거하면 화면을 채우지 못하는 공간이 확연하게 나타납니다.



세로로 긴 형태의 이미지를 portrait(초상화) 라고 일컫습니다.

이러한 형태의 이미지들은 정해진 영역의 너비에 이미지의 너비를 맞춰야 합니다.

Portrait

css
img.portrait {
    width: 100%;
    height: auto;    
}


마찬가지로 가로로 긴 형태의 이미지를 landscape(풍경화) 라고 부르곤 한다. 이러한 형태의 이미지들은 정해진 영역의 높이에 이미지의 높이를 맞춰야 화면에 가득차게 된다.

Landscape

css
img.landscape {
    width: auto;
    height: 100%;    
}



위의 이미지들은 원본 이미지의 크기를 넘어서는 컨테이너 영역을 가득 채우기 위해서 각각 너비와 높이를 100%로 강제로 늘였기 때문에 이미지가 훼손된 상태입니다. 

만일, max-widthmax-height를 활용한다면 이미지의 최대 크기는 원본 크기를 넘어서지 못하고 여백을 남기게 되므로, 각각 상황에 맞게 활용해야 할 것입니다.




이미지 자르기

위에서 설정한 이미지들의 너비와 높이를 auto 값으로 두면 원본 이미지의 크기가 컨테이너 안에서 출력되게 될 것이고 중앙정렬을 했다면 가운데 부분이 잘려서 보이게 될 것입니다.



즉, 컨테이너의 크기에 따라, 정렬하고 싶은 위치에 따라, 원본 이미지의 사진을 잘라내어 노출할 수 있게 됩니다. 

정렬을 위해 translate 속성을 사용했으므로 이 값을 원하는 만큼 조정하면 될 것이고, translate 속성을 모두 제거하고 직접 absolute 포지셔닝을 이용해 잘라낼 부위를 선택할 수 있을 것입니다.


Responsive Image TEST DEMO VIEW



  • 플러그인 및 스크립트를 이용한 썸네일은 아래의 리스트를 참고하기 바랍니다.


아직까지는 스크립트의 사용없이는 완벽한 모델을 구현할 수가 없는 것 같습니다. 

적어도 서버단에서 썸네일로 사용될 이미지에 대한 형태 구분이라도 지원된다면 원하는 결과에 다가설 수는  있을 것입니다.



[출처] WEBDIR - 흉내쟁이님


Jaehee's WebClub