팝업 가운데 정렬 CSS - pab-eob gaunde jeonglyeol CSS

outer div는 modal의 background layer다.
jsfiddle에서 잘 보이도록 1000px로 고정시켜놨고 실제로는 100%를 사용한다.
inner div에는 modal의 내용이 들어간다.
요즘 잘 듣고있는 악뮤의 낙하 뮤직비디오를 넣었다.

아래 fiddle에서 직접 확인할 수 있다.

HTML

<div class="outer">
    <div class="inner">
      <iframe width="100%" height="100%" src="https://www.youtube.com/embed/EtiPbWzUY9o" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
    </div>
</div>

CSS

.outer {
  position: absolute;
  top: 0;
  left: 0;
  height: 1000px; /*100%*/
  width: 1000px; /*100%*/
  background-color: gray;
}

.inner {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
  width: 500px;  
  height: 300px;
}

스크롤를 어떻게 움직이든 악뮤는 가운데 고정이 된다.

팝업 가운데 정렬 CSS - pab-eob gaunde jeonglyeol CSS

아래처럼 레이어 팝업을 화면의 정 가운데 위치시키는 게 필요한 경우가 있다.

팝업 가운데 정렬 CSS - pab-eob gaunde jeonglyeol CSS

HTML

우선 이런 식으로 레이어를 준비한다. 보통은 body를 닫기 직전에 둔다.

<div class="js-layer  layer  hidden">
    <!-- 내용은 알아서 -->
</div>

js-layer 클래스는 js 제어를 위한 클래스고, hidden 클래스는 감춰 두기 위한 것이다. js에서 레이어를 보이게 할 때 이 hidden 클래스를 제거해서 보이게 한다.

다음은 레이어를 열게 할 버튼용 html 태그다. 역시 js-open은 js 제어를 위한 클래스고, open-button 클래스는 스타일링을 위한 클래스다.

<button type="button" class="js-open  open-button">Open Layer</button>

CSS

CSS가 핵심이다. 설명은 아래에 있다.

/* basic */
.layer {
    position: fixed;
    width: 40%;
    left: 50%;
    margin-left: -20%; /* half of width */
    height: 300px;
    top: 50%;
    margin-top: -150px; /* half of height */
    overflow: auto;

    /* decoration */
    border: 1px solid #000;
    background-color: #eee;
    padding: 1em;
    box-sizing: border-box;
}

  • 우선 포지션은 fixed로 한다. 그러면 화면을 스크롤 해도 레이어는 계속 화면 한 가운데 있게 된다.
  • width, left, margin-left를 이용해서 좌측 위치를 가운데로 맞추는 기법이다. left: 50%를 주면 화면 좌측의 50% 위치에서 레이어가 시작된다. 이 때 음수 마진을 레이어 너비의 절반 만큼 주면 레이어 너비의 절반 만큼 레이어가 왼쪽으로 이동하면서 가운데 오게 되는 것이다.
  • height, top, margin-top을 이용해서 상단 위치를 가운데로 맞추는 기법이다. top: 50%를 주면 화면 상단의 50% 위치에서 레이어가 시작된다. 이 때 음수 마진을 레이어 높이의 절반 만큼 주면 레이어 높이의 절반 만큼 레이어가 위로 이동하면서 가운데 오게 되는 것이다.
  • 레이어의 내용이 넘치면 스크롤이 생기도록 overflow: auto를 준다.

아래 코드는 화면이 좁을 때 레이어 너비를 좀더 넓히는 CSS 코드다.

@media (max-width: 600px) {
    .layer {
        width: 80%;
        margin-left: -40%;
    }
}

아래 코드는 처음에 레이어를 감춰 두기 위한 코드다.

.hidden {
    display: none;
}

자바스크립트

.js-open 버튼을 클릭하면 레이어에서 hidden 클래스를 뗀다.

$('.js-open').click(function () {
    var $layer = $('.js-layer');
    $layer.removeClass('hidden');
});

이게 전부다.

접근성

스크린 리더 등 보조 기기 사용자들을 위해 팝업으로 초점을 옮겨 줘야 한다. 여기서 다룰 주제는 아니니 넘어간다. 해당 내용은 Using ARIA role=dialog to implement a modal dialog box 등을 참고하라.

데모

데모 확인

데모는 jQuery 3을 사용하므로 구형 브라우저에서 돌아가지 않는다.

팝업 사이즈 고정

<!DOCTYPE html>
<html lang="kr">

<head>
  <meta charset="UTF-8">
  <title>레이어 팝업</title>
  <style>
    .content {
      height: 5000px;
    }

    .popup {
      position: fixed;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
    }

    .popup_layer {
      position: relative;
      width: 300px;
      min-height: 150px;
      padding-bottom: 50px;
      background: #fff;
      z-index: 10;
    }

    .text_area {
      padding: 50px 30px 30px;
      text-align: center
    }

    .btn_area {
      position: absolute;
      left: 0;
      right: 0;
      bottom: 0;
      height: 50px;
      overflow: hidden;
    }

    .btn {
      float: left;
      width: 50%;
      height: 100%;
      font-size: 15px;
      font-weight: bold;
      border: 0;
      background: pink;
    }

    .btn.no {
      background: lightblue;
    }

    .popup_dimmed {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      background: #000;
      opacity: 0.3;
    }



    /* 팝업 사이즈 고정 */

    /* IE7 이상 대응 */
    .popup_layer {
      position: absolute;
      top: 50%;
      left: 50%;
      width: 300px;
      height: 150px;
      padding-bottom: 50px;
      margin: -100px 0 0 -150px;
      background: #fff;
      z-index: 10;
    }

    /* IE8 이상 대응 */
    .popup_layer {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      width: 300px;
      height: 150px;
      padding-bottom: 50px;
      margin: auto;
      background: #fff;
      z-index: 10;
    }

  </style>
</head>

<body>
  <div class="content">
    <!-- 콘텐츠 -->
  </div>
  <div class="popup">
    <div class="popup_layer">
      <div class="text_area">
        <strong class="title">팝업 타이틀</strong>
        <p class="text">팝업 텍스트 영역</p>
      </div>
      <div class="btn_area">
        <button type="button" name="button" class="btn">예</button>
        <button type="button" name="button" class="btn no">아니오</button>
      </div>
    </div>
    <div class="popup_dimmed"></div>
  </div>
</body>

</html>

팝업 사이즈가 고정일 경우에는 position: absolute;로 요소를 띄워서 margin 으로 위치를 조절하는 방법을 사용합니다.

IE7까지 대응할 경우에는 팝업 크기만큼 마이너스 마진으로 위치를 옮겨주고, IE8 이상 대응할 경우에는 margin: auto; 를 사용하여 보다 쉽게 중앙 정렬할 수 있습니다.

margin: auto;

margin의 top, left, right, bottom 모두 auto로 적용할 경우, margin: auto; 로 축약하여 사용할 수 있습니다. 하지만 경우에 따라 auto는 0으로 처리되기도 합니다.

  • 0으로 처리되는 경우
    • 상하 margin
    • inline, float 요소, 혹은 absolute, fixed로 위치가 고정된 요소의 모든 margin
  • auto로 처리되는 경우
    • width가 있는 요소의 좌우 margin
    • absolute의 top + bottom + height 혹은 left + right + width 값이 함께 있는 요소의 모든 margin

팝업 사이즈 가변

display:inline-block;이용

<!DOCTYPE html>
<html lang="kr">

<head>
  <meta charset="UTF-8">
  <title>레이어 팝업</title>
  <style>
    .content {
      height: 5000px;
    }

    .popup {
      position: fixed;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
    }

    .popup_layer {
      position: relative;
      width: 300px;
      min-height: 150px;
      padding-bottom: 50px;
      background: #fff;
      z-index: 10;
    }

    .text_area {
      padding: 50px 30px 30px;
      text-align: center
    }

    .btn_area {
      position: absolute;
      left: 0;
      right: 0;
      bottom: 0;
      height: 50px;
      overflow: hidden;
    }

    .btn {
      float: left;
      width: 50%;
      height: 100%;
      font-size: 15px;
      font-weight: bold;
      border: 0;
      background: pink;
    }

    .btn.no {
      background: lightblue;
    }

    .popup_dimmed {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      background: #000;
      opacity: 0.3;
    }



    /* 팝업 사이즈 가변 - display:inline-block */

    .popup {
      position: fixed;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      text-align: center;
    }

    .popup:after {
      display: inline-block;
      vertical-align: middle;
      width: 0;
      height: 100%;
      content: '';
    }

    .popup_layer {
      position: relative;
      display: inline-block;
      vertical-align: middle;
      width: 300px;
      min-height: 150px;
      padding-bottom: 50px;
      background: #fff;
      z-index: 10;
    }

  </style>
</head>

<body>
  <div class="content">
    <!-- 콘텐츠 -->
  </div>
  <div class="popup">
    <div class="popup_layer">
      <div class="text_area">
        <strong class="title">팝업 타이틀</strong>
        <p class="text">팝업 텍스트 영역</p>
      </div>
      <div class="btn_area">
        <button type="button" name="button" class="btn">예</button>
        <button type="button" name="button" class="btn no">아니오</button>
      </div>
    </div>
    <div class="popup_dimmed"></div>
  </div>
</body>

</html>

.popup_layer를 inline-block 요소로 만들어 .popup의 text-align: center로 가로 중앙 정렬을 합니다. 그리고 .popup 요소 안에 빈 요소 혹은 가상요소를 추가하여 .popup_layer와 vertical-align: middle; 로 세로 중앙정렬을 합니다.

display:table;과 display:table-cell;이용

<!DOCTYPE html>
<html lang="kr">

<head>
  <meta charset="UTF-8">
  <title>레이어 팝업</title>
  <style>
    .content {
      height: 5000px;
    }

    .popup {
      position: fixed;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
    }

    .popup_layer {
      position: relative;
      width: 300px;
      min-height: 150px;
      padding-bottom: 50px;
      background: #fff;
      z-index: 10;
    }

    .text_area {
      padding: 50px 30px 30px;
      text-align: center
    }

    .btn_area {
      position: absolute;
      left: 0;
      right: 0;
      bottom: 0;
      height: 50px;
      overflow: hidden;
    }

    .btn {
      float: left;
      width: 50%;
      height: 100%;
      font-size: 15px;
      font-weight: bold;
      border: 0;
      background: pink;
    }

    .btn.no {
      background: lightblue;
    }

    .popup_dimmed {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      background: #000;
      opacity: 0.3;
    }



    /* 팝업 사이즈 가변 - display:table;과 display:table-cell; */

    .popup_wrap {
      display: table;
      table-layout: fixed;
      width: 100%;
      height: 100%;
    }

    .popup_inner {
      display: table-cell;
      vertical-align: middle;
      text-align: center;
    }

    .popup_layer {
      position: relative;
      display: inline-block;
      width: 300px;
      min-height: 150px;
      padding-bottom: 50px;
      background: #fff;
      z-index: 10;
    }
    
    
  </style>
</head>

<body>
  <div class="content">
    <!-- 콘텐츠 -->
  </div>
  <div class="popup">
    <div class="popup_wrap">
      <div class="popup_inner">
        <!-- 팝업 영역 -->
        <div class="popup_layer">
          <div class="text_area">
            <strong class="title">팝업 타이틀</strong>
            <p class="text">팝업 텍스트 영역</p>
          </div>
          <div class="btn_area">
            <button type="button" class="btn">예</button>
            <button type="button" class="btn no">아니오</button>
          </div>
        </div>
        <!-- // 팝업 영역 -->
      </div>
    </div>
    <div class="popup_dimmed"></div>
  </div>
</body>
</html>

추가한 요소에 각각 display: table;과 display: table-cell;을 적용하고, .popup_layer를 inline-block 요소로 변경합니다. 그리고 그 부모인 .popup_inner에 vertical-align과 text-align를 적용해서 중앙 절렬을 합니다.