Skip to Content
Go Back
안형우

안녕하세요. 14년차 풀스택 웹개발자 안형우입니다. 이 블로그에서는 WordPress, PHP, CSS, 사용성, 리눅스 서버 등 풀스택 웹개발에서 마주하는 다양한 문제 상황과 해결책, 필요한 개념들을 다룹니다. 👉 소개


작업물

📌 CSS가 어려운 이유 — 프로젝트 중심 실전 CSS 강의 소개 2023-04-13
📌 워드프레스, 답답한 빌더와 플러그인 대신 시원하게 커스터마징하기(강의) 2023-01-15
📌 아무도 말하지 않는 PHP의 좋은 점 2018-10-13
📌 유지보수하기 쉬운 CSS 전략(슬라이드) 2016-12-20
📌 워드프레스 테마에서 템플릿 파일 매칭 순서 2013-05-12
📌 [번역] CSS 코드 냄새 2013-01-01

[jQuery]레이어 팝업(modal window) 띄울 때 전체를 덮는 반투명 검은 막(black mask) 만들기

들어가기 전에 : 이 글과 함께 레이어 팝업을 화면 정 가운데 위치시키는 방법, 이미지가 늦게 로딩되어 정 가운데 위치 계산이 틀리는 것을 방지하는 방법을 보면 좋다.

항상 궁금했다. modal box를 띄우는 방법은 궁금하지 않았다. 뒷면을 다 덮는 검은 반투명 막을 어떻게 만드는지가 궁금했다.

답은 간단했다. jQuery modal window를 만드는 튜토리얼에서 그 방법을 발견했다. 우리가 해왔던 방식하고 크게 다르지 않았다. 이것만 가지고 플러그인을 만들어 볼까 하는 생각도 들었다.

자, 반투명 검은 막을 만드는 방법은 간단하다.(예제부터 보길 바라면 아래 파일을 사용하면 된다.)

일단, HTML의 어딘가에 아래 코드를 끼워 넣는다. 어디든 별 상관 없지만 찾기 편한 곳에 둬야 할 거다.

<div id="mask"></div>

다음은 CSS인데 아래처럼 해 준다.

#mask {  
  position:absolute;  
  left:0;
  top:0;
  z-index:9000;  
  background-color:#000;  
  display:none;  
}

마지막으로 jQuery 코드를 짜 보자.

function wrapWindowByMask(){
        //화면의 높이와 너비를 구한다.
        var maskHeight = $(document).height();  
        var maskWidth = $(window).width();  
		
        //마스크의 높이와 너비를 화면 것으로 만들어 전체 화면을 채운다.
        $('#mask').css({'width':maskWidth,'height':maskHeight});  
		
        //애니메이션 효과
        $('#mask').fadeIn(1000);      
        $('#mask').fadeTo("slow",0.8);    
}

자, 위 함수를 사용하면 반투명의 검은 마스크가 나타날 것이다. 그럼 어떻게 닫을까?

두 가지가 있을 것이다.

  1. modal window의 닫기 버튼을 눌렀을 때
  2. 반투명 검은 막을 눌렀을 때

두 경우 모두를 지원하기 위해서 click할 때 일어나는 이벤트를 두 군데 걸어야겠다.

이건 원본에서 그냥 긁어 온 코드다. .window는 검은 막 위에 뜬 modal window다.

//닫기 버튼을 눌렀을 때
$('.window .close').click(function (e) {  
    //링크 기본동작은 작동하지 않도록 한다.
    e.preventDefault();  
    $('#mask, .window').hide();  
});       

//검은 막을 눌렀을 때
$('#mask').click(function () {  
    $(this).hide();  
    $('.window').hide();  
});

위 코드들은 당연히 jQuery(document).ready(function(){ /*코드 넣는 부분*/ }) 으로 감싸 줘야 한다.

완성된 코드는 아래와 같다. (주의! DTD 선언을 하지 않으면 IE에서 깨진다! 아마 쿽스모드로 렌더링하기 때문일 것이다.)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <style>
    #mask {  
      position:absolute;  
      z-index:9000;  
      background-color:#000;  
      display:none;  
      left:0;
      top:0;
    }
    .window{
      display: none;
      position:absolute;  
      left:100px;
      top:100px;
      z-index:10000;
    }
    </style>
    <script src="https://code.jquery.com/jquery-latest.js"></script> 
    <script>
    function wrapWindowByMask(){
        //화면의 높이와 너비를 구한다.
        var maskHeight = $(document).height();  
        var maskWidth = $(window).width();  

        //마스크의 높이와 너비를 화면 것으로 만들어 전체 화면을 채운다.
        $('#mask').css({'width':maskWidth,'height':maskHeight});  

        //애니메이션 효과 - 일단 1초동안 까맣게 됐다가 80% 불투명도로 간다.
        $('#mask').fadeIn(1000);      
        $('#mask').fadeTo("slow",0.8);    

        //윈도우 같은 거 띄운다.
        $('.window').show();
    }

    $(document).ready(function(){
        //검은 막 띄우기
        $('.openMask').click(function(e){
            e.preventDefault();
            wrapWindowByMask();
        });

        //닫기 버튼을 눌렀을 때
        $('.window .close').click(function (e) {  
            //링크 기본동작은 작동하지 않도록 한다.
            e.preventDefault();  
            $('#mask, .window').hide();  
        });       

        //검은 막을 눌렀을 때
        $('#mask').click(function () {  
            $(this).hide();  
            $('.window').hide();  
        });      
    });
    </script>
</head>
<body>
    <div id="mask"></div>
    <div class="window">
        <input type="button" href="#" class="close" value="나는야 닫기 버튼(.window .close)"/>
    </div>
    <a href="#" class="openMask">검은 막 띄우기</a>
</body>
</html>

반투명 검은 막 위로 박스를 띄울 때 박스를 스크롤과 상관없이 화면의 정 중앙에 오도록 하고 싶다면 ‘[jQuery] 레이어 팝업 박스를 화면 정 가운데 위치시키기(ie든 파폭이든 크롬이든 다 되는 거)’를 참고하면 된다.

터치 이벤트(2013-05-31 추가) 처리

터치가 가능한 기기에서 실수로 검은 막을 터치해 레이어를 닫는 경우가 생긴다는 지적이 있었다. 그러나 화면을 움직이거나 확대 축소하면 레이어가 닫히지 않는다. 정확히 터치를 해야 닫힌다. 따라서 혼동을 주지 않을 거라고 나는 생각한다.

그러나 사이트 기획자 입장에서는 선택할 수 있는 옵션이 있는 게 좋을 것이다. 만약 검은 막을 터치하는 경우에는 닫고 싶지 않다면 자바스크립트에 아래 코드를 추가하면 된다. (당연히 $(document).ready(function(){ ... }) 안에.) ‘touchstart’ 이벤트를 사용했다.

// 터치 스크린에서 실수로 레이어를 닫는 경우를 막으려면.
$('#mask').one('touchstart', function () {  
    $(this).unbind('click');
    alert('터치 이벤트일 때는 아무 일도 안 일어난다.');
});

one()은 이벤트에 따른 함수를 한 번만 실행하고 해당 이벤트를 unbind하는 함수다.

안녕하세요. 14년차 풀스택 웹개발자 안형우입니다. 이 블로그에서는 WordPress, PHP, CSS, 사용성, 리눅스 서버 등 풀스택 웹개발에서 마주하는 다양한 문제 상황과 해결책, 필요한 개념들을 다룹니다. 👉 소개


작업물

댓글 (43개)

  • 와우~ 정말 멋지 정보입니다.
    제가 찾던 그 정보입니다.^^
    저에겐 마스크 기능 보다 $(doucment).height 가 더 좋은 정보였습니다.^^
    전 $(window).height 으로 사이즈를 구했는데
    항상 스크롤 때문에 하단 부분에는 적용이 안되더군요.ㅠ.ㅠ
    님 정말 감사합니다.^^

    • var maskWidth = $(window).width();

      var maskWidth = ‘100%’;

      이렇게 수정하는것이 좋을거 같습니다. 그래야 창을 늘렸다 줄여도 막이 전부 덮네요

  • 진짜 정말 너무 감사합니다!!
    제가 한참 찾아 다녔던 소스입니다.ㅠㅠ 정말 감사합니다..

    • 소스를 보내주실 수 있나요? HTML 전체를 보내주심 됩니다. mytory쥐메일로요.

  • 위소스를 이용했을때 크롬에서 정상작동하는데 IE8, IE7에서는 막이 적용이 안되네요^^

    • 소스를 보내 주실 수 있을까요? 제가 했을 땐 다 됐거든요. 소스가 있어야 분석을 해 볼 수 있을 것 같습니다. mytory쥐메일입니다.

    • 오쌍 님이 메일로 답장을 보내 주셨습니다.

      홈페이지에 있는 소스랑 동일합니다.
      아마 DTD 선언이 안되어서 IE에서 안뜬거같습니다^^
      상단에 DTD선언해주니 IE에서도 정상적으로 뜨네요^^

      이렇게 보내 주셨고, 답장 보내주신대로 소스코드에 DTD 선언을 반영했습니다.

  • 감사합니다. ㅠㅠ.. 제 블로그에 님의 블로그 글 출처를 밝히고, 개재하고 싶은데요,
    만일 안된다면, 제 블로그에 댓글 남겨주세요. T^T

    • 부분인용 후 링크해 주세요 ^^ 이 블로그가 사라질 염려는 없어요.
      그래도 사라질 염려 때문에 그러시는 거라면 이 페이지를 통째로 다운받아서 압축한 다음 블로그에 파일로 업로드하는 건 괜찮습니다. Ctrl+S 누르면 CSS와 JS까지 통째로 다운받아집니다.
      하지만 퍼가는 것보다는 이걸 참고해서 직접 글을 작성하시는 걸 더 추천합니다.

  • 사이트 리뉴얼 중인데 클릭했을때 말고 바로 반투명으로 레이어뜨게 할수없나요?ㅠ..ㅠ

      • 답변감사합니다~~ 제가 이런쪽에 문외한이라…ㅠㅠ 소스를 어떻게 써줘야하나요ㅠㅠ 죄송합니다ㅠ

  • 마스크 레이어를 클릭해서 팝업레이어를 닫는 내용과 관련하여 웹 접근성 이슈가 발견되어 알려드립니다.
    터치 디바이스를 이용하는 사용자들은 화면 확대나 축소를 위해 영역을 터치하면 레이어가 그냥 닫혀버리는 불편함이 있다고 하네요.
    (fb 웹 접근성 그룹 발췌)

    그래서 저는 클릭 대신 마스크 레이어 더블클릭 시 팝업레이어를 닫는 방법을 제안하고자 합니다. :)

    • 제 생각엔 더블클릭은 데스크탑에서 레이어를 닫는 일반적 동작이 아닌 것 같습니다.
      터치 기기에서 실수로 레이어를 닫는 것은 마스크 위에서 스와이프를 하지 않고 정확히 터치하는 경우입니다. 그런데 이건 개연성이 있는 작동입니다. 그래서 저는 터치하는 경우 닫게 하는 것이 혼란을 줄 가능성은 적다고 생각합니다.
      다만, 터치의 경우엔 아예 닫히지 않도록 하는 옵션을 줄 수는 있을 것 같습니다. 사이트 기획자가 선호하는 것을 선택할 수 있도록 하는 것이지요.
      관련 코드를 찾아보고 가능한지 알아 봐야 할 것 같지만 말입니다. (아마 가능할 것 같습니다 ㅋ)

    • 터치 이벤트에는 검은 막이 닫히지 않도록 하는 예제와 코드를 추가했습니다.

  • 페이드인 돼면서 불투명도 80%로 될때 글씨색이 흐리게 보이는데 이거 색을 바꾸거나 진하게 할라면
    어디다가 추가를 해야 하나요?
    font-color를 .window에 추가해도 안돼고 직접 쓴데다가 넣어도 안먹네여…ㅡ.ㅡ

  • 안녕하세요.
    좋은자료 정말 감사합니다.
    질문이 있어서요
    얘가 없어도 ie에선 되더라구요 얘를 넣으니간 dtd선언 했음에도 화면이 깨져서요

    그리고 검은색말고 다른색으로 바꾸려면 어디 부분을 수정해야 하죠? (완성된 소스에서..)

    저 그리고

    이 부분이 화면 정중앙에 나오려면 어케 해야 하죠???

    또 한가지 더 있는데요, 뒤덮은 검은색레이어를 화면 꽉차게 하려면 어케 하는지좀?

    질문이 많았네요.
    감사합니다.^^

  • 안녕하세요 인턴 중에 메인 홈페이지를 리뉴얼 하고 있는데 로그인 링크를 클릭하면 black mask가 전 화면을 덮으면서 로그인 폼이 뜨는(마치 팝업처럼) 걸 고안하고 있었는데 좋은 방법을 알아가게 됬어요 ^^ 정말 감사합니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다