[HTML/접근성] iframe 태그의 반응형 대응

2022. 12. 4.공부/HTML,CSS

728x90

회사 업무 중 iframe의 사용법이 쉽지는 않았기도 하고 외부 페이지가 가진 자체적인 이슈도 있어 반응형 대응을 하기에 난이도가 좀 있었기 때문에 문제 해결 과정을 다시 한번 정리해보고자 한다.

 

삽입해야하는 외부 url 페이지

 

최선의 방법은 아니었지만 직면했던 상황에서 최대한 할 수 있는 대처를 했으며 공부가 많이 되었다. 크리티컬한 이슈는 아래 세 가지였다.

 

1) 영역 삽입했을 시 상단부 이미지에만 테두리 생기는 현상이 있었음

 

문제 원인 :

외부 url을 iframe에 노출시켰을 시 상단 이미지 2개가 일정 width를 넘어가면 (694px 추정ㅠㅠ) 여백이 생겼다.모든 이미지가 동일한 상태면 처리가 쉬웠을 것 같은데 url 페이지 하단 삽입 이미지들은 또 반응형이 되어있고......

 

해결 방법 : d

 

a. iframe 프로퍼티로 frameborder=0을 줘본다

변동 사항 없음

 

b. 외부 페이지 영역 자체의 scale을 확대하여 상단부 이미지의 테두리가 보이지 않게 한다

하단부 레이아웃은 반응형 처리 되어있기 때문에 상단부만 정상 출력됨

 

c. iframe에 연결해야할 url의 코드를 강제로 변경하여 문제의 상단 메인 이미지를 반응형 처리한다.

기존 외부 url 코드 살펴보니 vue.js로 작업한 것처럼 보여서 기각

 

d. iframe 태그에 background-image를 삽입한다 

  • iframe에 배경 이미지 삽입하여 여백 부분을 배경으로 채움

[좌측] 삽입한 배경이미지 [우] iframe 연결 페이지 UI 전체

 

<div class="body-wrapper">
        <div id="contentsWrap" class="mainCon bgDarkGray">
            <div class="contents">
                <iframe id="(생략)" 
                    title="(생략)" 
                    width="100%" 
                    height="100%" 
                    frameborder="0" 
                    framespacing="0" 
                    marginheight="0" 
                    marginwidth="0" 
                    scrolling="no" 
                    vspace="0" 
                    src="(url)" 
                    style="background-image:url('./img/iframe_background.png');
		                   background-repeat:no-repeat;
		                   background-size: cover;
		                   background-position-y: -20px;">
                </iframe>
            </div>
        </div>
    </div>
  • 695 px 부터 여백 생기므로 max-width 694까지는 미디어 쿼리로 iframe background-image를 none 처리함
            @media screen and (max-width: 694px){
            iframe {
                position:absolute;
                left:0px;
                width:100%;
                background-color: white;
                background-image:none !important;
                }
             }

 

 

 

 

2) 화면의 가변 사이즈에 맞춰 iframe의 height를 변경시켜줘야 함

 

문제 원인 :

iframe 프로퍼티에서 width 100%, height 100%을 주면 해결될 것 같지만 iframe 태그가 height에는 퍼센트 단위가 적용되지 않음..

 

해결 방법 : b

 

a. iframe을 resizing하는 jQuery 구문을 사용

iframe background가 있기 때문에 height만 변경하는게 아니라 style에서 background-image의 y값도 변경해야했는데, iFrameSizer에서 style을 변경하는 옵션을 찾지 못했다.

<!-- html 로드 후 실행하도록 함 -->
<script type="text/javascript" src="./js/jquery.iframeResizer.min.js"></script>
<script type="text/javascript" src="./js/iframeResizer.contentWindow.min.js"></script>
<script>
    let iframe = document.querySelector("iframe");
        console.log(iframe);
        console.log(iframe.offsetHeight);
        console.log(iframe.offsetWidth);
    $('iframe').iFrameSizer({
        log:true,
        autoResize : true,
        bodyBackground : null,
        bodyMargin : null,
        bodyMarginV1: 0,
        bodyPadding : null,
        enablePublicMethods: false,
        checkOrigin : true,
        maxHeight: Infinity,
        maxWidth: Infinity,
        minHiehgt:0,
        minWidth:0,
        scrolling:false,
        sizeWidth:true,
        sizeHeight:true,
        heightCalculationMethod: 'offset',
    })
 </script>

 

b. Javascript로 디바이스 별 브레이크 포인트에 따라 강제로 리사이징

<!-- html 로드 후 실행하도록 함 -->
<script>
        let iframe = document.querySelector("iframe");
        let contents = document.querySelector(".contents");
        let bodyWrap = document.querySelector(".body-wrapper");
        console.log(iframe);
        console.log("HEIGHT");
        console.log(iframe.offsetHeight);
        console.log("WIDTH");
        console.log(iframe.offsetWidth);
        if(iframe.offsetWidth >= 2560) {
            bodyWrap.style.paddingBottom = 8500 + "px";
            iframe.style.height = 8500 + "px";
            contents.style.height = 8500 + "px";
            iframe.style.backgroundPositionY = -41 + "px";
        } else if(iframe.offsetWidth >= 1920) {
            bodyWrap.style.paddingBottom = 7400 + "px";
            iframe.style.height = 7400 + "px";
            contents.style.height = 7400 + "px";
            iframe.style.backgroundPositionY = -41 + "px";
        } else if(iframe.offsetWidth >= 1440) {
            bodyWrap.style.paddingBottom = 5700 + "px";
            iframe.style.height = 5700 + "px";
            contents.style.height = 5700 + "px";
            iframe.style.backgroundPositionY = -31 + "px";
        } else if(iframe.offsetWidth >= 1024){
            bodyWrap.style.paddingBottom = 4200 + "px";
            iframe.style.height = 4200 + "px";
            contents.style.height = 4200 + "px";
            iframe.style.backgroundPositionY = -25 + "px";
        } else if(iframe.offsetWidth >= 928) {
            bodyWrap.style.paddingBottom = 3800 + "px";
            iframe.style.height = 3800 + "px";
            contents.style.height = 3800 + "px";
            iframe.style.backgroundPositionY = -22 + "px";
        } else if(iframe.offsetWidth >= 694) {
            bodyWrap.style.paddingBottom = 3300 + "px";
            iframe.style.height = 3300 + "px";
            contents.style.height = 3300 + "px";
        } else if(iframe.offsetWidth >= 428) {
            bodyWrap.style.paddingBottom = 2000 + "px";
            iframe.style.height = 2000 + "px";
            contents.style.height = 2000 + "px";
        } else if(iframe.offsetWidth >= 360) {
            bodyWrap.style.paddingBottom =  1750  + "px";
            iframe.style.height = 1750 + "px";
            contents.style.height = 1750 + "px";
        } else if(iframe.offsetWidth >= 320) {
            bodyWrap.style.paddingBottom = 1000 + "px";
            iframe.style.height = 1000 + "px";
            contents.style.height = 1000 + "px";
        } else {
            contents.style.height = 300 + "px";
        }
  </script>

 

 

 

 

3) landscape와 portrait 화면 전환 시 이슈 생김

 

해결 방법 : 

 2번 코드가 결국 모바일 화면 가로/세로 전환할 때 이슈가 생겼었고, 디바이스 별로 landscape와 portrait를 구분해서 하드코딩할 수는 없었기 때문에 기존 코드를 걷어내고 삽입 url 페이지 비율 계산해서 화면 사이즈 가변되더라도 영구적인 고정비를 주는 방법으로 재작업

 

  • iframe을 고정비를 지닌 부모 div에 가두고 iframe style에 width 100%, height 100% 처리
    <div class="iframebox" style="position:relative; width:100%; padding-bottom:450%;">
            <iframe id="dataUniverse"
                    title="신종금융사기사례"
                    width="100%"
                    height="100%"
                    scrolling="no" 
                    frameborder="0" 
                    marginheight="0px" 
                    marginwidth="0px"
                    allowfullscreen="0"
                    vspace="0"
                    src="https://partner.antiscam.co.kr/app2/sci_s_03"
                    style="position:absolute; 
                           width:100%;
                           height:100%;
                           left:0px; 
                           top:0px;" 
                    >
            </iframe>  
    </div>
  • css에서 landscape와 portrait의 노출 영역 각각 대응
        @media (orientation: landscape) {
        .iframebox {
            position:relative;
            width:100%;
            padding-bottom:400% !important;
        }
        }

        @media (orientation: portrait) {
        .iframebox {
            position:relative;
            width:100%;
            padding-bottom:450%;
        }
        }

 

문제 생기면 공유를 잘 안하는 습관이 있는데 고쳐야겠다는 생각이 든다. 이렇게 고뇌한거 협업자는 모름....................ㅎ 약한 소리가 아니라 업무 공유라는 측면에서 접근하며 커뮤니케이션해야겠다 어려웡