본문 바로가기
Dev/script

썸네일 이미지 비율 유지 영역에 꽉 차게 이미지 자르기 한 후 가운데 정렬 CSS 및 jquery 가로세로 비율

by 하양동백 2020. 10. 11.

목차

    썸네일 이미지 비율 유지 영역에 꽉 차게 이미지 자르기 한 후 가운데 정렬 CSS 및 jquery 가로세로 비율

    썸네일 이미지 비율유지 영역에 꽉 차게 이미지 자르기 한 후 가운데 정렬 CSS 및 jquery

    썸네일이나 대표이미지의 가로 세로 비율이 고정된 영역에 다양한 이미지의 가로세로 비율이 다를 때, 해당 영역의 크기에 딱 맞춰서 넘치는 영역은 잘려 보이게 하는 것은 조금 복잡하다.

    이미지 자체만으로 하려면 서버에서 자체적으로 이미지를 해당 비율에 맞춰서 잘라 주어야 하겠지만, 원본 소스를 유지한체 스타일시트 CSS만으로 해결하려면 어려움이 따른다.

    이미지가 세로가 긴 포트레이트일 수도 있고, 가로가 긴 랜드스케이프일 수도 있기 때문이다.

    CSS는 자체적으로 어느 쪽이 긴 지 알 수 없다.

    SCSS라면 해결할 수 있겠지만 CSS는 이미지의 가로가 긴지 세로가 긴지 확인하기 위해서는 자바스크립트나 jquery의 도움을 받아야 한다.

    위의 예시화면처럼 만들기 위해서 img는 최소 2개의 wrap에 쌓여 있어야 한다.

    이렇게 감싼 영역은 absolute를 이용해서 가운데 정렬을 하고, 길이가 짧은쪽이 100%를 차지하게 해서 긴쪽이 영역 밖으로 사라져서 감춰지게 한다.

    스타일시트.css는 다음과 같다.

    .featImgWrap {
      width: 380px;
    }
    
    .featImgWrap {
      position: relative;
      padding-top: 56.57%;
      /* 16:9 ratio */
      overflow: hidden;
    }
    
    
    .featImgWrap .featImage {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      -webkit-transform: translate(50%, 50%);
      -ms-transform: translate(50%, 50%);
      transform: translate(50%, 50%);
    }
    
    .featImgWrap .featImage 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%);
    }
    
    .featImgWrap .featImage img.landscape {
      max-height: 100%;
      height: 100%;
      max-width: none;
    }
    
    .featImgWrap .featImage img.portrait {
      max-width: 100%;
      width: 100%;
      max-height: none;
    }

    화면 비율의 Ratio는 최외곽 wrap의 padding-top으로 맞춰준다.

    1:1이면 100%이고, 가로:세로비가 16:9라면 56.25%가 된다.

    이 비율은 세로 나누기 가로 길이의 % 값이 된다.

    9/16 = 0.5625가 되므로 16:9 비율의 영역에서는 padding-top은 56.25%가 된다.

    이미지가 세로가 길다면 포트레이트 class를 주고, 가로가 길다면 landscape 클래스를 부여해서, 짧은 쪽 변의 길이를 영역의 100%에 맞춘다.

    $(document).ready(function () {
    
        // feat image ratio size
        $('.featImage > img').each(function (index, item) {
            if ($(this).height() / $(this).width() < 0.567) {
                $(this).addClass('landscape').removeClass('portrait');
            } else {
                $(this).addClass('portrait').removeClass('landscape');
            }
        });
        $('#programModalSummary').on('shown.bs.modal', function (e) {
            $('#programModalSummary .featImage > img').each(function (index, item) {
                if ($(this).height() / $(this).width() < 0.567) {
                    $(this).addClass('landscape').removeClass('portrait');
                } else {
                    $(this).addClass('portrait').removeClass('landscape');
                }
            });
        })
        
    });

    그러기 위한 jquery 스크립트는 위와 같다.

    같은 스크립트가 2개 사용된 이유는 모달 창에서도 같은 태그로 구성된 영역이 존재하는데, 모달이 열리기 전까지는 해당 영역의 폭과 높이가 0이기 때문이다.

    부트스트랩의 모달 기능으로 모달창이 열릴 때 이벤트 감지를 한 후 클래스를 부여하도록 해서 같은 기능이 한 번 더 사용되었다.

    반응형

    댓글