[HTML/CSS/JS] 팝업 구현 1(+ rotate, visibillity)

happyyeom·2024년 10월 21일

팝업 구현

addClass, RemoveClass를 이용해서 구현

html

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<!--jQuery라이브러리 사용을 위한 링크-->

<!--팝업창-->
<div class="popup">
  <div class="popup__head">
    <button class="popup__btn-close">X</button>
  </div>
</div>

<!--container-->
<div class="con">
  <button class="btn-popupshow">팝업 1</button>
  Lorem.../* <- * 50 생략 *
</div>

css

.con{
  width:1000px;
  margin:0 auto;
}
/*container의 너비를 설정하고 가운데정렬해준다.*/

.popup{
  width:300px;
  height:300px;
  border:10px solid black;
  background-color:white;
  /*너비, 높이, 배경색, 보더 설정*/
  position:fixed;
  /*스크롤을 내려도 팝업창의 위치는 그대로 가운데여야하기 때문에 position값을
  absolute대신에 fixed를 사용한다.fixed -> 고정*/
  top:50%;
  left:50%;
  transform:translate(-50%,-50%);
  /*중앙 정렬*/
  box-shadow:10px 10px 30px rgba(0,0,0,0.7);
  display:none;
  /*버튼을 누르기 전 기본상태는 안보여야 하므로 display:none;으로 해준다.*/
}

.popup__btn-close{
  display:block;
  margin:5px;
  margin-left:auto;
  /*팝업창 속 X버튼 css*/
}

/*.popup클래스와 .active클래스를 동시에 가지고 있는 태그에게만 적용되는 속성*/
.popup.active{
  display:block;
}
/*display속성을 block으로 만드는 .active클래스 속성.*/

JS

console.clear();

//버튼을 누르면 작동하는 함수
function popup_open_close() {
  let has = $('.popup').hasClass('active');
  /*변수 has를 선언하고 값을 명제로 주는데,
  .popup클래스를 가지고 있는 태그가 .active태그를 가지고 있으면 참,
  가지고 있지 않으면 거짓이다.*/
  console.log(has);
  /*변수 has값 확인을 위해 console창에 출력해준다.*/
  
  if(has){
    $('.popup').removeClass('active');
    /*만약 has가 참이라면(.popup클래스를 가지고 있는 태그가 .active태그를 가지고 있으면)
    .popup, .active클래스를 동시에 가지고 있는 태그에게서 .active태그를 제거해준다.*/
  }
  else{
    $('.popup').addClass('active');
    /*만약 has가 거짓이라면(.popup클래스를 가지고 있는 태그가 .active태그를 가지고 있지 않으면)
    .popup클래스를 가지고 있는 태그에게.active태그를 추가해준다.*/
    
  }
}

코드를 입력하세요

$('.popup__btn-close').click(popup_open_close);
//.popup__btn-close(팝업창 속 X버튼)를 클릭하면 popup_open_close를 실행한다.
$('.btn-popupshow').click(popup_open_close);
//.btn-popupshow(팝업 버튼)를 클릭하면 popup_open_close를 실행한다.


visibillity, rotate를 이용한 팝업


이번에는 배경색도 흐릿하게 바뀌고 X버튼에 hover시 돌아간다. 그리고 팝업이 위에서부터 생기면서 내려오는 것을 구현해보자.
html

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<!--jQuery사용을 위한 코드-->

<!--팝업-->
<div class="popup">
  <div class="popup__content">
  <!--부모 .popup클래스는 배경색을 흐리게 만드느데 사용하고 popup__content를 만들어
새로 팝업창을 만든다.-->
    <!--팝업 헤더-->
    <div class="popup__head">
      <div class="popup__btn-close"></div>
    </div>
    <!--팝업 내용-->
    <div class="popup__body">
      <div class="con">
        Lorem ...
      </div>
    </div>
  
  </div>
</div>

<section class="section-1">
  <div class="con">
    <!--팝업 생성 버튼-->
    <button class="btn-popup-1">팝업 1</button>
    Lorem ipsum...
  </div>
</section>

css

/*노말라이즈*/
body, ul, li {
  margin:0;
  padding:0;
  list-style:none;
}

a {
  color:inherit;
  text-decoration:none;
}

/*컨텐츠 너비만들고 가운데로 옮겨 양 옆 여백만들기*/
.con {
  margin-left:auto;
  margin-right:auto;
}

.con {
  max-width:1200px;
}

.popup {
  position:fixed;
  top:0;
  left:0;
  right:0;
  bottom:0;
  background-color:rgba(0,0,0,0.5);
  /*웹을 가득 채우고 배경색을 흐린 검정색으로 만든다.*/
  align-items:center;
  justify-content:center;
  display:flex;
  /*display를 flex로 만들어 팝업창(.popup__content)를 정가운데로 옮긴다.*/
  opacity:0;
  visibility:hidden;
  /*불투명도를 0으로 만들어 평소에 보이지 않게 만들고 visivility로 숨긴다. .active클래스가 추가되면 나타나게 한다.*/
  transition: opacity .3s, visibility .3s;
  /*opacity와 visibility에 재생시간을 부여한다.*/
}

.popup.active {
  opacity:1;
  visibility:visible;
  /*팝업을 다시 나타나게 하는 클래스를 만든다.*/
}

.popup__content {
  min-width:200px;
  min-height:200px;
  /*최소 너비, 높이 지정*/
  background-color:white;
  border:2px solid black;
  transform:translateY(-100%);
  /*평소에는 팝업창이 위에 있게 만들고 .active클래스 추가로 가운데 오게 만든다.*/
  transition: transform .3s;
  /*transform에 재생시간을 부여한다.*/
}

/*.popup과 .active클래스를 모두 가지고 있는 태그의 후손이면서
.popup__content를 가지고 있는 태그에게 적용하는 속성*/
/*원래는 .popup이 .active클래스를 가지고 있지 않으므로 이 속성이 활성화
되지 않지만 JS를 이용해 .popup이 .active클래스를 갖는 순간 활성화된다.*/
/*단순히 .active클래스를 라이브러리처럼 사용하는 것이 아니라 관련된 클래스를 만들어 
클래스를 추가하는 것만으로 여러 css속성이 추가되도록 구현한 것!!*/
.popup.active .popup__content {
  transform:translateY(0);
  /*다시 원래 자리로 오게하는 클래스를 만든다.*/
}

.popup__head {
  padding:10px;
}

.popup__btn-close {
  width:30px;
  height:30px;
  /*X표를 만들기위해 네모 틀을 만든다.*/
  margin-left:auto;
  /*.popup__head의 오른쪽에 붙인다.*/
  position:relative;
  /*before, after태그를 absolute로 하고 이 태그를 유령의 집으로 만든다.*/
  cursor:pointer;
  transition:transform 0.3s;
  /*transform(rotate)에 재생시간을 부여한다. 돌아가는 애니매이션 구현*/
}

.popup__btn-close:hover {
  transform:rotate(185deg);
  /*hover시 185도 돌아간다.*/
}

.popup__btn-close::before,
.popup__btn-close::after {
  content:"";
  background-color:black;
  position:absolute;
  top:40%;
  left:0;
  width:100%;
  height:20%;
  transform:rotate(45deg);
  /*before, after태그를 막대기처럼 만들어 하나는 45도 하나는 -45도 기울여
  X표처럼 만든다.*/
  transition:box-shadow 0.3s;
  /*box-shadow에 재생시간을 부여한다.*/
  
}

.popup__btn-close::after {
  transform:rotate(-45deg);
}

.popup__btn-close:hover::before,
.popup__btn-close:hover::after {
  box-shadow:0 0 3px black;
  /*hover시 그림자가 생기도록 한다.*/
}

.popup__body {
  padding:0 10px;
  /*팝업 내용에 양엽 padding값 부여*/
}

JS

console.clear();

$('.btn-popup-1').click(function() {
  $('.popup').addClass('active');
});
/*팝업 1 버튼(.btn-popup-1)을 클릭시 팝업(.popup)에게 .active클래스를 부여한다.*/
$('.popup__btn-close').click(function() {
  $('.popup').removeClass('active');
});
/*X버튼(.popup__btn-close)을 클릭시 팝업(.popup)에게 .active클래스를 제거한다.*/

transform: rotate

이 속성은 transform속성 중에서 요소를 회전 시킬 수 있는 속성이다.

selector{
	transform: rotate(각도)
}

보통 radian과 degree를 사용하는데 radian은 rad, degree는 deg으로 사용한다.
180도 = 180deg = 3.142..rad


visibillity

우리가 위 코드에서 팝업창의 평소상태를 보이지 않게 만들 때 전에 배웠던 display: none;을 생각할 것이다. 하지만 클릭했을 때 transition을 이용해야 하는데 아쉽게도 display: none;은 애니메이션 효과가 나타나지 않는다.
그럼 opacity속성을 사용해야 할까? 반은 정답이다. 하지만 가장 큰 문제가 있다.
opacity를 사용하면 투명하게만 보이기 때문에 말 그대로 보이지만 않을 뿐 그 레이어는 그대로 있다. 그래서 .con안에 있는 팝업 1 버튼을 누를 수 없다는 것이다.

그래서 우리는 opacity와 함께 visibillity속성을 사용한다. visibillity속성은 태그의 가시성을 결정하고

  • visible: 보임
  • hidden: 숨김 (자신의 영역은 계속 차지)
  • collapse: 겹치도록 지정(테이블의 행과 열 요소만 지정할 수 있으며, 그 외 요소의 지정하면 hidden으로 해석)
  • inherit: 부모 요소의 값을 상속
    4가지 값을 가진다.
    여기서 hidden값을 사용하면 요소를 숨겼을때 hidden으로 숨긴 요소의 아래에 있는 요소의 제어를 방해하지 않는다.
    (hidden : 박스가 보이지 않지만 공간을 확보하기 때문에 여전히 레이아웃에 영향을 미친다.
    출처: https://webdir.tistory.com/348 [WEBDIR:티스토리]?아직 이해하지 못함)
    그리하여 두가지 속성을 함께 사용하면 팝업 1 버튼의 제어를 방해하지 않고 부드러운 fade in, fade out이 가능하다.

visibillity, opacity를 같이 사용하는 이유

transition은 수치로 나타낼 수 없는 속성에는 적용되지 않는다. visibillity는 숨기고 나타낼 뿐 수치는 없다.

profile
🌳🌳🌳🌳🌳🌳🌳🌳🌳🌳🌳🌳🌳🌳

0개의 댓글